mirror of
https://github.com/status-im/nim-eth-keys.git
synced 2025-02-13 01:36:38 +00:00
PublicKey serialization and stringification (#8)
This commit is contained in:
parent
74bdca4f1c
commit
ef185ff1ee
@ -48,8 +48,8 @@ proc private_key_to_public_key*(key: PrivateKey): PublicKey {.noInit.}=
|
|||||||
if not success:
|
if not success:
|
||||||
raise newException(ValueError, "Private key is invalid")
|
raise newException(ValueError, "Private key is invalid")
|
||||||
|
|
||||||
proc serialize*(key: PublicKey): string =
|
proc serialize*(key: PublicKey, output: var openarray[byte], addPrefix = false) =
|
||||||
## Exports a publicKey to a hex string
|
## Exports a publicKey to `output` buffer so that it can be
|
||||||
var
|
var
|
||||||
tmp{.noInit.}: Serialized_PubKey
|
tmp{.noInit.}: Serialized_PubKey
|
||||||
tmp_len: csize = 65
|
tmp_len: csize = 65
|
||||||
@ -64,14 +64,43 @@ proc serialize*(key: PublicKey): string =
|
|||||||
)
|
)
|
||||||
|
|
||||||
assert tmp_len == 65 # header 0x04 (uncompressed) + 128 hex char
|
assert tmp_len == 65 # header 0x04 (uncompressed) + 128 hex char
|
||||||
|
if addPrefix:
|
||||||
|
assert(output.len >= 65)
|
||||||
|
copyMem(addr output[0], addr tmp[0], 65)
|
||||||
|
else:
|
||||||
|
assert(output.len >= 64)
|
||||||
|
copyMem(addr output[0], addr tmp[1], 64) # Skip the 0x04 prefix
|
||||||
|
|
||||||
result = tmp.toHex
|
proc toString*(key: PublicKey): string =
|
||||||
|
var data: array[64, byte]
|
||||||
|
key.serialize(data)
|
||||||
|
result = data.toHex
|
||||||
|
|
||||||
proc parsePublicKey*(data: openarray[byte]): PublicKey =
|
proc toStringWithPrefix*(key: PublicKey): string =
|
||||||
|
var data: array[65, byte]
|
||||||
|
key.serialize(data, true)
|
||||||
|
result = data.toHex
|
||||||
|
|
||||||
|
proc serialize*(key: PublicKey): string {.deprecated.} = key.toStringWithPrefix()
|
||||||
|
|
||||||
|
proc parsePublicKeyWithPrefix(data: openarray[byte], result: var PublicKey) =
|
||||||
## Parse a variable-length public key into the PublicKey object
|
## Parse a variable-length public key into the PublicKey object
|
||||||
if secp256k1_ec_pubkey_parse(ctx, result.asPtrPubKey, cast[ptr cuchar](unsafeAddr data[0]), data.len.csize) != 1:
|
if secp256k1_ec_pubkey_parse(ctx, result.asPtrPubKey, cast[ptr cuchar](unsafeAddr data[0]), data.len.csize) != 1:
|
||||||
raise newException(Exception, "Could not parse public key")
|
raise newException(Exception, "Could not parse public key")
|
||||||
|
|
||||||
|
proc parsePublicKey*(data: openarray[byte]): PublicKey =
|
||||||
|
## Parse a variable-length public key into the PublicKey object
|
||||||
|
case data.len
|
||||||
|
of 65:
|
||||||
|
parsePublicKeyWithPrefix(data, result)
|
||||||
|
of 64:
|
||||||
|
var tmpData: Serialized_PubKey
|
||||||
|
copyMem(addr tmpData[1], unsafeAddr data[0], 64)
|
||||||
|
tmpData[0] = 0x04
|
||||||
|
parsePublicKeyWithPrefix(tmpData, result)
|
||||||
|
else: # TODO: Support other lengths
|
||||||
|
raise newException(Exception, "Wrong public key length")
|
||||||
|
|
||||||
proc ecdsa_sign*(key: PrivateKey, msg_hash: Hash[256]): Signature {.noInit.}=
|
proc ecdsa_sign*(key: PrivateKey, msg_hash: Hash[256]): Signature {.noInit.}=
|
||||||
## Sign a message with a recoverable signature
|
## Sign a message with a recoverable signature
|
||||||
## Input:
|
## Input:
|
||||||
@ -103,3 +132,5 @@ proc ecdsa_recover*(msg_hash: Hash[256], sig: Signature): PublicKey =
|
|||||||
|
|
||||||
if not success:
|
if not success:
|
||||||
raise newException(ValueError, "Failed to recover public key. Is the signature correct?")
|
raise newException(ValueError, "Failed to recover public key. Is the signature correct?")
|
||||||
|
|
||||||
|
proc `$`*(key: PublicKey): string {.inline.} = key.toString()
|
||||||
|
@ -23,6 +23,8 @@ when defined(backend_native):
|
|||||||
else:
|
else:
|
||||||
import ./backend_libsecp256k1/libsecp256k1
|
import ./backend_libsecp256k1/libsecp256k1
|
||||||
export libsecp256k1.serialize
|
export libsecp256k1.serialize
|
||||||
|
export libsecp256k1.`$`
|
||||||
|
export libsecp256k1.parsePublicKey
|
||||||
|
|
||||||
# ################################
|
# ################################
|
||||||
# Initialization
|
# Initialization
|
||||||
@ -63,3 +65,6 @@ proc sign_msg*(key: PrivateKey, message: string): Signature {.inline.} =
|
|||||||
|
|
||||||
proc sign_msg*(key: PrivateKey, message_hash: Hash[256]): Signature {.inline.} =
|
proc sign_msg*(key: PrivateKey, message_hash: Hash[256]): Signature {.inline.} =
|
||||||
ecdsa_sign(key, message_hash)
|
ecdsa_sign(key, message_hash)
|
||||||
|
|
||||||
|
proc `$`*(key: PrivateKey): string {.inline.} =
|
||||||
|
key.raw_key.toHex()
|
||||||
|
@ -17,6 +17,6 @@ suite "Testing private -> public key conversion":
|
|||||||
for person in [alice, bob, eve]:
|
for person in [alice, bob, eve]:
|
||||||
let privkey = initPrivateKey(person.privkey)
|
let privkey = initPrivateKey(person.privkey)
|
||||||
|
|
||||||
let computed_pubkey = privkey.public_key.serialize
|
let computed_pubkey = $privkey.public_key
|
||||||
|
|
||||||
check: computed_pubkey == "04" & person.pubkey # Serialization prefixes uncompressed public keys with 04
|
check: computed_pubkey == person.pubkey
|
Loading…
x
Reference in New Issue
Block a user