ethereumjs-util を使用した ECDSA 署名および署名検証の手順です。
署名の手順
- 署名するメッセージの Keccak ハッシュを得ます。
- メッセージのハッシュに署名をします。
署名検証の手順
- 検証したいメッセージと署名を入手します。
- メッセージの Keccak ハッシュを得ます。
- ecrecover を使用して、署名者の公開鍵を得ます。
- 公開鍵から Ethereum アドレスを計算し、実際の署名者のアドレスと比較します。
サンプルコード
const EthUtil = require('ethereumjs-util')
// 署名者のアドレス
const SIGNER_ADDRESS_STRING = '0x89c24a88bad4abe0a4f5b2eb5a86db1fb323832c'
// 署名者の秘密鍵文字列
const PRIVATE_KEY_STRING = '0x61ce8b95ca5fd6f55cd97ac60817777bdf64f1670e903758ce53efc32c3dffeb'
// メッセージ
const MESSAGE = 'piyopiyo!'
// 秘密鍵の文字列からバッファを取得
const privateKey = EthUtil.toBuffer(PRIVATE_KEY_STRING)
// 与えられたメッセージと秘密鍵から署名を返すメソッドです。
function sign(message, privateKey) {
// メッセージ の Keccak ハッシュを得ます。
const hashedMessage = EthUtil.keccak(message)
// ecsign を使用してメッセージのハッシュに署名します。
const signature = EthUtil.ecsign(hashedMessage, privateKey)
return signature
}
// 与えられたメッセージと署名から署名者の Ethereum アドレスを導出し、
// 署名者が正しいかどうかを返すメソッドです。
function verify(message, signature, address) {
// メッセージ の Keccak ハッシュを得ます。
const hashedMessage = EthUtil.keccak(message)
// ecrecover を使用して、署名から公開鍵を導出します。
const publicKey = EthUtil.ecrecover(hashedMessage,
signature.v,
EthUtil.toBuffer(signature.r),
EthUtil.toBuffer(signature.s))
// 公開鍵から署名者のアドレスを計算します。
const recoverdAddress = EthUtil.bufferToHex(EthUtil.pubToAddress(publicKey))
// アドレスを比較します。
if (EthUtil.toChecksumAddress(address)
== EthUtil.toChecksumAddress(recoverdAddress)) {
return true
} else {
return false
}
}
// 署名
const signature = sign(MESSAGE, privateKey)
console.log('signature:\n', signature)
// 署名検証
const isVerified = verify(MESSAGE, signature, SIGNER_ADDRESS_STRING)
console.log('isVerified:', isVerified)