2021-03-02 07:37:38 +01:00
|
|
|
import pkg/secp256k1
|
2025-12-10 20:44:01 +01:00
|
|
|
import pkg/nimcrypto/keccak
|
2021-03-02 07:37:38 +01:00
|
|
|
import pkg/stew/byteutils
|
2021-03-09 11:07:35 +01:00
|
|
|
import ../basics
|
2021-03-09 13:16:54 +01:00
|
|
|
import ../keys
|
2021-03-02 07:37:38 +01:00
|
|
|
import ./state
|
|
|
|
|
|
2025-12-10 20:44:01 +01:00
|
|
|
{.push raises: [].}
|
2021-03-03 10:30:07 +01:00
|
|
|
|
2021-03-09 11:07:35 +01:00
|
|
|
export basics
|
2021-03-09 13:16:54 +01:00
|
|
|
export keys
|
2021-03-02 07:37:38 +01:00
|
|
|
|
2021-03-09 13:16:54 +01:00
|
|
|
type Signature* = SkRecoverableSignature
|
2021-03-02 07:37:38 +01:00
|
|
|
|
2021-03-17 12:22:00 +01:00
|
|
|
func hashMessage(message: openArray[byte]): array[32, byte] =
|
2021-03-02 07:37:38 +01:00
|
|
|
# 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)
|
2021-03-15 17:34:16 +01:00
|
|
|
keccak256.digest(data).data
|
|
|
|
|
|
2021-04-07 09:15:26 +02:00
|
|
|
func sign(key: EthPrivateKey, hash: array[32, byte]): Signature =
|
2021-03-15 17:34:16 +01:00
|
|
|
key.signRecoverable(SkMessage(hash))
|
2021-03-02 07:37:38 +01:00
|
|
|
|
2021-04-07 09:15:26 +02:00
|
|
|
func sign*(key: EthPrivateKey, state: State): Signature =
|
2021-03-15 17:34:16 +01:00
|
|
|
let hash = hashMessage(hashState(state))
|
|
|
|
|
key.sign(hash)
|
|
|
|
|
|
2021-04-07 09:15:26 +02:00
|
|
|
func recover(signature: Signature, hash: array[32, byte]): ?EthPublicKey =
|
2021-03-15 17:34:16 +01:00
|
|
|
recover(signature, SkMessage(hash)).option
|
|
|
|
|
|
2021-03-17 12:22:00 +01:00
|
|
|
func recover*(signature: Signature, state: State): ?EthAddress =
|
2021-03-15 17:34:16 +01:00
|
|
|
let hash = hashMessage(hashState(state))
|
2021-04-12 16:29:44 +02:00
|
|
|
recover(signature, hash).?toAddress
|
2021-03-02 07:37:38 +01:00
|
|
|
|
2021-03-17 12:22:00 +01:00
|
|
|
func verify*(signature: Signature, state: State, signer: EthAddress): bool =
|
2021-03-16 10:19:13 +01:00
|
|
|
recover(signature, state) == signer.some
|
|
|
|
|
|
2021-03-17 12:22:00 +01:00
|
|
|
func `$`*(signature: Signature): string =
|
2021-03-02 07:37:38 +01:00
|
|
|
var bytes = signature.toRaw()
|
|
|
|
|
bytes[64] += 27
|
|
|
|
|
bytes.toHex()
|
|
|
|
|
|
2021-03-17 12:22:00 +01:00
|
|
|
func parse*(_: type Signature, s: string): ?Signature =
|
2021-05-10 09:12:46 +02:00
|
|
|
without var bytes =? array[65, byte].fromHex(s).catch:
|
|
|
|
|
return Signature.none
|
|
|
|
|
bytes[64] = bytes[64] - 27
|
|
|
|
|
SkRecoverableSignature.fromRaw(bytes).option
|