NodeJs 實現keccak256運算和ECDSA數字簽名

Keccak 256

SHA3採用Keccak算法,在很多場合下Keccak和SHA3是同義詞,但在2015年8月SHA3最終完成標準化時,NIST調整了填充算法,標準的SHA3和原先的Keccak算法就有所區別了。在早期的Ethereum相關代碼中,普遍使用SHA3代指Keccak256,爲了避免和NIST標準的SHA3混淆,現在的代碼直接使用Keccak256作爲函數名。

ECDSA 簽名算法

橢圓曲線數字簽名算法(ECDSA)是使用橢圓曲線密碼(ECC)對數字簽名算法(DSA)的模擬。ECDSA於1999年成爲ANSI標準,並於2000年成爲IEEE和NIST標準。它在1998年既已爲ISO所接受,並且包含它的其他一些標準亦在ISO的考慮之中。與普通的離散對數問題(discrete logarithm problem DLP)和大數分解問題(integer factorization problem IFP)不同,橢圓曲線離散對數問題(elliptic curve discrete logarithm problem ECDLP)沒有亞指數時間的解決方法。因此橢圓曲線密碼的單位比特強度要高於其他公鑰體制。

ECDSA原理

ECDSA是ECC與DSA的結合,整個簽名過程與DSA類似,所不一樣的是簽名中採取的算法爲ECC,最後簽名出來的值也是分爲r,s。
簽名過程如下:
1、選擇一條橢圓曲線Ep(a,b),和基點G;
2、選擇私有密鑰k(k<n,n爲G的階),利用基點G計算公開密鑰K=kG;
3、產生一個隨機整數r(r<n),計算點R=rG;
4、將原數據和點R的座標值x,y作爲參數,計算SHA1做爲hash,即Hash=SHA1(原數據,x,y);
5、計算s≡r - Hash * k (mod n)
6、r和s做爲簽名值,如果r和s其中一個爲0,重新從第3步開始執行
驗證過程如下:
1、接受方在收到消息(m)和簽名值(r,s)後,進行以下運算
2、計算:sG+H(m)P=(x1,y1), r1≡ x1 mod p。
3、驗證等式:r1 ≡ r mod p。
4、如果等式成立,接受簽名,否則簽名無效。

瞭解了這麼多怎麼快速實現keccak256+ecdsa數字簽名呢?

const { keccak256, ecsign,isValidPrivate,privateToPublic} = require('ethereumjs-util')

var rlpdata = "your hash data"
const privKey = Buffer.alloc(32, '1973a11dc782d83281af10b97b0c208f49d9598af40bc91aee3cb1628bd60578', 'hex')
const pubKey = privateToPublic(privKey)
console.log(pubKey.toString('hex'))
//檢查私鑰是否滿足曲線secp256k1的規則。
console.log(isValidPrivate(privKey))

const sign = (msgHash, privKey) => {
  if (typeof msgHash === 'string' && msgHash.slice(0, 2) === '0x') {
    msgHash = Buffer.alloc(32, msgHash.slice(2), 'hex')
  }
 const sig = ecsign(msgHash, privKey)
  return `0x${sig.r.toString('hex')}${sig.s.toString('hex')}${sig.v.toString(16)}`
}

const hash = '0x' + keccak256(rlpdata).toString('hex')

const sig = sign(hash, privKey)

console.log('keccak256("hash"): ' + hash)
console.log('signature: ' + sig)


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章