Remove tests of private fields + Hide privat fields for real

This commit is contained in:
mratsim 2018-03-21 21:03:12 +01:00
parent a4ed335c8b
commit 85e7f11efe
6 changed files with 48 additions and 52 deletions

View File

@ -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"

View File

@ -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)

View File

@ -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()

View File

@ -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

View File

@ -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]:

View File

@ -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