nim-secp256k1/tests/test_secp256k1.nim

109 lines
3.2 KiB
Nim
Raw Permalink Normal View History

import
../secp256k1,
unittest,
stew/ptrops
2020-04-17 05:43:30 +00:00
{.used.}
const
msg0 = SkMessage([
0'u8, 0, 0, 0, 0, 0, 0, 0,
0'u8, 0, 0, 0, 0, 0, 0, 0,
0'u8, 0, 0, 0, 0, 0, 0, 0,
0'u8, 0, 0, 0, 0, 0, 0, 0,
])
msg1 = SkMessage([
2020-04-17 05:43:30 +00:00
1'u8, 0, 0, 0, 0, 0, 0, 0,
1'u8, 0, 0, 0, 0, 0, 0, 0,
1'u8, 0, 0, 0, 0, 0, 0, 0,
1'u8, 0, 0, 0, 0, 0, 0, 0,
])
msg2: array[40, byte] = [
Enable and expose Schnorrsig (#44) * Enable Schnorrsig module in wrapper The extrakeys module is a dependency for Schnorrsig, so that's enabled as well. * Add {.bycopy.} pragma * Add Schnorrsig interface to `abi.nim` Multikey interface is a dependency the for schnorrsig, so it was added as well. * Add tests for Schnorr signing * Fix schnorr magic const declaration on 1.6 and below * Remove unnecessary {.bycopy.} pragmas Done under the impression that {.bycopy.} is not necessary when only passing the object to C via ptr. * Make SkKeyPair a wrapper around secp256k1_keypair * Add more helper procs for new SkKeyPair * Small fixes * Re-order * Rework patch. Implement Schnorr signing and undo breaking changes. * Reduce code duplication * Fix type * Remove accidental extra indentation * Add `default` {.error.} proc for SkSchnorrSignature * Remove extra test * Add from/to raw/hex * Comments * Add low-level test for `secp256k1_keypair` * Fix errors on Nim 1.2 * Comment * Allow passing a `Rng`/`FoolproofRng` to `signSchnorr` for improved security * Comments * Correct `noncefp` to be a pointer in `extraparams` object * Remove unneeded {.bycopy.} Co-authored-by: Jacek Sieka <arnetheduck@gmail.com> * Don't check the RNG for Schnorr sig using private key requirements. * Add comment detailing that `signSchnorr` without an `rng` is discouraged * Remove non-`rng` signSchnorr variant from tests * Rename `signSchnorr` without `rng` to `signSchnorrUnsafe` * Unify `schnorrSig` implementations and add `array[32, bytes]` variant * Fix on Nim 1.2 * Make `signSchnorr` accept `Opt[array[32, byte]]` rather than `[array[32,byte]]` * Remove unused template param * Inline `signSchnorr Rng` procs * Remove `nimble.lock`, was breaking tests on Nim >1.6 Was causing `Error: cannot open file: stew/byteutils` * Correct template parameter naming * Consistently apply {.noinit.} pragma * `{.noinit.}` random byte array * Revert "`{.noinit.}` random byte array" This reverts commit a3f99817d9627880974be1ae81014fa17d14f2db. * Correct template pragmas * Explicitly declare `noncefp` as `nil` * Create and export `xonly_pubkey` wrapping type * Complete implementation of `SkXOnlyPublicKey` * Correct comment * Add tests for 'SkXOnlyPublicKey` * Correct conversion proc name * Correct conversion proc name cont. --------- Co-authored-by: Jacek Sieka <arnetheduck@gmail.com>
2023-04-11 08:17:03 +00:00
0'u8, 0, 0, 0, 0, 0, 0, 0,
0'u8, 0, 0, 0, 0, 0, 0, 0,
0'u8, 0, 0, 0, 0, 0, 0, 0,
0'u8, 0, 0, 0, 0, 0, 0, 0,
0'u8, 0, 0, 0, 0, 0, 0, 0,
]
2020-04-17 05:43:30 +00:00
proc workingRng(data: var openArray[byte]): bool =
data[0] += 1
true
proc brokenRng(data: var openArray[byte]): bool = false
2020-04-17 05:43:30 +00:00
suite "secp256k1":
test "Key ops":
let
sk = SkSecretKey.random(workingRng).expect("should get a key")
pk = sk.toPublicKey()
2020-04-17 05:43:30 +00:00
check:
SkSecretKey.fromRaw(sk.toRaw())[].toHex() == sk.toHex()
SkSecretKey.fromHex(sk.toHex())[].toHex() == sk.toHex()
SkPublicKey.fromRaw(pk.toRaw())[].toHex() == pk.toHex()
SkPublicKey.fromRaw(pk.toRawCompressed())[].toHex() == pk.toHex()
SkPublicKey.fromHex(pk.toHex())[].toHex() == pk.toHex()
Enable and expose Schnorrsig (#44) * Enable Schnorrsig module in wrapper The extrakeys module is a dependency for Schnorrsig, so that's enabled as well. * Add {.bycopy.} pragma * Add Schnorrsig interface to `abi.nim` Multikey interface is a dependency the for schnorrsig, so it was added as well. * Add tests for Schnorr signing * Fix schnorr magic const declaration on 1.6 and below * Remove unnecessary {.bycopy.} pragmas Done under the impression that {.bycopy.} is not necessary when only passing the object to C via ptr. * Make SkKeyPair a wrapper around secp256k1_keypair * Add more helper procs for new SkKeyPair * Small fixes * Re-order * Rework patch. Implement Schnorr signing and undo breaking changes. * Reduce code duplication * Fix type * Remove accidental extra indentation * Add `default` {.error.} proc for SkSchnorrSignature * Remove extra test * Add from/to raw/hex * Comments * Add low-level test for `secp256k1_keypair` * Fix errors on Nim 1.2 * Comment * Allow passing a `Rng`/`FoolproofRng` to `signSchnorr` for improved security * Comments * Correct `noncefp` to be a pointer in `extraparams` object * Remove unneeded {.bycopy.} Co-authored-by: Jacek Sieka <arnetheduck@gmail.com> * Don't check the RNG for Schnorr sig using private key requirements. * Add comment detailing that `signSchnorr` without an `rng` is discouraged * Remove non-`rng` signSchnorr variant from tests * Rename `signSchnorr` without `rng` to `signSchnorrUnsafe` * Unify `schnorrSig` implementations and add `array[32, bytes]` variant * Fix on Nim 1.2 * Make `signSchnorr` accept `Opt[array[32, byte]]` rather than `[array[32,byte]]` * Remove unused template param * Inline `signSchnorr Rng` procs * Remove `nimble.lock`, was breaking tests on Nim >1.6 Was causing `Error: cannot open file: stew/byteutils` * Correct template parameter naming * Consistently apply {.noinit.} pragma * `{.noinit.}` random byte array * Revert "`{.noinit.}` random byte array" This reverts commit a3f99817d9627880974be1ae81014fa17d14f2db. * Correct template pragmas * Explicitly declare `noncefp` as `nil` * Create and export `xonly_pubkey` wrapping type * Complete implementation of `SkXOnlyPublicKey` * Correct comment * Add tests for 'SkXOnlyPublicKey` * Correct conversion proc name * Correct conversion proc name cont. --------- Co-authored-by: Jacek Sieka <arnetheduck@gmail.com>
2023-04-11 08:17:03 +00:00
SkXOnlyPublicKey.fromRaw(pk.toXOnly.toRaw())[].toHex() == pk.toXOnly.toHex()
SkXOnlyPublicKey.fromHex(pk.toXOnly.toHex())[].toHex() == pk.toXOnly.toHex()
SkSecretKey.random(brokenRng).isErr
2020-04-17 05:43:30 +00:00
test "Signatures":
let
sk = SkSecretKey.random(workingRng)[]
pk = sk.toPublicKey()
otherPk = SkSecretKey.random(workingRng)[].toPublicKey()
sig = sign(sk, msg0)
sig2 = signRecoverable(sk, msg0)
Enable and expose Schnorrsig (#44) * Enable Schnorrsig module in wrapper The extrakeys module is a dependency for Schnorrsig, so that's enabled as well. * Add {.bycopy.} pragma * Add Schnorrsig interface to `abi.nim` Multikey interface is a dependency the for schnorrsig, so it was added as well. * Add tests for Schnorr signing * Fix schnorr magic const declaration on 1.6 and below * Remove unnecessary {.bycopy.} pragmas Done under the impression that {.bycopy.} is not necessary when only passing the object to C via ptr. * Make SkKeyPair a wrapper around secp256k1_keypair * Add more helper procs for new SkKeyPair * Small fixes * Re-order * Rework patch. Implement Schnorr signing and undo breaking changes. * Reduce code duplication * Fix type * Remove accidental extra indentation * Add `default` {.error.} proc for SkSchnorrSignature * Remove extra test * Add from/to raw/hex * Comments * Add low-level test for `secp256k1_keypair` * Fix errors on Nim 1.2 * Comment * Allow passing a `Rng`/`FoolproofRng` to `signSchnorr` for improved security * Comments * Correct `noncefp` to be a pointer in `extraparams` object * Remove unneeded {.bycopy.} Co-authored-by: Jacek Sieka <arnetheduck@gmail.com> * Don't check the RNG for Schnorr sig using private key requirements. * Add comment detailing that `signSchnorr` without an `rng` is discouraged * Remove non-`rng` signSchnorr variant from tests * Rename `signSchnorr` without `rng` to `signSchnorrUnsafe` * Unify `schnorrSig` implementations and add `array[32, bytes]` variant * Fix on Nim 1.2 * Make `signSchnorr` accept `Opt[array[32, byte]]` rather than `[array[32,byte]]` * Remove unused template param * Inline `signSchnorr Rng` procs * Remove `nimble.lock`, was breaking tests on Nim >1.6 Was causing `Error: cannot open file: stew/byteutils` * Correct template parameter naming * Consistently apply {.noinit.} pragma * `{.noinit.}` random byte array * Revert "`{.noinit.}` random byte array" This reverts commit a3f99817d9627880974be1ae81014fa17d14f2db. * Correct template pragmas * Explicitly declare `noncefp` as `nil` * Create and export `xonly_pubkey` wrapping type * Complete implementation of `SkXOnlyPublicKey` * Correct comment * Add tests for 'SkXOnlyPublicKey` * Correct conversion proc name * Correct conversion proc name cont. --------- Co-authored-by: Jacek Sieka <arnetheduck@gmail.com>
2023-04-11 08:17:03 +00:00
sig3 = signSchnorr(sk, msg0, workingRng)[]
sig4 = signSchnorr(sk, cast[array[SkMessageSize, byte]](msg0), workingRng)[]
sig5 = signSchnorr(sk, msg2, workingRng)[]
2020-04-17 05:43:30 +00:00
check:
verify(sig, msg0, pk)
not verify(sig, msg0, otherPk)
2020-04-17 05:43:30 +00:00
not verify(sig, msg1, pk)
recover(sig2, msg0)[] == pk
recover(sig2, msg1)[] != pk
SkSignature.fromDer(sig.toDer())[].toHex() == sig.toHex()
Enable and expose Schnorrsig (#44) * Enable Schnorrsig module in wrapper The extrakeys module is a dependency for Schnorrsig, so that's enabled as well. * Add {.bycopy.} pragma * Add Schnorrsig interface to `abi.nim` Multikey interface is a dependency the for schnorrsig, so it was added as well. * Add tests for Schnorr signing * Fix schnorr magic const declaration on 1.6 and below * Remove unnecessary {.bycopy.} pragmas Done under the impression that {.bycopy.} is not necessary when only passing the object to C via ptr. * Make SkKeyPair a wrapper around secp256k1_keypair * Add more helper procs for new SkKeyPair * Small fixes * Re-order * Rework patch. Implement Schnorr signing and undo breaking changes. * Reduce code duplication * Fix type * Remove accidental extra indentation * Add `default` {.error.} proc for SkSchnorrSignature * Remove extra test * Add from/to raw/hex * Comments * Add low-level test for `secp256k1_keypair` * Fix errors on Nim 1.2 * Comment * Allow passing a `Rng`/`FoolproofRng` to `signSchnorr` for improved security * Comments * Correct `noncefp` to be a pointer in `extraparams` object * Remove unneeded {.bycopy.} Co-authored-by: Jacek Sieka <arnetheduck@gmail.com> * Don't check the RNG for Schnorr sig using private key requirements. * Add comment detailing that `signSchnorr` without an `rng` is discouraged * Remove non-`rng` signSchnorr variant from tests * Rename `signSchnorr` without `rng` to `signSchnorrUnsafe` * Unify `schnorrSig` implementations and add `array[32, bytes]` variant * Fix on Nim 1.2 * Make `signSchnorr` accept `Opt[array[32, byte]]` rather than `[array[32,byte]]` * Remove unused template param * Inline `signSchnorr Rng` procs * Remove `nimble.lock`, was breaking tests on Nim >1.6 Was causing `Error: cannot open file: stew/byteutils` * Correct template parameter naming * Consistently apply {.noinit.} pragma * `{.noinit.}` random byte array * Revert "`{.noinit.}` random byte array" This reverts commit a3f99817d9627880974be1ae81014fa17d14f2db. * Correct template pragmas * Explicitly declare `noncefp` as `nil` * Create and export `xonly_pubkey` wrapping type * Complete implementation of `SkXOnlyPublicKey` * Correct comment * Add tests for 'SkXOnlyPublicKey` * Correct conversion proc name * Correct conversion proc name cont. --------- Co-authored-by: Jacek Sieka <arnetheduck@gmail.com>
2023-04-11 08:17:03 +00:00
verify(sig3, msg0, pk)
sig3 == sig4
verify(sig5, msg2, pk)
2020-04-17 05:43:30 +00:00
test "Message":
check:
SkMessage.fromBytes([]).isErr()
SkMessage.fromBytes([0'u8]).isErr()
SkMessage.fromBytes(array[32, byte](msg0)).isOk()
test "Custom hash function":
proc customHash(output: ptr byte, x32, y32: ptr byte, data: pointer): cint
{.cdecl, raises: [].} =
# Save x and y as uncompressed public key
output[] = 0x04
copyMem(output.offset(1), x32, 32)
copyMem(output.offset(33), y32, 32)
return 1
proc skone(_: type SkSecretKey): SkSecretKey =
# silence noisy warning: Cannot prove that 'result' is initialized.
result = SkSecretKey.random(workingRng)[]
var data: array[SkRawSecretKeySize, byte]
zeroMem(data[0].addr, data.len)
data[31] = 1
copyMem(result.addr, data[0].addr, data.len)
let
sone = SkSecretKey.skone()
sb32 = SkSecretKey.random(workingRng)[]
pk0 = sone.toPublicKey
pk1 = sb32.toPublicKey
var
# compute using ECDH function with custom hash function
outputEcdh = ecdh[65](sb32, pk0, customHash, nil).get
# compute "explicitly"
pointSer = pk1.toRaw
check equalMem(outputEcdh.addr, pointSer.addr, 65)