diff --git a/libp2p.nimble b/libp2p.nimble index f6bd0e664..b5f94f43c 100644 --- a/libp2p.nimble +++ b/libp2p.nimble @@ -8,6 +8,7 @@ license = "MIT" skipDirs = @["tests", "examples", "Nim"] requires "nim > 0.18.0", + "secp256k1", "nimcrypto >= 0.3.9", "chronos" diff --git a/libp2p/crypto/crypto.nim b/libp2p/crypto/crypto.nim index c136c6950..a32ea9ab3 100644 --- a/libp2p/crypto/crypto.nim +++ b/libp2p/crypto/crypto.nim @@ -8,7 +8,7 @@ ## those terms. ## This module implements Public Key and Private Key interface for libp2p. -import rsa, ecnist, ed25519/ed25519 +import rsa, ecnist, ed25519/ed25519, secp import ../protobuf/minprotobuf, ../vbuffer import nimcrypto/[rijndael, blowfish, sha, sha2, hash, hmac, utils] @@ -42,7 +42,7 @@ type of Ed25519: edkey*: EdPublicKey of Secp256k1: - discard + skkey*: SkPublicKey of ECDSA: eckey*: EcPublicKey of NoSupport: @@ -55,7 +55,7 @@ type of Ed25519: edkey*: EdPrivateKey of Secp256k1: - discard + skkey*: SkPrivateKey of ECDSA: eckey*: EcPrivateKey of NoSupport: @@ -78,8 +78,9 @@ type P2pSigError* = object of CatchableError const - SupportedSchemes* = {RSA, Ed25519, ECDSA} - SupportedSchemesInt* = {int8(RSA), int8(Ed25519), int8(ECDSA)} + SupportedSchemes* = {RSA, Ed25519, Secp256k1, ECDSA} + SupportedSchemesInt* = {int8(RSA), int8(Ed25519), int8(Secp256k1), + int8(ECDSA)} proc random*(t: typedesc[PrivateKey], scheme: PKScheme, bits = DefaultKeySize): PrivateKey = @@ -95,6 +96,8 @@ proc random*(t: typedesc[PrivateKey], scheme: PKScheme, result.edkey = EdPrivateKey.random() elif scheme == ECDSA: result.eckey = EcPrivateKey.random(Secp256r1) + elif scheme == Secp256k1: + result.skkey = SkPrivateKey.random() proc random*(t: typedesc[KeyPair], scheme: PKScheme, bits = DefaultKeySize): KeyPair = @@ -117,6 +120,10 @@ proc random*(t: typedesc[KeyPair], scheme: PKScheme, var pair = EcKeyPair.random(Secp256r1) result.seckey.eckey = pair.seckey result.pubkey.eckey = pair.pubkey + elif scheme == Secp256k1: + var pair = SkKeyPair.random() + result.seckey.skkey = pair.seckey + result.pubkey.skkey = pair.pubkey proc getKey*(key: PrivateKey): PublicKey = ## Get public key from corresponding private key ``key``. @@ -127,6 +134,8 @@ proc getKey*(key: PrivateKey): PublicKey = result.edkey = key.edkey.getKey() elif key.scheme == ECDSA: result.eckey = key.eckey.getKey() + elif key.scheme == Secp256k1: + result.skkey = key.skkey.getKey() proc toRawBytes*(key: PrivateKey, data: var openarray[byte]): int = ## Serialize private key ``key`` (using scheme's own serialization) and store @@ -139,6 +148,8 @@ proc toRawBytes*(key: PrivateKey, data: var openarray[byte]): int = result = key.edkey.toBytes(data) elif key.scheme == ECDSA: result = key.eckey.toBytes(data) + elif key.scheme == Secp256k1: + result = key.skkey.toBytes(data) proc toRawBytes*(key: PublicKey, data: var openarray[byte]): int = ## Serialize public key ``key`` (using scheme's own serialization) and store @@ -151,6 +162,8 @@ proc toRawBytes*(key: PublicKey, data: var openarray[byte]): int = result = key.edkey.toBytes(data) elif key.scheme == ECDSA: result = key.eckey.toBytes(data) + elif key.scheme == Secp256k1: + result = key.skkey.toBytes(data) proc getRawBytes*(key: PrivateKey): seq[byte] = ## Return private key ``key`` in binary form (using scheme's own @@ -161,6 +174,8 @@ proc getRawBytes*(key: PrivateKey): seq[byte] = result = key.edkey.getBytes() elif key.scheme == ECDSA: result = key.eckey.getBytes() + elif key.scheme == Secp256k1: + result = key.skkey.getBytes() proc getRawBytes*(key: PublicKey): seq[byte] = ## Return public key ``key`` in binary form (using scheme's own @@ -171,6 +186,8 @@ proc getRawBytes*(key: PublicKey): seq[byte] = result = key.edkey.getBytes() elif key.scheme == ECDSA: result = key.eckey.getBytes() + elif key.scheme == Secp256k1: + result = key.skkey.getBytes() proc toBytes*(key: PrivateKey, data: var openarray[byte]): int = ## Serialize private key ``key`` (using libp2p protobuf scheme) and store @@ -254,6 +271,10 @@ proc init*(key: var PrivateKey, data: openarray[byte]): bool = if init(nkey.eckey, buffer) == Asn1Status.Success: key = nkey result = true + elif scheme == Secp256k1: + if init(nkey.skkey, buffer): + key = nkey + result = true proc init*(key: var PublicKey, data: openarray[byte]): bool = ## Initialize public key ``key`` from libp2p's protobuf serialized raw @@ -281,6 +302,10 @@ proc init*(key: var PublicKey, data: openarray[byte]): bool = if init(nkey.eckey, buffer) == Asn1Status.Success: key = nkey result = true + elif scheme == Secp256k1: + if init(nkey.skkey, buffer): + key = nkey + result = true proc init*(sig: var Signature, data: openarray[byte]): bool = ## Initialize signature ``sig`` from raw binary form. @@ -374,6 +399,10 @@ proc `$`*(key: PrivateKey): string = result = "Secp256r1 key (" result.add($(key.eckey)) result.add(")") + elif key.scheme == Secp256k1: + result = "Secp256k1 key (" + result.add($(key.skkey)) + result.add(")") proc `$`*(key: PublicKey): string = ## Get string representation of public key ``key``. @@ -387,6 +416,10 @@ proc `$`*(key: PublicKey): string = result = "Secp256r1 key (" result.add($(key.eckey)) result.add(")") + elif key.scheme == Secp256k1: + result = "Secp256k1 key (" + result.add($(key.skkey)) + result.add(")") proc `$`*(sig: Signature): string = ## Get string representation of signature ``sig``. @@ -404,6 +437,9 @@ proc sign*(key: PrivateKey, data: openarray[byte]): Signature = elif key.scheme == ECDSA: var sig = key.eckey.sign(data) result.data = sig.getBytes() + elif key.scheme == Secp256k1: + var sig = key.skkey.sign(data) + result.data = sig.getBytes() proc verify*(sig: Signature, message: openarray[byte], key: PublicKey): bool = @@ -421,6 +457,10 @@ proc verify*(sig: Signature, message: openarray[byte], var signature: EcSignature if signature.init(sig.data) == Asn1Status.Success: result = signature.verify(message, key.eckey) + elif key.scheme == Secp256k1: + var signature: SkSignature + if signature.init(sig.data): + result = signature.verify(message, key.skkey) template makeSecret(buffer, hmactype, secret, seed) = var ctx: hmactype diff --git a/libp2p/crypto/secp.nim b/libp2p/crypto/secp.nim new file mode 100644 index 000000000..c4a015421 --- /dev/null +++ b/libp2p/crypto/secp.nim @@ -0,0 +1,381 @@ +## Nim-Libp2p +## Copyright (c) 2018 Status Research & Development GmbH +## Licensed under either of +## * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE)) +## * MIT license ([LICENSE-MIT](LICENSE-MIT)) +## at your option. +## This file may not be copied, modified, or distributed except according to +## those terms. +import strutils +import secp256k1, nimcrypto/sysrand, nimcrypto/utils, nimcrypto/hash, + nimcrypto/sha2 +export sha2 + +const + SkRawPrivateKeySize* = 256 div 8 + ## Size of private key in octets (bytes) + SkRawSignatureSize* = SkRawPrivateKeySize * 2 + 1 + ## Size of signature in octets (bytes) + SkRawPublicKeySize* = SkRawPrivateKeySize + 1 + ## Size of public key in octets (bytes) + +type + SkPublicKey* = secp256k1_pubkey + ## Representation of public key. + + SkPrivateKey* = object + ## Representation of secret key. + data*: array[SkRawPrivateKeySize, byte] + + SkKeyPair* = object + ## Representation of private/public keys pair. + seckey*: SkPrivateKey + pubkey*: SkPublicKey + + SkSignature* = secp256k1_ecdsa_recoverable_signature + ## Representation of signature. + + SkContext* = ref object + ## Representation of Secp256k1 context object. + context: ptr secp256k1_context + error: string + + Secp256k1Error* = object of CatchableError + ## Exceptions generated by `libsecp256k1` + +## +## Private procedures interface +## + +var secpContext {.threadvar.}: SkContext + ## Thread local variable which holds current context + +proc illegalCallback(message: cstring, data: pointer) {.cdecl.} = + let ctx = cast[SkContext](data) + ctx.error = $message + +proc errorCallback(message: cstring, data: pointer) {.cdecl.} = + let ctx = cast[SkContext](data) + ctx.error = $message + +proc shutdownLibsecp256k1(ctx: SkContext) = + # TODO: use destructor when finalizer are deprecated for destructors + if not(isNil(ctx.context)): + secp256k1_context_destroy(ctx.context) + +proc newSkContext(): SkContext = + ## Create new Secp256k1 context object. + new(result, shutdownLibsecp256k1) + let flags = cuint(SECP256K1_CONTEXT_VERIFY or SECP256K1_CONTEXT_SIGN) + result.context = secp256k1_context_create(flags) + secp256k1_context_set_illegal_callback(result.context, illegalCallback, + cast[pointer](result)) + secp256k1_context_set_error_callback(result.context, errorCallback, + cast[pointer](result)) + result.error = "" + +proc getContext(): SkContext = + ## Get current `EccContext` + if isNil(secpContext): + secpContext = newSkContext() + result = secpContext + +template raiseSecp256k1Error() = + ## Raises `libsecp256k1` error as exception + let mctx = getContext() + if len(mctx.error) > 0: + let msg = mctx.error + mctx.error.setLen(0) + raise newException(Secp256k1Error, msg) + else: + raise newException(Secp256k1Error, "") + +proc init*(key: var SkPrivateKey, data: openarray[byte]): bool = + ## Initialize Secp256k1 `private key` ``key`` from raw binary + ## representation ``data``. + ## + ## Procedure returns ``true`` on success. + let ctx = getContext() + if len(data) >= SkRawPrivateKeySize: + let res = secp256k1_ec_seckey_verify(ctx.context, + cast[ptr cuchar](unsafeAddr data[0])) + result = (res == 1) and (len(ctx.error) == 0) + if result: + copyMem(addr key.data[0], unsafeAddr data[0], SkRawPrivateKeySize) + +proc init*(key: var SkPrivateKey, data: string): bool {.inline.} = + ## Initialize Secp256k1 `private key` ``key`` from hexadecimal string + ## representation ``data``. + ## + ## Procedure returns ``true`` on success. + var buffer: seq[byte] + try: + buffer = fromHex(stripSpaces(data)) + except: + return false + result = init(key, buffer) + +proc init*(key: var SkPublicKey, data: openarray[byte]): bool = + ## Initialize Secp256k1 `public key` ``key`` from raw binary + ## representation ``data``. + ## + ## Procedure returns ``true`` on success. + let ctx = getContext() + var length = 0 + if len(data) > 0: + if data[0] == 0x02'u8 or data[0] == 0x03'u8: + length = min(len(data), 33) + elif data[0] == 0x04'u8 or data[0] == 0x06'u8 or data[0] == 0x07'u8: + length = min(len(data), 65) + else: + return false + let res = secp256k1_ec_pubkey_parse(ctx.context, addr key, + cast[ptr cuchar](unsafeAddr data[0]), + length) + result = (res == 1) and (len(ctx.error) == 0) + +proc init*(key: var SkPublicKey, data: string): bool = + ## Initialize Secp256k1 `public key` ``key`` from hexadecimal string + ## representation ``data``. + ## + ## Procedure returns ``true`` on success. + var buffer: seq[byte] + try: + buffer = fromHex(stripSpaces(data)) + except: + return false + result = init(key, buffer) + +proc init*(sig: var SkSignature, data: openarray[byte]): bool = + ## Initialize Secp256k1 `signature` ``sig`` from raw binary + ## representation ``data``. + ## + ## Procedure returns ``true`` on success. + let ctx = getContext() + let length = len(data) + if length >= SkRawSignatureSize: + var recid = cint(data[SkRawPrivateKeySize * 2]) + let res = secp256k1_ecdsa_recoverable_signature_parse_compact(ctx.context, + addr sig, cast[ptr cuchar](unsafeAddr data[0]), recid) + result = (res == 1) and (len(ctx.error) == 0) + +proc init*(sig: var SkSignature, data: string): bool = + ## Initialize Secp256k1 `signature` ``sig`` from hexadecimal string + ## representation ``data``. + ## + ## Procedure returns ``true`` on success. + var buffer: seq[byte] + try: + buffer = fromHex(stripSpaces(data)) + except: + return false + result = init(sig, buffer) + +proc init*(t: typedesc[SkPrivateKey], + data: openarray[byte]): SkPrivateKey {.inline.} = + ## Initialize Secp256k1 `private key` from raw binary + ## representation ``data``. + ## + ## Procedure returns `private key` on success. + if not init(result, data): + raise newException(Secp256k1Error, "Incorrect binary form") + +proc init*(t: typedesc[SkPrivateKey], + data: string): SkPrivateKey {.inline.} = + ## Initialize Secp256k1 `private key` from hexadecimal string + ## representation ``data``. + ## + ## Procedure returns `private key` on success. + if not init(result, data): + raise newException(Secp256k1Error, "Incorrect binary form") + +proc init*(t: typedesc[SkPublicKey], + data: openarray[byte]): SkPublicKey {.inline.} = + ## Initialize Secp256k1 `public key` from raw binary + ## representation ``data``. + ## + ## Procedure returns `public key` on success. + if not init(result, data): + raise newException(Secp256k1Error, "Incorrect binary form") + +proc init*(t: typedesc[SkPublicKey], + data: string): SkPublicKey {.inline.} = + ## Initialize Secp256k1 `public key` from hexadecimal string + ## representation ``data``. + ## + ## Procedure returns `public key` on success. + if not init(result, data): + raise newException(Secp256k1Error, "Incorrect binary form") + +proc init*(t: typedesc[SkSignature], + data: openarray[byte]): SkSignature {.inline.} = + ## Initialize Secp256k1 `signature` from raw binary + ## representation ``data``. + ## + ## Procedure returns `signature` on success. + if not init(result, data): + raise newException(Secp256k1Error, "Incorrect binary form") + +proc init*(t: typedesc[SkSignature], + data: string): SkSignature {.inline.} = + ## Initialize Secp256k1 `signature` from hexadecimal string + ## representation ``data``. + ## + ## Procedure returns `signature` on success. + if not init(result, data): + raise newException(Secp256k1Error, "Incorrect binary form") + +proc getKey*(key: SkPrivateKey): SkPublicKey = + ## Calculate and return Secp256k1 `public key` from `private key` ``key``. + let ctx = getContext() + let res = secp256k1_ec_pubkey_create(ctx.context, addr result, + cast[ptr cuchar](unsafeAddr key)) + if (res != 1) or (len(ctx.error) != 0): + raiseSecp256k1Error() + +proc random*(t: typedesc[SkPrivateKey]): SkPrivateKey = + ## Generates new random private key. + let ctx = getContext() + while true: + if randomBytes(result.data) == SkRawPrivateKeySize: + let res = secp256k1_ec_seckey_verify(ctx.context, + cast[ptr cuchar](addr result.data[0])) + if (res == 1) and (len(ctx.error) == 0): + break + +proc random*(t: typedesc[SkKeyPair]): SkKeyPair {.inline.} = + ## Generates new random key pair. + result.seckey = SkPrivateKey.random() + result.pubkey = result.seckey.getKey() + +proc toBytes*(key: SkPrivateKey, data: var openarray[byte]): int = + ## Serialize Secp256k1 `private key` ``key`` to raw binary form and store it + ## to ``data``. + ## + ## Procedure returns number of bytes (octets) needed to store + ## Secp256k1 private key. + result = SkRawPrivateKeySize + if len(data) >= SkRawPrivateKeySize: + copyMem(addr data[0], unsafeAddr key.data[0], SkRawPrivateKeySize) + +proc toBytes*(key: SkPublicKey, data: var openarray[byte]): int = + ## Serialize Secp256k1 `public key` ``key`` to raw binary form and store it + ## to ``data``. + ## + ## Procedure returns number of bytes (octets) needed to store + ## Secp256k1 public key. + let ctx = getContext() + var length = csize(len(data)) + result = SkRawPublicKeySize + if len(data) >= SkRawPublicKeySize: + let res = secp256k1_ec_pubkey_serialize(ctx.context, + cast[ptr cuchar](addr data[0]), + addr length, unsafeAddr key, + SECP256K1_EC_COMPRESSED) + +proc toBytes*(sig: SkSignature, data: var openarray[byte]): int = + ## Serialize Secp256k1 `signature` ``sig`` to raw binary form and store it + ## to ``data``. + ## + ## Procedure returns number of bytes (octets) needed to store + ## Secp256k1 signature. + let ctx = getContext() + var recid = cint(0) + result = SkRawSignatureSize + if len(data) >= SkRawSignatureSize: + let res = secp256k1_ecdsa_recoverable_signature_serialize_compact( + ctx.context, cast[ptr cuchar](unsafeAddr data[0]), + addr recid, unsafeAddr sig) + if (res == 1) and (len(ctx.error) == 0): + data[64] = uint8(recid) + +proc getBytes*(key: SkPrivateKey): seq[byte] {.inline.} = + ## Serialize Secp256k1 `private key` and return it. + result = @(key.data) + +proc getBytes*(key: SkPublicKey): seq[byte] {.inline.} = + ## Serialize Secp256k1 `public key` and return it. + result = newSeq[byte](SkRawPublicKeySize) + discard toBytes(key, result) + +proc getBytes*(sig: SkSignature): seq[byte] {.inline.} = + ## Serialize Secp256k1 `signature` and return it. + result = newSeq[byte](SkRawSignatureSize) + discard toBytes(sig, result) + +proc `==`*(ska, skb: SkPrivateKey): bool = + ## Compare Secp256k1 `private key` objects for equality. + result = (ska.data == skb.data) + +proc `==`*(pka, pkb: SkPublicKey): bool = + ## Compare Secp256k1 `public key` objects for equality. + var + akey: array[SkRawPublicKeySize, byte] + bkey: array[SkRawPublicKeySize, byte] + discard pka.toBytes(akey) + discard pkb.toBytes(bkey) + result = (akey == bkey) + +proc `==`*(sia, sib: SkSignature): bool = + ## Compare Secp256k1 `signature` objects for equality. + var + asig: array[SkRawSignatureSize, byte] + bsig: array[SkRawSignatureSize, byte] + discard sia.toBytes(asig) + discard sib.toBytes(bsig) + result = (asig == bsig) + +proc `$`*(key: SkPrivateKey): string = toHex(key.data) + ## Return string representation of Secp256k1 `private key`. + +proc `$`*(key: SkPublicKey): string = + ## Return string representation of Secp256k1 `private key`.s + var spub: array[SkRawPublicKeySize, byte] + discard key.toBytes(spub) + result = toHex(spub) + +proc `$`*(sig: SkSignature): string = + ## Return string representation of Secp256k1 `signature`.s + var ssig: array[SkRawSignatureSize, byte] + discard sig.toBytes(ssig) + result = toHex(ssig) + +proc sign*[T: byte|char](key: SkPrivateKey, msg: openarray[T]): SkSignature = + ## Sign message `msg` using private key `key` and return signature object. + let ctx = getContext() + var hash = sha256.digest(msg) + let res = secp256k1_ecdsa_sign_recoverable(ctx.context, addr result, + cast[ptr cuchar](addr hash.data[0]), + cast[ptr cuchar](unsafeAddr key), + nil, nil) + if (res != 1) or (len(ctx.error) != 0): + raiseSecp256k1Error() + +proc verify*[T: byte|char](sig: SkSignature, msg: openarray[T], + key: SkPublicKey): bool = + var pubkey: SkPublicKey + let ctx = getContext() + var hash = sha256.digest(msg) + let res = secp256k1_ecdsa_recover(ctx.context, addr pubkey, unsafeAddr sig, + cast[ptr cuchar](addr hash.data[0])) + if (res == 1) and (len(ctx.error) == 0): + if key == pubkey: + result = true + +proc clear*(key: var SkPrivateKey) {.inline.} = + ## Wipe and clear memory of Secp256k1 `private key`. + burnMem(key.data) + +proc clear*(key: var SkPublicKey) {.inline.} = + ## Wipe and clear memory of Secp256k1 `public key`. + burnMem(addr key, SkRawPrivateKeySize * 2) + +proc clear*(sig: var SkSignature) {.inline.} = + ## Wipe and clear memory of Secp256k1 `signature`. + # Internal memory representation size of signature object is 64 bytes. + burnMem(addr sig, SkRawPrivateKeySize * 2) + +proc clear*(pair: var SkKeyPair) {.inline.} = + ## Wipe and clear memory of Secp256k1 `key pair`. + pair.seckey.clear() + pair.pubkey.clear() diff --git a/tests/testnative.nim b/tests/testnative.nim index c14ac8f5c..edb99400c 100644 --- a/tests/testnative.nim +++ b/tests/testnative.nim @@ -1,4 +1,4 @@ import unittest import testvarint, testbase32, testbase58, testbase64 -import testrsa, testecnist, tested25519, testcrypto +import testrsa, testecnist, tested25519, testsecp256k1, testcrypto import testmultibase, testmultihash, testmultiaddress, testcid, testpeer diff --git a/tests/testpeer.nim b/tests/testpeer.nim index 98f5ef80e..5d013f432 100644 --- a/tests/testpeer.nim +++ b/tests/testpeer.nim @@ -76,9 +76,9 @@ const 50BEB59FEAAC43389ABC490E11172750A94A01D155FE553DA9F559CE6687CDF 6160B6C11BDD02F58D5E28A2BB1C59F991CE52A49618185C82E750A044979""", # Secp256k1 keys - # "0802122053DADF1D5A164D6B4ACDB15E24AA4C5B1D3461BDBD42ABEDB0A4404D56CED8FB", - # "08021220FD659951E2ED440CC7ECE436357D123D4C8B3CF1056E3F1607FF3641FB578A1B", - # "08021220B333BE3E843339E0E2CE9E083ABC119BE05C7B65B8665ADE19E172D47BF91305" + "0802122053DADF1D5A164D6B4ACDB15E24AA4C5B1D3461BDBD42ABEDB0A4404D56CED8FB", + "08021220FD659951E2ED440CC7ECE436357D123D4C8B3CF1056E3F1607FF3641FB578A1B", + "08021220B333BE3E843339E0E2CE9E083ABC119BE05C7B65B8665ADE19E172D47BF91305" ] PeerIDs = [ @@ -91,10 +91,9 @@ const "QmVMT29id3TUASyfZZ6k9hmNyc2nYabCo4uMSpDw4zrgDk", "QmXz4wPSQqYF33qB7JRdSExETu56HgWRpE9bsf75HgeXL5", "Qmcfz2MaPjw44RfVpHKFgXwhW3uFBRBxByVEkgPhefKCJW", - # Secp256k1 peer ids - # "16Uiu2HAmLhLvBoYaoZfaMUKuibM6ac163GwKY74c5kiSLg5KvLpY", - # "16Uiu2HAmRRrT319h5upVoC3E8vs1Qej4UF3vPPnLgrhbpHhUb2Av", - # "16Uiu2HAmDrDaty3uYPgqSr1h5Cup32S2UdYo46rhqZfXPjJMABZL" + "16Uiu2HAmLhLvBoYaoZfaMUKuibM6ac163GwKY74c5kiSLg5KvLpY", + "16Uiu2HAmRRrT319h5upVoC3E8vs1Qej4UF3vPPnLgrhbpHhUb2Av", + "16Uiu2HAmDrDaty3uYPgqSr1h5Cup32S2UdYo46rhqZfXPjJMABZL" ] suite "Peer testing suite": diff --git a/tests/testsecp256k1.nim b/tests/testsecp256k1.nim new file mode 100644 index 000000000..84cba99fd --- /dev/null +++ b/tests/testsecp256k1.nim @@ -0,0 +1,71 @@ +## Nim-Libp2p +## Copyright (c) 2018 Status Research & Development GmbH +## Licensed under either of +## * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE)) +## * MIT license ([LICENSE-MIT](LICENSE-MIT)) +## at your option. +## This file may not be copied, modified, or distributed except according to +## those terms. +import unittest +import ../libp2p/crypto/secp +import nimcrypto/utils + +suite "Secp256k1 testing suite": + const TestsCount = 20 + test "Private key serialize/deserialize test": + for i in 0.. 0 + check: + rkey1.init(skey1) == true + rkey2.init(skey2) == true + var rkey3 = SkPrivateKey.init(skey1) + var rkey4 = SkPrivateKey.init(skey2) + check: + rkey1 == key + rkey2 == key + rkey3 == key + rkey4 == key + rkey1.clear() + rkey2.clear() + check: + isFullZero(rkey1.data) == true + isFullZero(rkey2.data) == true + test "Public key serialize/deserialize test": + for i in 0.. 0 + rkey1.init(skey1) == true + rkey2.init(skey2) == true + var rkey3 = SkPublicKey.init(skey1) + var rkey4 = SkPublicKey.init(skey2) + check: + rkey1 == pair.pubkey + rkey2 == pair.pubkey + rkey3 == pair.pubkey + rkey4 == pair.pubkey + rkey1.clear() + rkey2.clear() + test "Generate/Sign/Serialize/Deserialize/Verify test": + var message = "message to sign" + for i in 0..