Remove tests of private fields + Hide privat fields for real
This commit is contained in:
parent
a4ed335c8b
commit
85e7f11efe
|
@ -26,11 +26,6 @@ task test_cpp, "Run all tests - C++ only & libsecp256k1 backend":
|
||||||
test "all_tests", "cpp"
|
test "all_tests", "cpp"
|
||||||
|
|
||||||
task test, "Run all tests - C and C++ & libsecp256k1 backend":
|
task test, "Run all tests - C and C++ & libsecp256k1 backend":
|
||||||
## TODO: This only runs the C++ tests ...
|
|
||||||
# block:
|
|
||||||
# test "all_tests"
|
|
||||||
# block:
|
|
||||||
# test "all_tests", "cpp"
|
|
||||||
exec "nimble test_c"
|
exec "nimble test_c"
|
||||||
exec "rm ./nimcache/*"
|
exec "rm ./nimcache/*"
|
||||||
exec "nimble test_cpp"
|
exec "nimble test_cpp"
|
||||||
|
|
|
@ -13,23 +13,52 @@ import ./private/conversion_bytes
|
||||||
# See private field access issue: https://github.com/nim-lang/Nim/issues/7390
|
# See private field access issue: https://github.com/nim-lang/Nim/issues/7390
|
||||||
type
|
type
|
||||||
PublicKey* = object
|
PublicKey* = object
|
||||||
Fraw_key*: array[64, byte]
|
Fraw_key: array[64, byte]
|
||||||
|
|
||||||
PrivateKey* = object
|
PrivateKey* = object
|
||||||
Fraw_key*: array[32, byte]
|
Fraw_key: array[32, byte]
|
||||||
Fpublic_key*: PublicKey
|
Fpublic_key: PublicKey # This is exported publicly through public_key
|
||||||
|
|
||||||
|
|
||||||
type
|
type
|
||||||
Scalar256 = array[32, byte]
|
Scalar256 = distinct array[32, byte]
|
||||||
# Secp256k1 makes the signature an opaque "implementation dependent".
|
# Secp256k1 makes the signature an opaque "implementation dependent".
|
||||||
#
|
#
|
||||||
# Scalar256 is opaque/distinct too as in practice, they are uint256
|
# Scalar256 is opaque/distinct too as in practice it's uint256
|
||||||
# and by default we don't load any.
|
# and by default we don't load any uint256 library.
|
||||||
# See implementation details in datatypes.md.
|
# See implementation details in datatypes.md.
|
||||||
|
|
||||||
Signature* {.packed.}= object
|
Signature* {.packed.}= object
|
||||||
Fr*: Scalar256
|
Fr: Scalar256
|
||||||
Fs*: Scalar256
|
Fs: Scalar256
|
||||||
Fv*: range[0.byte .. 1.byte] # This should be 27..28 as per Ethereum but it's 0..1 in eth-keys ...
|
Fv: range[0.byte .. 1.byte] # This should be 27..28 as per Ethereum but it's 0..1 in eth-keys ...
|
||||||
|
|
||||||
|
# Hide the private fields and generate accessors.
|
||||||
|
# This is needed to:
|
||||||
|
# - Be able to not store the public_key in PrivateKey in the future and replace it by
|
||||||
|
# an on-the-fly computation
|
||||||
|
# - Signature: have different data representation
|
||||||
|
|
||||||
|
template genAccessors(name: untyped, fieldType, objType: typedesc): untyped =
|
||||||
|
# Access
|
||||||
|
proc name*(obj: objType): fieldType {.noSideEffect, inline, noInit.} =
|
||||||
|
obj.`F name`
|
||||||
|
|
||||||
|
# Assignement
|
||||||
|
proc `name=`*(obj: var objType, value: fieldType) {.noSideEffect, inline.} =
|
||||||
|
obj.`F name` = value
|
||||||
|
|
||||||
|
# Mutable
|
||||||
|
proc `name`*(obj: var objType): var fieldType {.noSideEffect, inline.} =
|
||||||
|
obj.`F name`
|
||||||
|
|
||||||
|
genAccessors(raw_key, array[64, byte], PublicKey)
|
||||||
|
genAccessors(raw_key, array[32, byte], PrivateKey)
|
||||||
|
genAccessors(public_key, PublicKey, PrivateKey)
|
||||||
|
|
||||||
|
|
||||||
|
## If we hide the fields we need to provide a custom `==` proc
|
||||||
|
## Because Nim `==` template will not be able to access the fields
|
||||||
|
|
||||||
|
proc `==`*(x, y: Scalar256): bool {.noSideEffect, inline, borrow.}
|
||||||
|
proc `==`*(x, y: PublicKey or PrivateKey or Signature): bool {.noSideEffect, inline.} =
|
||||||
|
system.`==`(x, y)
|
||||||
|
|
|
@ -31,8 +31,8 @@ else:
|
||||||
# Initialization
|
# Initialization
|
||||||
|
|
||||||
proc initPrivateKey*(hexString: string): PrivateKey {.noInit.} =
|
proc initPrivateKey*(hexString: string): PrivateKey {.noInit.} =
|
||||||
hexToByteArrayBE(hexString, result.Fraw_key)
|
hexToByteArrayBE(hexString, result.raw_key)
|
||||||
result.Fpublic_key = private_key_to_public_key(result)
|
result.public_key = private_key_to_public_key(result)
|
||||||
|
|
||||||
proc initPublicKey*(hexString: string): PublicKey {.noInit.} =
|
proc initPublicKey*(hexString: string): PublicKey {.noInit.} =
|
||||||
var b: array[65, byte]
|
var b: array[65, byte]
|
||||||
|
@ -68,4 +68,4 @@ 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.} =
|
proc `$`*(key: PrivateKey): string {.inline.} =
|
||||||
key.Fraw_key.toHex()
|
key.raw_key.toHex()
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
||||||
|
|
||||||
import ./datatypes
|
import ./datatypes
|
||||||
export PublicKey, PrivateKey, Signature
|
export PublicKey, PrivateKey, Signature, public_key, `==`
|
||||||
|
|
||||||
import ./datatypes_interface
|
import ./datatypes_interface
|
||||||
export datatypes_interface
|
export datatypes_interface
|
||||||
|
|
|
@ -14,41 +14,13 @@ import unittest
|
||||||
|
|
||||||
suite "Test key and signature data structure":
|
suite "Test key and signature data structure":
|
||||||
|
|
||||||
# TODO: For now due to needing hex <-> uint256 conversion
|
|
||||||
# Testing r, s, v direct access is disabled
|
|
||||||
#
|
|
||||||
# test "Signing from private key object":
|
|
||||||
# for person in [alice, bob, eve]:
|
|
||||||
# let
|
|
||||||
# pk = initPrivateKey(person.privkey)
|
|
||||||
# signature = pk.sign_msg(MSG)
|
|
||||||
|
|
||||||
# check:
|
|
||||||
# signature.Fv == person.raw_sig.v
|
|
||||||
# signature.Fr == hexToByteArrayBE[32](person.raw_sig.r)
|
|
||||||
# signature.Fs == hexToByteArrayBE[32](person.raw_sig.s)
|
|
||||||
|
|
||||||
test "Signing from private key object (ported from official eth-keys)":
|
test "Signing from private key object (ported from official eth-keys)":
|
||||||
for person in [alice, bob, eve]:
|
for person in [alice, bob, eve]:
|
||||||
let
|
let
|
||||||
pk = initPrivateKey(person.privkey)
|
pk = initPrivateKey(person.privkey)
|
||||||
signature = pk.sign_msg(MSG)
|
signature = pk.sign_msg(MSG)
|
||||||
|
|
||||||
check: verify_msg(pk.Fpublic_key, MSG, signature)
|
check: verify_msg(pk.public_key, MSG, signature)
|
||||||
|
|
||||||
# TODO: For now due to needing hex <-> uint256 conversion
|
|
||||||
# Testing r, s, v direct access is disabled
|
|
||||||
#
|
|
||||||
# test "Hash signing from private key object":
|
|
||||||
# for person in [alice, bob, eve]:
|
|
||||||
# let
|
|
||||||
# pk = initPrivateKey(person.privkey)
|
|
||||||
# signature = pk.sign_msg(MSG)
|
|
||||||
|
|
||||||
# check:
|
|
||||||
# signature.Fv == person.raw_sig.v
|
|
||||||
# signature.Fr == hexToByteArrayBE[32](person.raw_sig.r)
|
|
||||||
# signature.Fs == hexToByteArrayBE[32](person.raw_sig.s)
|
|
||||||
|
|
||||||
test "Hash signing from private key object (ported from official eth-keys)":
|
test "Hash signing from private key object (ported from official eth-keys)":
|
||||||
for person in [alice, bob, eve]:
|
for person in [alice, bob, eve]:
|
||||||
|
@ -56,7 +28,7 @@ suite "Test key and signature data structure":
|
||||||
pk = initPrivateKey(person.privkey)
|
pk = initPrivateKey(person.privkey)
|
||||||
signature = pk.sign_msg(MSGHASH)
|
signature = pk.sign_msg(MSGHASH)
|
||||||
|
|
||||||
check: verify_msg(pk.Fpublic_key, MSGHASH, signature)
|
check: verify_msg(pk.public_key, MSGHASH, signature)
|
||||||
|
|
||||||
test "Recover public key from message":
|
test "Recover public key from message":
|
||||||
for person in [alice, bob, eve]:
|
for person in [alice, bob, eve]:
|
||||||
|
@ -66,7 +38,7 @@ suite "Test key and signature data structure":
|
||||||
|
|
||||||
recovered_pubkey = recover_pubkey_from_msg(MSG, signature)
|
recovered_pubkey = recover_pubkey_from_msg(MSG, signature)
|
||||||
|
|
||||||
check: pk.Fpublic_key == recovered_pubkey
|
check: pk.public_key == recovered_pubkey
|
||||||
|
|
||||||
test "Recover public key from message hash":
|
test "Recover public key from message hash":
|
||||||
for person in [alice, bob, eve]:
|
for person in [alice, bob, eve]:
|
||||||
|
@ -76,7 +48,7 @@ suite "Test key and signature data structure":
|
||||||
|
|
||||||
recovered_pubkey = recover_pubkey_from_msg(MSGHASH, signature)
|
recovered_pubkey = recover_pubkey_from_msg(MSGHASH, signature)
|
||||||
|
|
||||||
check: pk.Fpublic_key == recovered_pubkey
|
check: pk.public_key == recovered_pubkey
|
||||||
|
|
||||||
test "Signature serialization and deserialization":
|
test "Signature serialization and deserialization":
|
||||||
for person in [alice, bob, eve]:
|
for person in [alice, bob, eve]:
|
||||||
|
|
|
@ -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.Fpublic_key
|
let computed_pubkey = $privkey.public_key
|
||||||
|
|
||||||
check: computed_pubkey == person.pubkey
|
check: computed_pubkey == person.pubkey
|
||||||
|
|
Loading…
Reference in New Issue