Merge pull request #31 from status-im/secp256k1

Secp256k1
This commit is contained in:
Eugene Kabanov 2019-09-02 22:04:49 +03:00 committed by GitHub
commit 2935b52d63
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 505 additions and 13 deletions

View File

@ -8,6 +8,7 @@ license = "MIT"
skipDirs = @["tests", "examples", "Nim"] skipDirs = @["tests", "examples", "Nim"]
requires "nim > 0.18.0", requires "nim > 0.18.0",
"secp256k1",
"nimcrypto >= 0.3.9", "nimcrypto >= 0.3.9",
"chronos" "chronos"

View File

@ -8,7 +8,7 @@
## those terms. ## those terms.
## This module implements Public Key and Private Key interface for libp2p. ## 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 ../protobuf/minprotobuf, ../vbuffer
import nimcrypto/[rijndael, blowfish, sha, sha2, hash, hmac, utils] import nimcrypto/[rijndael, blowfish, sha, sha2, hash, hmac, utils]
@ -42,7 +42,7 @@ type
of Ed25519: of Ed25519:
edkey*: EdPublicKey edkey*: EdPublicKey
of Secp256k1: of Secp256k1:
discard skkey*: SkPublicKey
of ECDSA: of ECDSA:
eckey*: EcPublicKey eckey*: EcPublicKey
of NoSupport: of NoSupport:
@ -55,7 +55,7 @@ type
of Ed25519: of Ed25519:
edkey*: EdPrivateKey edkey*: EdPrivateKey
of Secp256k1: of Secp256k1:
discard skkey*: SkPrivateKey
of ECDSA: of ECDSA:
eckey*: EcPrivateKey eckey*: EcPrivateKey
of NoSupport: of NoSupport:
@ -78,8 +78,9 @@ type
P2pSigError* = object of CatchableError P2pSigError* = object of CatchableError
const const
SupportedSchemes* = {RSA, Ed25519, ECDSA} SupportedSchemes* = {RSA, Ed25519, Secp256k1, ECDSA}
SupportedSchemesInt* = {int8(RSA), int8(Ed25519), int8(ECDSA)} SupportedSchemesInt* = {int8(RSA), int8(Ed25519), int8(Secp256k1),
int8(ECDSA)}
proc random*(t: typedesc[PrivateKey], scheme: PKScheme, proc random*(t: typedesc[PrivateKey], scheme: PKScheme,
bits = DefaultKeySize): PrivateKey = bits = DefaultKeySize): PrivateKey =
@ -95,6 +96,8 @@ proc random*(t: typedesc[PrivateKey], scheme: PKScheme,
result.edkey = EdPrivateKey.random() result.edkey = EdPrivateKey.random()
elif scheme == ECDSA: elif scheme == ECDSA:
result.eckey = EcPrivateKey.random(Secp256r1) result.eckey = EcPrivateKey.random(Secp256r1)
elif scheme == Secp256k1:
result.skkey = SkPrivateKey.random()
proc random*(t: typedesc[KeyPair], scheme: PKScheme, proc random*(t: typedesc[KeyPair], scheme: PKScheme,
bits = DefaultKeySize): KeyPair = bits = DefaultKeySize): KeyPair =
@ -117,6 +120,10 @@ proc random*(t: typedesc[KeyPair], scheme: PKScheme,
var pair = EcKeyPair.random(Secp256r1) var pair = EcKeyPair.random(Secp256r1)
result.seckey.eckey = pair.seckey result.seckey.eckey = pair.seckey
result.pubkey.eckey = pair.pubkey 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 = proc getKey*(key: PrivateKey): PublicKey =
## Get public key from corresponding private key ``key``. ## Get public key from corresponding private key ``key``.
@ -127,6 +134,8 @@ proc getKey*(key: PrivateKey): PublicKey =
result.edkey = key.edkey.getKey() result.edkey = key.edkey.getKey()
elif key.scheme == ECDSA: elif key.scheme == ECDSA:
result.eckey = key.eckey.getKey() result.eckey = key.eckey.getKey()
elif key.scheme == Secp256k1:
result.skkey = key.skkey.getKey()
proc toRawBytes*(key: PrivateKey, data: var openarray[byte]): int = proc toRawBytes*(key: PrivateKey, data: var openarray[byte]): int =
## Serialize private key ``key`` (using scheme's own serialization) and store ## 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) result = key.edkey.toBytes(data)
elif key.scheme == ECDSA: elif key.scheme == ECDSA:
result = key.eckey.toBytes(data) result = key.eckey.toBytes(data)
elif key.scheme == Secp256k1:
result = key.skkey.toBytes(data)
proc toRawBytes*(key: PublicKey, data: var openarray[byte]): int = proc toRawBytes*(key: PublicKey, data: var openarray[byte]): int =
## Serialize public key ``key`` (using scheme's own serialization) and store ## 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) result = key.edkey.toBytes(data)
elif key.scheme == ECDSA: elif key.scheme == ECDSA:
result = key.eckey.toBytes(data) result = key.eckey.toBytes(data)
elif key.scheme == Secp256k1:
result = key.skkey.toBytes(data)
proc getRawBytes*(key: PrivateKey): seq[byte] = proc getRawBytes*(key: PrivateKey): seq[byte] =
## Return private key ``key`` in binary form (using scheme's own ## 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() result = key.edkey.getBytes()
elif key.scheme == ECDSA: elif key.scheme == ECDSA:
result = key.eckey.getBytes() result = key.eckey.getBytes()
elif key.scheme == Secp256k1:
result = key.skkey.getBytes()
proc getRawBytes*(key: PublicKey): seq[byte] = proc getRawBytes*(key: PublicKey): seq[byte] =
## Return public key ``key`` in binary form (using scheme's own ## 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() result = key.edkey.getBytes()
elif key.scheme == ECDSA: elif key.scheme == ECDSA:
result = key.eckey.getBytes() result = key.eckey.getBytes()
elif key.scheme == Secp256k1:
result = key.skkey.getBytes()
proc toBytes*(key: PrivateKey, data: var openarray[byte]): int = proc toBytes*(key: PrivateKey, data: var openarray[byte]): int =
## Serialize private key ``key`` (using libp2p protobuf scheme) and store ## 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: if init(nkey.eckey, buffer) == Asn1Status.Success:
key = nkey key = nkey
result = true result = true
elif scheme == Secp256k1:
if init(nkey.skkey, buffer):
key = nkey
result = true
proc init*(key: var PublicKey, data: openarray[byte]): bool = proc init*(key: var PublicKey, data: openarray[byte]): bool =
## Initialize public key ``key`` from libp2p's protobuf serialized raw ## 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: if init(nkey.eckey, buffer) == Asn1Status.Success:
key = nkey key = nkey
result = true result = true
elif scheme == Secp256k1:
if init(nkey.skkey, buffer):
key = nkey
result = true
proc init*(sig: var Signature, data: openarray[byte]): bool = proc init*(sig: var Signature, data: openarray[byte]): bool =
## Initialize signature ``sig`` from raw binary form. ## Initialize signature ``sig`` from raw binary form.
@ -374,6 +399,10 @@ proc `$`*(key: PrivateKey): string =
result = "Secp256r1 key (" result = "Secp256r1 key ("
result.add($(key.eckey)) result.add($(key.eckey))
result.add(")") result.add(")")
elif key.scheme == Secp256k1:
result = "Secp256k1 key ("
result.add($(key.skkey))
result.add(")")
proc `$`*(key: PublicKey): string = proc `$`*(key: PublicKey): string =
## Get string representation of public key ``key``. ## Get string representation of public key ``key``.
@ -387,6 +416,10 @@ proc `$`*(key: PublicKey): string =
result = "Secp256r1 key (" result = "Secp256r1 key ("
result.add($(key.eckey)) result.add($(key.eckey))
result.add(")") result.add(")")
elif key.scheme == Secp256k1:
result = "Secp256k1 key ("
result.add($(key.skkey))
result.add(")")
proc `$`*(sig: Signature): string = proc `$`*(sig: Signature): string =
## Get string representation of signature ``sig``. ## Get string representation of signature ``sig``.
@ -404,6 +437,9 @@ proc sign*(key: PrivateKey, data: openarray[byte]): Signature =
elif key.scheme == ECDSA: elif key.scheme == ECDSA:
var sig = key.eckey.sign(data) var sig = key.eckey.sign(data)
result.data = sig.getBytes() 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], proc verify*(sig: Signature, message: openarray[byte],
key: PublicKey): bool = key: PublicKey): bool =
@ -421,6 +457,10 @@ proc verify*(sig: Signature, message: openarray[byte],
var signature: EcSignature var signature: EcSignature
if signature.init(sig.data) == Asn1Status.Success: if signature.init(sig.data) == Asn1Status.Success:
result = signature.verify(message, key.eckey) 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) = template makeSecret(buffer, hmactype, secret, seed) =
var ctx: hmactype var ctx: hmactype

381
libp2p/crypto/secp.nim Normal file
View File

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

View File

@ -1,4 +1,4 @@
import unittest import unittest
import testvarint, testbase32, testbase58, testbase64 import testvarint, testbase32, testbase58, testbase64
import testrsa, testecnist, tested25519, testcrypto import testrsa, testecnist, tested25519, testsecp256k1, testcrypto
import testmultibase, testmultihash, testmultiaddress, testcid, testpeer import testmultibase, testmultihash, testmultiaddress, testcid, testpeer

View File

@ -76,9 +76,9 @@ const
50BEB59FEAAC43389ABC490E11172750A94A01D155FE553DA9F559CE6687CDF 50BEB59FEAAC43389ABC490E11172750A94A01D155FE553DA9F559CE6687CDF
6160B6C11BDD02F58D5E28A2BB1C59F991CE52A49618185C82E750A044979""", 6160B6C11BDD02F58D5E28A2BB1C59F991CE52A49618185C82E750A044979""",
# Secp256k1 keys # Secp256k1 keys
# "0802122053DADF1D5A164D6B4ACDB15E24AA4C5B1D3461BDBD42ABEDB0A4404D56CED8FB", "0802122053DADF1D5A164D6B4ACDB15E24AA4C5B1D3461BDBD42ABEDB0A4404D56CED8FB",
# "08021220FD659951E2ED440CC7ECE436357D123D4C8B3CF1056E3F1607FF3641FB578A1B", "08021220FD659951E2ED440CC7ECE436357D123D4C8B3CF1056E3F1607FF3641FB578A1B",
# "08021220B333BE3E843339E0E2CE9E083ABC119BE05C7B65B8665ADE19E172D47BF91305" "08021220B333BE3E843339E0E2CE9E083ABC119BE05C7B65B8665ADE19E172D47BF91305"
] ]
PeerIDs = [ PeerIDs = [
@ -91,10 +91,9 @@ const
"QmVMT29id3TUASyfZZ6k9hmNyc2nYabCo4uMSpDw4zrgDk", "QmVMT29id3TUASyfZZ6k9hmNyc2nYabCo4uMSpDw4zrgDk",
"QmXz4wPSQqYF33qB7JRdSExETu56HgWRpE9bsf75HgeXL5", "QmXz4wPSQqYF33qB7JRdSExETu56HgWRpE9bsf75HgeXL5",
"Qmcfz2MaPjw44RfVpHKFgXwhW3uFBRBxByVEkgPhefKCJW", "Qmcfz2MaPjw44RfVpHKFgXwhW3uFBRBxByVEkgPhefKCJW",
# Secp256k1 peer ids "16Uiu2HAmLhLvBoYaoZfaMUKuibM6ac163GwKY74c5kiSLg5KvLpY",
# "16Uiu2HAmLhLvBoYaoZfaMUKuibM6ac163GwKY74c5kiSLg5KvLpY", "16Uiu2HAmRRrT319h5upVoC3E8vs1Qej4UF3vPPnLgrhbpHhUb2Av",
# "16Uiu2HAmRRrT319h5upVoC3E8vs1Qej4UF3vPPnLgrhbpHhUb2Av", "16Uiu2HAmDrDaty3uYPgqSr1h5Cup32S2UdYo46rhqZfXPjJMABZL"
# "16Uiu2HAmDrDaty3uYPgqSr1h5Cup32S2UdYo46rhqZfXPjJMABZL"
] ]
suite "Peer testing suite": suite "Peer testing suite":

71
tests/testsecp256k1.nim Normal file
View File

@ -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..<TestsCount:
var rkey1, rkey2: SkPrivateKey
var skey2 = newSeq[byte](256)
var key = SkPrivateKey.random()
var skey1 = key.getBytes()
check:
key.toBytes(skey2) > 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..<TestsCount:
var rkey1, rkey2: SkPublicKey
var skey2 = newSeq[byte](256)
var pair = SkKeyPair.random()
var skey1 = pair.pubkey.getBytes()
check:
pair.pubkey.toBytes(skey2) > 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..<TestsCount:
var kp = SkKeyPair.random()
var sig = kp.seckey.sign(message)
var sersk = kp.seckey.getBytes()
var serpk = kp.pubkey.getBytes()
var sersig = sig.getBytes()
var seckey = SkPrivateKey.init(sersk)
var pubkey = SkPublicKey.init(serpk)
var csig = SkSignature.init(sersig)
check csig.verify(message, pubkey) == true
let error = len(csig.data) - 1
csig.data[error] = not(csig.data[error])
check csig.verify(message, pubkey) == false