Rebase on master (new serialization #9 and tests #11)

This commit is contained in:
mratsim 2018-03-21 16:45:39 +01:00
parent 6383b00bc2
commit b4f513c847
9 changed files with 65 additions and 60 deletions

View File

@ -9,7 +9,7 @@ srcDir = "src"
requires "nim >= 0.18.0", "keccak_tiny >= 0.1.0", "ttmath >= 0.1.0", "nimSHA2", "secp256k1"
proc test(name: string, lang: string = "cpp") =
proc test(name: string, lang: string = "c") =
if not dirExists "build":
mkDir "build"
if not dirExists "nimcache":
@ -19,9 +19,12 @@ proc test(name: string, lang: string = "cpp") =
switch("out", ("./build/" & name))
setCommand lang, "tests/" & name & ".nim"
task test, "Run all tests - libsecp256k1 backend":
task test, "Run all tests - C & libsecp256k1 backend":
test "all_tests"
task test_cpp, "Run all tests - C++ & libsecp256k1 backend":
test "all_tests", "cpp"
task test_backend_native, "Run all tests - pure Nim backend":
switch("define", "backend_native")
test "all_tests"
test "all_tests", "cpp"

View File

@ -7,7 +7,7 @@
#
# at your option. This file may not be copied, modified, or distributed except according to those terms.
import ../datatypes
import ../datatypes, ../private/conversion_bytes
import secp256k1, keccak_tiny
const SECP256K1_CONTEXT_ALL = SECP256K1_CONTEXT_VERIFY or SECP256K1_CONTEXT_SIGN

View File

@ -8,42 +8,19 @@
# at your option. This file may not be copied, modified, or distributed except according to those terms.
import ./private/conversion_bytes
export toHex, hexToByteArrayBE, hexToSeqByteBE
# Note: Fields are intentionally kept private
# Note: Fields F should be private, it is intentionally ugly to directly access them
# See private field access issue: https://github.com/nim-lang/Nim/issues/7390
type
PublicKey* = object
Fraw_key: array[64, byte]
Fraw_key*: array[64, byte]
PrivateKey* = object
Fraw_key: array[32, byte]
Fpublic_key: PublicKey
Fraw_key*: array[32, byte]
Fpublic_key*: PublicKey
Signature* {.packed.}= object
Fr: array[32, byte]
Fs: array[32, byte]
Fv: range[0.byte .. 1.byte]
Fr*: array[32, byte]
Fs*: array[32, byte]
Fv*: range[0.byte .. 1.byte] # This should be 27..28 as per Ethereum but it's 0..1 in eth-keys ...
# "Public" accessors, only exposed to internal modules
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): 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)
genAccessors(s, array[32, byte], Signature)
genAccessors(r, array[32, byte], Signature)
genAccessors(v, range[0.byte .. 1.byte], Signature)

View File

@ -13,7 +13,7 @@
# Note: for now only a native pure Nim backend is supported
# In the future alternative, proven crypto backend will be added like libsecpk1
import ./datatypes
import ./datatypes, ./private/conversion_bytes
import keccak_tiny
@ -31,8 +31,8 @@ else:
# Initialization
proc initPrivateKey*(hexString: string): PrivateKey {.noInit.} =
hexToByteArrayBE(hexString, result.raw_key)
result.public_key = private_key_to_public_key(result)
hexToByteArrayBE(hexString, result.Fraw_key)
result.Fpublic_key = private_key_to_public_key(result)
proc initPublicKey*(hexString: string): PublicKey {.noInit.} =
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)
proc `$`*(key: PrivateKey): string {.inline.} =
key.raw_key.toHex()
key.Fraw_key.toHex()

View File

@ -9,9 +9,15 @@
when defined(backend_native):
echo "\nBackend tested: native\n"
when defined(c):
{.fatal: "The native backend require C++ compilation for ttmath.}".}
else:
echo "\nBackend tested: libsecp256k1\n"
when not defined(cpp):
echo "C backend chosen. Skipping ttmath_hex_bytes_conversion test"
import ./test_hex_bytes_conversion,
./test_private_public_key_consistency,
when defined(cpp):
import ./test_ttmath_hex_bytes_conversion
import ./test_private_public_key_consistency,
./test_key_and_signature_datastructures

View File

@ -42,14 +42,16 @@ let
MSG* = "message"
MSGHASH* = keccak256(MSG)
# Conversion done through https://www.mobilefish.com/services/big_number/big_number.php
let
alice* = testKeySig(
privkey: "9c0257114eb9399a2985f8e75dad7600c5d89fe3824ffa99ec1c3eb8bf3b0501",
pubkey: "5eed5fa3a67696c334762bb4823e585e2ee579aba3558d9955296d6c04541b426078dbd48d74af1fd0c72aa1a05147cf17be6b60bdbed6ba19b08ec28445b0ca",
raw_sig: (
v: 1,
r: "80536744857756143861726945576089915884233437828013729338039544043241440681784",
s: "1902566422691403459035240420865094128779958320521066670269403689808757640701"
r: "B20E2EA5D3CBAA83C1E0372F110CF12535648613B479B64C1A8C1A20C5021F38", # Decimal "80536744857756143861726945576089915884233437828013729338039544043241440681784",
s: "434D07EC5795E3F789794351658E80B7FAF47A46328F41E019D7B853745CDFD" # Decimal "1902566422691403459035240420865094128779958320521066670269403689808757640701"
),
serialized_sig: "b20e2ea5d3cbaa83c1e0372f110cf12535648613b479b64c1a8c1a20c5021f380434d07ec5795e3f789794351658e80b7faf47a46328f41e019d7b853745cdfd01"
)
@ -59,8 +61,8 @@ let
pubkey: "347746ccb908e583927285fa4bd202f08e2f82f09c920233d89c47c79e48f937d049130e3d1c14cf7b21afefc057f71da73dec8e8ff74ff47dc6a574ccd5d570",
raw_sig: (
v: 1,
r: "41741612198399299636429810387160790514780876799439767175315078161978521003886",
s: "47545396818609319588074484786899049290652725314938191835667190243225814114102"
r: "5C48EA4F0F2257FA23BD25E6FCB0B75BBE2FF9BBDA0167118DAB2BB6E31BA76E", # Decimal "41741612198399299636429810387160790514780876799439767175315078161978521003886",
s: "691DBDAF2A231FC9958CD8EDD99507121F8184042E075CF10F98BA88ABFF1F36" # Decimal "47545396818609319588074484786899049290652725314938191835667190243225814114102"
),
serialized_sig: "5c48ea4f0f2257fa23bd25e6fcb0b75bbe2ff9bbda0167118dab2bb6e31ba76e691dbdaf2a231fc9958cd8edd99507121f8184042e075cf10f98ba88abff1f3601"
)
@ -70,8 +72,8 @@ let
pubkey: "c06641f0d04f64dba13eac9e52999f2d10a1ff0ca68975716b6583dee0318d91e7c2aed363ed22edeba2215b03f6237184833fd7d4ad65f75c2c1d5ea0abecc0",
raw_sig: (
v: 0,
r: "84467545608142925331782333363288012579669270632210954476013542647119929595395",
s: "43529886636775750164425297556346136250671451061152161143648812009114516499167"
r: "BABEEFC5082D3CA2E0BC80532AB38F9CFB196FB9977401B2F6A98061F15ED603", # Decimal "84467545608142925331782333363288012579669270632210954476013542647119929595395",
s: "603D0AF084BF906B2CDF6CDDE8B2E1C3E51A41AF5E9ADEC7F3643B3F1AA2AADF" # Decimal "43529886636775750164425297556346136250671451061152161143648812009114516499167"
),
serialized_sig: "babeefc5082d3ca2e0bc80532ab38f9cfb196fb9977401b2f6a98061f15ed603603d0af084bf906b2cdf6cdde8b2e1c3e51a41af5e9adec7f3643b3f1aa2aadf00"
)

View File

@ -7,7 +7,7 @@
#
# at your option. This file may not be copied, modified, or distributed except according to those terms.
import ../src/eth_keys,
import ../src/eth_keys, ../src/private/conversion_bytes,
./config
import unittest
@ -20,9 +20,9 @@ suite "Test key and signature data structure":
signature = pk.sign_msg(MSG)
check:
signature.v == person.raw_sig.v
signature.r == person.raw_sig.r.u256
signature.s == person.raw_sig.s.u256
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)":
for person in [alice, bob, eve]:
@ -30,7 +30,7 @@ suite "Test key and signature data structure":
pk = initPrivateKey(person.privkey)
signature = pk.sign_msg(MSG)
check: verify_msg(pk.public_key, MSG, signature)
check: verify_msg(pk.Fpublic_key, MSG, signature)
test "Hash signing from private key object":
for person in [alice, bob, eve]:
@ -39,9 +39,9 @@ suite "Test key and signature data structure":
signature = pk.sign_msg(MSG)
check:
signature.v == person.raw_sig.v
signature.r == person.raw_sig.r.u256
signature.s == person.raw_sig.s.u256
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)":
for person in [alice, bob, eve]:
@ -49,7 +49,7 @@ suite "Test key and signature data structure":
pk = initPrivateKey(person.privkey)
signature = pk.sign_msg(MSGHASH)
check: verify_msg(pk.public_key, MSGHASH, signature)
check: verify_msg(pk.Fpublic_key, MSGHASH, signature)
test "Recover public key from message":
for person in [alice, bob, eve]:
@ -59,7 +59,7 @@ suite "Test key and signature data structure":
recovered_pubkey = recover_pubkey_from_msg(MSG, signature)
check: pk.public_key == recovered_pubkey
check: pk.Fpublic_key == recovered_pubkey
test "Recover public key from message hash":
for person in [alice, bob, eve]:
@ -69,7 +69,7 @@ suite "Test key and signature data structure":
recovered_pubkey = recover_pubkey_from_msg(MSGHASH, signature)
check: pk.public_key == recovered_pubkey
check: pk.Fpublic_key == recovered_pubkey
test "Signature serialization and deserialization":
for person in [alice, bob, eve]:

View File

@ -17,6 +17,6 @@ suite "Testing private -> public key conversion":
for person in [alice, bob, eve]:
let privkey = initPrivateKey(person.privkey)
let computed_pubkey = $privkey.public_key
let computed_pubkey = $privkey.Fpublic_key
check: computed_pubkey == person.pubkey
check: computed_pubkey == person.pubkey

View File

@ -10,6 +10,7 @@
import ../src/private/[conversion_bytes, conversion_ttmath]
import unittest, ttmath, strutils # TODO remove ttmath needs if backend libsecp256k1
import ./config
suite "Testing conversion functions: Hex, Bytes, Endianness":
let
@ -27,3 +28,19 @@ suite "Testing conversion functions: Hex, Bytes, Endianness":
test "uint256 -> big-endian array -> hex":
check: SECPK1_N.toByteArrayBE.toHex == SECPK1_N_HEX
suite "Confirming consistency: hex vs decimal conversion":
# Conversion done through https://www.mobilefish.com/services/big_number/big_number.php
test "Alice signature":
check: alice.raw_sig.r.hexToUInt256 == "80536744857756143861726945576089915884233437828013729338039544043241440681784".u256
check: alice.raw_sig.s.hexToUInt256 == "1902566422691403459035240420865094128779958320521066670269403689808757640701".u256
test "Bob signature":
check: alice.raw_sig.r.hexToUInt256 == "41741612198399299636429810387160790514780876799439767175315078161978521003886".u256
check: alice.raw_sig.s.hexToUInt256 == "47545396818609319588074484786899049290652725314938191835667190243225814114102".u256
test "Eve signature":
check: alice.raw_sig.r.hexToUInt256 == "84467545608142925331782333363288012579669270632210954476013542647119929595395".u256
check: alice.raw_sig.s.hexToUInt256 == "43529886636775750164425297556346136250671451061152161143648812009114516499167".u256