Recover ethereum address from signature

This commit is contained in:
Mark Spanbroek 2021-03-15 17:34:16 +01:00
parent 292a7ec2ac
commit c680d34a18
2 changed files with 22 additions and 7 deletions

View File

@ -12,20 +12,27 @@ export keys
type Signature* = SkRecoverableSignature
proc sign(key: PrivateKey, data: openArray[byte]): Signature =
let hash = keccak256.digest(data).data
key.signRecoverable(SkMessage(hash))
proc signMessage(key: PrivateKey, message: openArray[byte]): Signature =
proc hashMessage(message: openArray[byte]): array[32, byte] =
# https://eips.ethereum.org/EIPS/eip-191
var data: seq[byte]
data.add("\x19Ethereum Signed Message:\n".toBytes)
data.add(($message.len).toBytes)
data.add(message)
key.sign(data)
keccak256.digest(data).data
proc sign(key: PrivateKey, hash: array[32, byte]): Signature =
key.signRecoverable(SkMessage(hash))
proc sign*(key: PrivateKey, state: State): Signature =
key.signMessage(hashState(state))
let hash = hashMessage(hashState(state))
key.sign(hash)
proc recover(signature: Signature, hash: array[32, byte]): ?PublicKey =
recover(signature, SkMessage(hash)).option
proc recover*(signature: Signature, state: State): ?EthAddress =
let hash = hashMessage(hashState(state))
recover(signature, hash)?.toAddress
proc `$`*(signature: Signature): string =
var bytes = signature.toRaw()

View File

@ -17,6 +17,14 @@ suite "signature":
let hash = keccak256.digest(data).data
check recover(signature, SkMessage(hash)).tryGet() == publicKey
test "recovers ethereum address from signature":
let state1, state2 = State.example
let key = PrivateKey.random()
let address = key.toPublicKey.toAddress
let signature = key.sign(state1)
check recover(signature, state1) == address.some
check recover(signature, state2) != address.some
test "produces the same signatures as the javascript implementation":
let state =State(
channel: ChannelDefinition(