reuse single RNG instance for all crypto key generation (#249)

* reuse single RNG instance for all crypto key generation

* use foolproof rng

* initRng -> newRng (because it's ref)

* fix test

* imports/exports, chat fix

* fix rsa

* imports and exports

* work around threadvar issue

* fixup

* mac workaround test
This commit is contained in:
Jacek Sieka 2020-07-07 13:14:11 +02:00 committed by GitHub
parent b49c619ca8
commit d522537b19
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 352 additions and 299 deletions

View File

@ -1,7 +1,7 @@
when not(compileOption("threads")): when not(compileOption("threads")):
{.fatal: "Please, compile this program with the --threads:on option!".} {.fatal: "Please, compile this program with the --threads:on option!".}
import tables, strformat, strutils import tables, strformat, strutils, bearssl
import chronos # an efficient library for async import chronos # an efficient library for async
import ../libp2p/[switch, # manage transports, a single entry point for dialing and listening import ../libp2p/[switch, # manage transports, a single entry point for dialing and listening
multistream, # tag stream with short header to identify it multistream, # tag stream with short header to identify it
@ -149,10 +149,10 @@ proc readInput(wfd: AsyncFD) {.thread.} =
let line = stdin.readLine() let line = stdin.readLine()
discard waitFor transp.write(line & "\r\n") discard waitFor transp.write(line & "\r\n")
proc processInput(rfd: AsyncFD) {.async.} = proc processInput(rfd: AsyncFD, rng: ref BrHmacDrbgContext) {.async.} =
let transp = fromPipe(rfd) let transp = fromPipe(rfd)
let seckey = PrivateKey.random(RSA).get() let seckey = PrivateKey.random(RSA, rng[]).get()
let peerInfo = PeerInfo.init(seckey) let peerInfo = PeerInfo.init(seckey)
var localAddress = DefaultAddr var localAddress = DefaultAddr
while true: while true:
@ -178,7 +178,7 @@ proc processInput(rfd: AsyncFD) {.async.} =
let transports = @[Transport(TcpTransport.init())] let transports = @[Transport(TcpTransport.init())]
let muxers = [(MplexCodec, mplexProvider)].toTable() let muxers = [(MplexCodec, mplexProvider)].toTable()
let identify = newIdentify(peerInfo) let identify = newIdentify(peerInfo)
let secureManagers = [Secure(newSecio(seckey))] let secureManagers = [Secure(newSecio(rng, seckey))]
let switch = newSwitch(peerInfo, let switch = newSwitch(peerInfo,
transports, transports,
identify, identify,
@ -200,6 +200,7 @@ proc processInput(rfd: AsyncFD) {.async.} =
await allFuturesThrowing(libp2pFuts) await allFuturesThrowing(libp2pFuts)
proc main() {.async.} = proc main() {.async.} =
let rng = newRng() # Singe random number source for the whole application
let (rfd, wfd) = createAsyncPipe() let (rfd, wfd) = createAsyncPipe()
if rfd == asyncInvalidPipe or wfd == asyncInvalidPipe: if rfd == asyncInvalidPipe or wfd == asyncInvalidPipe:
raise newException(ValueError, "Could not initialize pipe!") raise newException(ValueError, "Could not initialize pipe!")
@ -207,7 +208,7 @@ proc main() {.async.} =
var thread: Thread[AsyncFD] var thread: Thread[AsyncFD]
thread.createThread(readInput, wfd) thread.createThread(readInput, wfd)
await processInput(rfd) await processInput(rfd, rng)
when isMainModule: # isMainModule = true when the module is compiled as the main file when isMainModule: # isMainModule = true when the module is compiled as the main file
waitFor(main()) waitFor(main())

View File

@ -11,14 +11,14 @@
{.push raises: [Defect].} {.push raises: [Defect].}
import rsa, ecnist, ed25519/ed25519, secp import rsa, ecnist, ed25519/ed25519, secp, bearssl
import ../protobuf/minprotobuf, ../vbuffer, ../multihash, ../multicodec import ../protobuf/minprotobuf, ../vbuffer, ../multihash, ../multicodec
import nimcrypto/[rijndael, blowfish, twofish, sha, sha2, hash, hmac, utils] import nimcrypto/[rijndael, blowfish, twofish, sha, sha2, hash, hmac, utils]
import ../utility import ../utility
import stew/results import stew/results
export results export results
# This is workaround for Nim's `import` bug # Export modules of types that are part of public API
export rijndael, blowfish, twofish, sha, sha2, hash, hmac, utils export rijndael, blowfish, twofish, sha, sha2, hash, hmac, utils
from strutils import split from strutils import split
@ -46,26 +46,26 @@ type
PublicKey* = object PublicKey* = object
case scheme*: PKScheme case scheme*: PKScheme
of RSA: of RSA:
rsakey*: RsaPublicKey rsakey*: rsa.RsaPublicKey
of Ed25519: of Ed25519:
edkey*: EdPublicKey edkey*: EdPublicKey
of Secp256k1: of Secp256k1:
skkey*: SkPublicKey skkey*: SkPublicKey
of ECDSA: of ECDSA:
eckey*: EcPublicKey eckey*: ecnist.EcPublicKey
of NoSupport: of NoSupport:
discard discard
PrivateKey* = object PrivateKey* = object
case scheme*: PKScheme case scheme*: PKScheme
of RSA: of RSA:
rsakey*: RsaPrivateKey rsakey*: rsa.RsaPrivateKey
of Ed25519: of Ed25519:
edkey*: EdPrivateKey edkey*: EdPrivateKey
of Secp256k1: of Secp256k1:
skkey*: SkPrivateKey skkey*: SkPrivateKey
of ECDSA: of ECDSA:
eckey*: EcPrivateKey eckey*: ecnist.EcPrivateKey
of NoSupport: of NoSupport:
discard discard
@ -98,52 +98,68 @@ const
template orError*(exp: untyped, err: untyped): untyped = template orError*(exp: untyped, err: untyped): untyped =
(exp.mapErr do (_: auto) -> auto: err) (exp.mapErr do (_: auto) -> auto: err)
proc random*(t: typedesc[PrivateKey], scheme: PKScheme, proc newRng*(): ref BrHmacDrbgContext =
bits = DefaultKeySize): CryptoResult[PrivateKey] = # You should only create one instance of the RNG per application / library
# Ref is used so that it can be shared between components
# TODO consider moving to bearssl
var seeder = brPrngSeederSystem(nil)
if seeder == nil:
return nil
var rng = (ref BrHmacDrbgContext)()
brHmacDrbgInit(addr rng[], addr sha256Vtable, nil, 0)
if seeder(addr rng.vtable) == 0:
return nil
rng
proc random*(
T: typedesc[PrivateKey], scheme: PKScheme,
rng: var BrHmacDrbgContext, bits = DefaultKeySize): CryptoResult[PrivateKey] =
## Generate random private key for scheme ``scheme``. ## Generate random private key for scheme ``scheme``.
## ##
## ``bits`` is number of bits for RSA key, ``bits`` value must be in ## ``bits`` is number of bits for RSA key, ``bits`` value must be in
## [512, 4096], default value is 2048 bits. ## [512, 4096], default value is 2048 bits.
case scheme case scheme
of RSA: of RSA:
let rsakey = ? RsaPrivateKey.random(bits).orError(KeyError) let rsakey = ? RsaPrivateKey.random(rng, bits).orError(KeyError)
ok(PrivateKey(scheme: scheme, rsakey: rsakey)) ok(PrivateKey(scheme: scheme, rsakey: rsakey))
of Ed25519: of Ed25519:
let edkey = ? EdPrivateKey.random().orError(KeyError) let edkey = EdPrivateKey.random(rng)
ok(PrivateKey(scheme: scheme, edkey: edkey)) ok(PrivateKey(scheme: scheme, edkey: edkey))
of ECDSA: of ECDSA:
let eckey = ? EcPrivateKey.random(Secp256r1).orError(KeyError) let eckey = ? ecnist.EcPrivateKey.random(Secp256r1, rng).orError(KeyError)
ok(PrivateKey(scheme: scheme, eckey: eckey)) ok(PrivateKey(scheme: scheme, eckey: eckey))
of Secp256k1: of Secp256k1:
let skkey = ? SkPrivateKey.random().orError(KeyError) let skkey = SkPrivateKey.random(rng)
ok(PrivateKey(scheme: scheme, skkey: skkey)) ok(PrivateKey(scheme: scheme, skkey: skkey))
else: else:
err(SchemeError) err(SchemeError)
proc random*(t: typedesc[KeyPair], scheme: PKScheme, proc random*(
bits = DefaultKeySize): CryptoResult[KeyPair] = T: typedesc[KeyPair], scheme: PKScheme,
rng: var BrHmacDrbgContext, bits = DefaultKeySize): CryptoResult[KeyPair] =
## Generate random key pair for scheme ``scheme``. ## Generate random key pair for scheme ``scheme``.
## ##
## ``bits`` is number of bits for RSA key, ``bits`` value must be in ## ``bits`` is number of bits for RSA key, ``bits`` value must be in
## [512, 4096], default value is 2048 bits. ## [512, 4096], default value is 2048 bits.
case scheme case scheme
of RSA: of RSA:
let pair = ? RsaKeyPair.random(bits).orError(KeyError) let pair = ? RsaKeyPair.random(rng, bits).orError(KeyError)
ok(KeyPair( ok(KeyPair(
seckey: PrivateKey(scheme: scheme, rsakey: pair.seckey), seckey: PrivateKey(scheme: scheme, rsakey: pair.seckey),
pubkey: PublicKey(scheme: scheme, rsakey: pair.pubkey))) pubkey: PublicKey(scheme: scheme, rsakey: pair.pubkey)))
of Ed25519: of Ed25519:
let pair = ? EdKeyPair.random().orError(KeyError) let pair = EdKeyPair.random(rng)
ok(KeyPair( ok(KeyPair(
seckey: PrivateKey(scheme: scheme, edkey: pair.seckey), seckey: PrivateKey(scheme: scheme, edkey: pair.seckey),
pubkey: PublicKey(scheme: scheme, edkey: pair.pubkey))) pubkey: PublicKey(scheme: scheme, edkey: pair.pubkey)))
of ECDSA: of ECDSA:
let pair = ? EcKeyPair.random(Secp256r1).orError(KeyError) let pair = ? EcKeyPair.random(Secp256r1, rng).orError(KeyError)
ok(KeyPair( ok(KeyPair(
seckey: PrivateKey(scheme: scheme, eckey: pair.seckey), seckey: PrivateKey(scheme: scheme, eckey: pair.seckey),
pubkey: PublicKey(scheme: scheme, eckey: pair.pubkey))) pubkey: PublicKey(scheme: scheme, eckey: pair.pubkey)))
of Secp256k1: of Secp256k1:
let pair = ? SkKeyPair.random().orError(KeyError) let pair = SkKeyPair.random(rng)
ok(KeyPair( ok(KeyPair(
seckey: PrivateKey(scheme: scheme, skkey: pair.seckey), seckey: PrivateKey(scheme: scheme, skkey: pair.seckey),
pubkey: PublicKey(scheme: scheme, skkey: pair.pubkey))) pubkey: PublicKey(scheme: scheme, skkey: pair.pubkey)))
@ -629,32 +645,35 @@ proc mac*(secret: Secret, id: int): seq[byte] {.inline.} =
offset += secret.ivsize + secret.keysize offset += secret.ivsize + secret.keysize
copyMem(addr result[0], unsafeAddr secret.data[offset], secret.macsize) copyMem(addr result[0], unsafeAddr secret.data[offset], secret.macsize)
proc ephemeral*(scheme: ECDHEScheme): CryptoResult[KeyPair] = proc ephemeral*(
scheme: ECDHEScheme,
rng: var BrHmacDrbgContext): CryptoResult[KeyPair] =
## Generate ephemeral keys used to perform ECDHE. ## Generate ephemeral keys used to perform ECDHE.
var keypair: EcKeyPair var keypair: EcKeyPair
if scheme == Secp256r1: if scheme == Secp256r1:
keypair = ? EcKeyPair.random(Secp256r1).orError(KeyError) keypair = ? EcKeyPair.random(Secp256r1, rng).orError(KeyError)
elif scheme == Secp384r1: elif scheme == Secp384r1:
keypair = ? EcKeyPair.random(Secp384r1).orError(KeyError) keypair = ? EcKeyPair.random(Secp384r1, rng).orError(KeyError)
elif scheme == Secp521r1: elif scheme == Secp521r1:
keypair = ? EcKeyPair.random(Secp521r1).orError(KeyError) keypair = ? EcKeyPair.random(Secp521r1, rng).orError(KeyError)
ok(KeyPair( ok(KeyPair(
seckey: PrivateKey(scheme: ECDSA, eckey: keypair.seckey), seckey: PrivateKey(scheme: ECDSA, eckey: keypair.seckey),
pubkey: PublicKey(scheme: ECDSA, eckey: keypair.pubkey))) pubkey: PublicKey(scheme: ECDSA, eckey: keypair.pubkey)))
proc ephemeral*(scheme: string): CryptoResult[KeyPair] {.inline.} = proc ephemeral*(
scheme: string, rng: var BrHmacDrbgContext): CryptoResult[KeyPair] =
## Generate ephemeral keys used to perform ECDHE using string encoding. ## Generate ephemeral keys used to perform ECDHE using string encoding.
## ##
## Currently supported encoding strings are P-256, P-384, P-521, if encoding ## Currently supported encoding strings are P-256, P-384, P-521, if encoding
## string is not supported P-521 key will be generated. ## string is not supported P-521 key will be generated.
if scheme == "P-256": if scheme == "P-256":
ephemeral(Secp256r1) ephemeral(Secp256r1, rng)
elif scheme == "P-384": elif scheme == "P-384":
ephemeral(Secp384r1) ephemeral(Secp384r1, rng)
elif scheme == "P-521": elif scheme == "P-521":
ephemeral(Secp521r1) ephemeral(Secp521r1, rng)
else: else:
ephemeral(Secp521r1) ephemeral(Secp521r1, rng)
proc makeSecret*(remoteEPublic: PublicKey, localEPrivate: PrivateKey, proc makeSecret*(remoteEPublic: PublicKey, localEPrivate: PrivateKey,
data: var openarray[byte]): int = data: var openarray[byte]): int =

View File

@ -29,7 +29,7 @@ type
Curve25519Key* = array[Curve25519KeySize, byte] Curve25519Key* = array[Curve25519KeySize, byte]
pcuchar = ptr cuchar pcuchar = ptr cuchar
Curve25519Error* = enum Curve25519Error* = enum
Curver25519RngError Curver25519GenError
proc intoCurve25519Key*(s: openarray[byte]): Curve25519Key = proc intoCurve25519Key*(s: openarray[byte]): Curve25519Key =
assert s.len == Curve25519KeySize assert s.len == Curve25519KeySize
@ -105,16 +105,10 @@ proc mulgen*(_: type[Curve25519], dst: var Curve25519Key, point: Curve25519Key)
proc public*(private: Curve25519Key): Curve25519Key = proc public*(private: Curve25519Key): Curve25519Key =
Curve25519.mulgen(result, private) Curve25519.mulgen(result, private)
proc random*(_: type[Curve25519Key]): Result[Curve25519Key, Curve25519Error] = proc random*(_: type[Curve25519Key], rng: var BrHmacDrbgContext): Result[Curve25519Key, Curve25519Error] =
var rng: BrHmacDrbgContext
var res: Curve25519Key var res: Curve25519Key
let seeder = brPrngSeederSystem(nil) let defaultBrEc = brEcGetDefault()
brHmacDrbgInit(addr rng, addr sha256Vtable, nil, 0) if brEcKeygen(addr rng.vtable, defaultBrEc, nil, addr res[0], EC_curve25519) != Curve25519KeySize:
if seeder(addr rng.vtable) == 0: err(Curver25519GenError)
err(Curver25519RngError)
else: else:
let defaultBrEc = brEcGetDefault() ok(res)
if brEcKeygen(addr rng.vtable, defaultBrEc, nil, addr res[0], EC_curve25519) != Curve25519KeySize:
err(Curver25519RngError)
else:
ok(res)

View File

@ -227,17 +227,14 @@ proc clear*[T: EcPKI|EcKeyPair](pki: var T) =
pki.pubkey.key.qlen = 0 pki.pubkey.key.qlen = 0
pki.pubkey.key.curve = 0 pki.pubkey.key.curve = 0
proc random*(t: typedesc[EcPrivateKey], kind: EcCurveKind): EcResult[EcPrivateKey] = proc random*(
T: typedesc[EcPrivateKey], kind: EcCurveKind,
rng: var BrHmacDrbgContext): EcResult[EcPrivateKey] =
## Generate new random EC private key using BearSSL's HMAC-SHA256-DRBG ## Generate new random EC private key using BearSSL's HMAC-SHA256-DRBG
## algorithm. ## algorithm.
## ##
## ``kind`` elliptic curve kind of your choice (secp256r1, secp384r1 or ## ``kind`` elliptic curve kind of your choice (secp256r1, secp384r1 or
## secp521r1). ## secp521r1).
var rng: BrHmacDrbgContext
var seeder = brPrngSeederSystem(nil)
brHmacDrbgInit(addr rng, addr sha256Vtable, nil, 0)
if seeder(addr rng.vtable) == 0:
return err(EcRngError)
var ecimp = brEcGetDefault() var ecimp = brEcGetDefault()
var res = new EcPrivateKey var res = new EcPrivateKey
res.buffer = newSeq[byte](BR_EC_KBUF_PRIV_MAX_SIZE) res.buffer = newSeq[byte](BR_EC_KBUF_PRIV_MAX_SIZE)
@ -266,14 +263,16 @@ proc getKey*(seckey: EcPrivateKey): EcResult[EcPublicKey] =
else: else:
err(EcKeyIncorrectError) err(EcKeyIncorrectError)
proc random*(t: typedesc[EcKeyPair], kind: EcCurveKind): EcResult[EcKeyPair] = proc random*(
T: typedesc[EcKeyPair], kind: EcCurveKind,
rng: var BrHmacDrbgContext): EcResult[T] =
## Generate new random EC private and public keypair using BearSSL's ## Generate new random EC private and public keypair using BearSSL's
## HMAC-SHA256-DRBG algorithm. ## HMAC-SHA256-DRBG algorithm.
## ##
## ``kind`` elliptic curve kind of your choice (secp256r1, secp384r1 or ## ``kind`` elliptic curve kind of your choice (secp256r1, secp384r1 or
## secp521r1). ## secp521r1).
let let
seckey = ? EcPrivateKey.random(kind) seckey = ? EcPrivateKey.random(kind, rng)
pubkey = ? seckey.getKey() pubkey = ? seckey.getKey()
key = EcKeyPair(seckey: seckey, pubkey: pubkey) key = EcKeyPair(seckey: seckey, pubkey: pubkey)
ok(key) ok(key)

View File

@ -13,8 +13,8 @@
{.push raises: Defect.} {.push raises: Defect.}
import constants import constants, bearssl
import nimcrypto/[hash, sha2, sysrand, utils] import nimcrypto/[hash, sha2, utils]
import stew/results import stew/results
export results export results
@ -44,7 +44,6 @@ type
pubkey*: EdPublicKey pubkey*: EdPublicKey
EdError* = enum EdError* = enum
EdRngError,
EdIncorrectError EdIncorrectError
proc `-`(x: uint32): uint32 {.inline.} = proc `-`(x: uint32): uint32 {.inline.} =
@ -1643,41 +1642,43 @@ proc checkScalar*(scalar: openarray[byte]): uint32 =
c = -1 c = -1
result = NEQ(z, 0'u32) and LT0(c) result = NEQ(z, 0'u32) and LT0(c)
proc random*(t: typedesc[EdPrivateKey]): Result[EdPrivateKey, EdError] = proc random*(t: typedesc[EdPrivateKey], rng: var BrHmacDrbgContext): EdPrivateKey =
## Generate new random ED25519 private key using OS specific CSPRNG. ## Generate new random ED25519 private key using the given random number generator
var var
point: GeP3 point: GeP3
pk: array[EdPublicKeySize, byte] pk: array[EdPublicKeySize, byte]
res: EdPrivateKey res: EdPrivateKey
if randomBytes(res.data.toOpenArray(0, 31)) != 32:
err(EdRngError)
else:
var hh = sha512.digest(res.data.toOpenArray(0, 31))
hh.data[0] = hh.data[0] and 0xF8'u8
hh.data[31] = hh.data[31] and 0x3F'u8
hh.data[31] = hh.data[31] or 0x40'u8
geScalarMultBase(point, hh.data)
geP3ToBytes(pk, point)
copyMem(addr res.data[32], addr pk[0], 32)
ok(res)
proc random*(t: typedesc[EdKeyPair]): Result[EdKeyPair, EdError] = brHmacDrbgGenerate(addr rng, addr res.data[0], 32)
var hh = sha512.digest(res.data.toOpenArray(0, 31))
hh.data[0] = hh.data[0] and 0xF8'u8
hh.data[31] = hh.data[31] and 0x3F'u8
hh.data[31] = hh.data[31] or 0x40'u8
geScalarMultBase(point, hh.data)
geP3ToBytes(pk, point)
res.data[32..63] = pk
res
proc random*(t: typedesc[EdKeyPair], rng: var BrHmacDrbgContext): EdKeyPair =
## Generate new random ED25519 private and public keypair using OS specific ## Generate new random ED25519 private and public keypair using OS specific
## CSPRNG. ## CSPRNG.
var var
point: GeP3 point: GeP3
res: EdKeyPair res: EdKeyPair
if randomBytes(res.seckey.data.toOpenArray(0, 31)) != 32:
err(EdRngError) brHmacDrbgGenerate(addr rng, addr res.seckey.data[0], 32)
else:
var hh = sha512.digest(res.seckey.data.toOpenArray(0, 31)) var hh = sha512.digest(res.seckey.data.toOpenArray(0, 31))
hh.data[0] = hh.data[0] and 0xF8'u8 hh.data[0] = hh.data[0] and 0xF8'u8
hh.data[31] = hh.data[31] and 0x3F'u8 hh.data[31] = hh.data[31] and 0x3F'u8
hh.data[31] = hh.data[31] or 0x40'u8 hh.data[31] = hh.data[31] or 0x40'u8
geScalarMultBase(point, hh.data) geScalarMultBase(point, hh.data)
geP3ToBytes(res.pubkey.data, point) geP3ToBytes(res.pubkey.data, point)
copyMem(addr res.seckey.data[32], addr res.pubkey.data[0], 32) res.seckey.data[32..63] = res.pubkey.data
ok(res)
res
proc getKey*(key: EdPrivateKey): EdPublicKey = proc getKey*(key: EdPrivateKey): EdPublicKey =
## Calculate and return ED25519 public key from private key ``key``. ## Calculate and return ED25519 public key from private key ``key``.

View File

@ -17,8 +17,6 @@ import nimcrypto/utils
type type
Asn1Error* {.pure.} = enum Asn1Error* {.pure.} = enum
None,
Error,
Overflow, Overflow,
Incomplete, Incomplete,
Indefinite, Indefinite,

View File

@ -76,7 +76,6 @@ type
RsaKP* = RsaPrivateKey | RsaKeyPair RsaKP* = RsaPrivateKey | RsaKeyPair
RsaError* = enum RsaError* = enum
RsaRngError,
RsaGenError, RsaGenError,
RsaKeyIncorrectError, RsaKeyIncorrectError,
RsaSignatureError RsaSignatureError
@ -112,7 +111,8 @@ template trimZeroes(b: seq[byte], pt, ptlen: untyped) =
pt = cast[ptr cuchar](cast[uint](pt) + 1) pt = cast[ptr cuchar](cast[uint](pt) + 1)
ptlen -= 1 ptlen -= 1
proc random*[T: RsaKP](t: typedesc[T], bits = DefaultKeySize, proc random*[T: RsaKP](t: typedesc[T], rng: var BrHmacDrbgContext,
bits = DefaultKeySize,
pubexp = DefaultPublicExponent): RsaResult[T] = pubexp = DefaultPublicExponent): RsaResult[T] =
## Generate new random RSA private key using BearSSL's HMAC-SHA256-DRBG ## Generate new random RSA private key using BearSSL's HMAC-SHA256-DRBG
## algorithm. ## algorithm.
@ -121,38 +121,26 @@ proc random*[T: RsaKP](t: typedesc[T], bits = DefaultKeySize,
## range [512, 4096] (default = 2048). ## range [512, 4096] (default = 2048).
## ##
## ``pubexp`` is RSA public exponent, which must be prime (default = 3). ## ``pubexp`` is RSA public exponent, which must be prime (default = 3).
var rng: BrHmacDrbgContext let
var keygen: BrRsaKeygen sko = 0
var seeder = brPrngSeederSystem(nil) pko = brRsaPrivateKeyBufferSize(bits)
brHmacDrbgInit(addr rng, addr sha256Vtable, nil, 0) eko = pko + brRsaPublicKeyBufferSize(bits)
if seeder(addr rng.vtable) == 0: length = eko + ((bits + 7) shr 3)
return err(RsaRngError)
keygen = brRsaKeygenGetDefault()
let length = brRsaPrivateKeyBufferSize(bits) +
brRsaPublicKeyBufferSize(bits) +
((bits + 7) shr 3)
let sko = 0
let pko = brRsaPrivateKeyBufferSize(bits)
let eko = pko + brRsaPublicKeyBufferSize(bits)
var res: T
when T is RsaKeyPair:
res = new T
else:
res = new RsaPrivateKey
let res = new T
res.buffer = newSeq[byte](length) res.buffer = newSeq[byte](length)
var keygen = brRsaKeygenGetDefault()
if keygen(addr rng.vtable, if keygen(addr rng.vtable,
addr res.seck, addr res.buffer[sko], addr res.seck, addr res.buffer[sko],
addr res.pubk, addr res.buffer[pko], addr res.pubk, addr res.buffer[pko],
cuint(bits), pubexp) == 0: cuint(bits), pubexp) == 0:
return err(RsaGenError) return err(RsaGenError)
let compute = brRsaComputePrivexpGetDefault() let
let computed = compute(addr res.buffer[eko], addr res.seck, pubexp) compute = brRsaComputePrivexpGetDefault()
computed = compute(addr res.buffer[eko], addr res.seck, pubexp)
if computed == 0: if computed == 0:
return err(RsaGenError) return err(RsaGenError)

View File

@ -9,10 +9,12 @@
{.push raises: [Defect].} {.push raises: [Defect].}
import secp256k1, stew/byteutils, nimcrypto/hash, nimcrypto/sha2 import
export sha2 secp256k1, bearssl,
import stew/results stew/[byteutils, results],
export results nimcrypto/[hash, sha2]
export sha2, results
const const
SkRawPrivateKeySize* = 256 div 8 SkRawPrivateKeySize* = 256 div 8
@ -32,11 +34,19 @@ type
template pubkey*(v: SkKeyPair): SkPublicKey = SkPublicKey(secp256k1.SkKeyPair(v).pubkey) template pubkey*(v: SkKeyPair): SkPublicKey = SkPublicKey(secp256k1.SkKeyPair(v).pubkey)
template seckey*(v: SkKeyPair): SkPrivateKey = SkPrivateKey(secp256k1.SkKeyPair(v).seckey) template seckey*(v: SkKeyPair): SkPrivateKey = SkPrivateKey(secp256k1.SkKeyPair(v).seckey)
proc random*(t: typedesc[SkPrivateKey]): SkResult[SkPrivateKey] = proc random*(t: typedesc[SkPrivateKey], rng: var BrHmacDrbgContext): SkPrivateKey =
ok(SkPrivateKey(? SkSecretKey.random())) let rngPtr = unsafeAddr rng # doesn't escape
proc callRng(data: var openArray[byte]) =
brHmacDrbgGenerate(rngPtr[], data)
proc random*(t: typedesc[SkKeyPair]): SkResult[SkKeyPair] = SkPrivateKey(SkSecretKey.random(callRng))
ok(SkKeyPair(? secp256k1.SkKeyPair.random()))
proc random*(t: typedesc[SkKeyPair], rng: var BrHmacDrbgContext): SkKeyPair =
let rngPtr = unsafeAddr rng # doesn't escape
proc callRng(data: var openArray[byte]) =
brHmacDrbgGenerate(rngPtr[], data)
SkKeyPair(secp256k1.SkKeyPair.random(callRng))
template seckey*(v: SkKeyPair): SkPrivateKey = template seckey*(v: SkKeyPair): SkPrivateKey =
SkPrivateKey(secp256k1.SkKeyPair(v).seckey) SkPrivateKey(secp256k1.SkKeyPair(v).seckey)
@ -90,14 +100,14 @@ proc init*(t: typedesc[SkPrivateKey], data: openarray[byte]): SkResult[SkPrivate
## representation ``data``. ## representation ``data``.
## ##
## Procedure returns `private key` on success. ## Procedure returns `private key` on success.
ok(SkPrivateKey(? SkSecretKey.fromRaw(data))) SkSecretKey.fromRaw(data).mapConvert(SkPrivateKey)
proc init*(t: typedesc[SkPrivateKey], data: string): SkResult[SkPrivateKey] = proc init*(t: typedesc[SkPrivateKey], data: string): SkResult[SkPrivateKey] =
## Initialize Secp256k1 `private key` from hexadecimal string ## Initialize Secp256k1 `private key` from hexadecimal string
## representation ``data``. ## representation ``data``.
## ##
## Procedure returns `private key` on success. ## Procedure returns `private key` on success.
ok(SkPrivateKey(? SkSecretKey.fromHex(data))) SkSecretKey.fromHex(data).mapConvert(SkPrivateKey)
proc init*(t: typedesc[SkPublicKey], data: openarray[byte]): SkResult[SkPublicKey] = proc init*(t: typedesc[SkPublicKey], data: openarray[byte]): SkResult[SkPublicKey] =
## Initialize Secp256k1 `public key` from raw binary ## Initialize Secp256k1 `public key` from raw binary
@ -169,11 +179,11 @@ proc toBytes*(sig: SkSignature, data: var openarray[byte]): int =
proc getBytes*(key: SkPrivateKey): seq[byte] {.inline.} = proc getBytes*(key: SkPrivateKey): seq[byte] {.inline.} =
## Serialize Secp256k1 `private key` and return it. ## Serialize Secp256k1 `private key` and return it.
result = @(SkSecretKey(key).toRaw()) @(SkSecretKey(key).toRaw())
proc getBytes*(key: SkPublicKey): seq[byte] {.inline.} = proc getBytes*(key: SkPublicKey): seq[byte] {.inline.} =
## Serialize Secp256k1 `public key` and return it. ## Serialize Secp256k1 `public key` and return it.
result = @(secp256k1.SkPublicKey(key).toRawCompressed()) @(secp256k1.SkPublicKey(key).toRawCompressed())
proc getBytes*(sig: SkSignature): seq[byte] {.inline.} = proc getBytes*(sig: SkSignature): seq[byte] {.inline.} =
## Serialize Secp256k1 `signature` and return it. ## Serialize Secp256k1 `signature` and return it.
@ -184,12 +194,12 @@ proc getBytes*(sig: SkSignature): seq[byte] {.inline.} =
proc sign*[T: byte|char](key: SkPrivateKey, msg: openarray[T]): SkSignature = proc sign*[T: byte|char](key: SkPrivateKey, msg: openarray[T]): SkSignature =
## Sign message `msg` using private key `key` and return signature object. ## Sign message `msg` using private key `key` and return signature object.
let h = sha256.digest(msg) let h = sha256.digest(msg)
SkSignature(sign(SkSecretKey(key), h)) SkSignature(sign(SkSecretKey(key), SkMessage(h.data)))
proc verify*[T: byte|char](sig: SkSignature, msg: openarray[T], proc verify*[T: byte|char](sig: SkSignature, msg: openarray[T],
key: SkPublicKey): bool = key: SkPublicKey): bool =
let h = sha256.digest(msg) let h = sha256.digest(msg)
verify(secp256k1.SkSignature(sig), h, secp256k1.SkPublicKey(key)) verify(secp256k1.SkSignature(sig), SkMessage(h.data), secp256k1.SkPublicKey(key))
func clear*(key: var SkPrivateKey) {.borrow.} func clear*(key: var SkPrivateKey) {.borrow.}

View File

@ -33,6 +33,7 @@ type
lifefut: Future[void] lifefut: Future[void]
protoVersion*: string protoVersion*: string
agentVersion*: string agentVersion*: string
secure*: string
case keyType*: KeyType: case keyType*: KeyType:
of HasPrivate: of HasPrivate:
privateKey*: PrivateKey privateKey*: PrivateKey

View File

@ -9,8 +9,9 @@
import chronos import chronos
import chronicles import chronicles
import bearssl
import stew/[endians2, byteutils] import stew/[endians2, byteutils]
import nimcrypto/[utils, sysrand, sha2, hmac] import nimcrypto/[utils, sha2, hmac]
import ../../stream/lpstream import ../../stream/lpstream
import ../../peerid import ../../peerid
import ../../peerinfo import ../../peerinfo
@ -69,10 +70,10 @@ type
rs: Curve25519Key rs: Curve25519Key
Noise* = ref object of Secure Noise* = ref object of Secure
rng: ref BrHmacDrbgContext
localPrivateKey: PrivateKey localPrivateKey: PrivateKey
localPublicKey: PublicKey localPublicKey: PublicKey
noisePrivateKey: Curve25519Key noiseKeys: KeyPair
noisePublicKey: Curve25519Key
commonPrologue: seq[byte] commonPrologue: seq[byte]
outgoing: bool outgoing: bool
@ -87,8 +88,8 @@ type
# Utility # Utility
proc genKeyPair(): KeyPair = proc genKeyPair(rng: var BrHmacDrbgContext): KeyPair =
result.privateKey = Curve25519Key.random().tryGet() result.privateKey = Curve25519Key.random(rng).tryGet()
result.publicKey = result.privateKey.public() result.publicKey = result.privateKey.public()
proc hashProtocol(name: string): MDigest[256] = proc hashProtocol(name: string): MDigest[256] =
@ -200,7 +201,7 @@ proc init(_: type[HandshakeState]): HandshakeState =
template write_e: untyped = template write_e: untyped =
trace "noise write e" trace "noise write e"
# Sets e (which must be empty) to GENERATE_KEYPAIR(). Appends e.public_key to the buffer. Calls MixHash(e.public_key). # Sets e (which must be empty) to GENERATE_KEYPAIR(). Appends e.public_key to the buffer. Calls MixHash(e.public_key).
hs.e = genKeyPair() hs.e = genKeyPair(p.rng[])
msg &= hs.e.publicKey msg &= hs.e.publicKey
hs.ss.mixHash(hs.e.publicKey) hs.ss.mixHash(hs.e.publicKey)
@ -293,8 +294,7 @@ proc handshakeXXOutbound(p: Noise, conn: Connection, p2pProof: ProtoBuffer): Fut
p2psecret = p2pProof.buffer p2psecret = p2pProof.buffer
hs.ss.mixHash(p.commonPrologue) hs.ss.mixHash(p.commonPrologue)
hs.s.privateKey = p.noisePrivateKey hs.s = p.noiseKeys
hs.s.publicKey = p.noisePublicKey
# -> e # -> e
var msg: seq[byte] var msg: seq[byte]
@ -340,8 +340,7 @@ proc handshakeXXInbound(p: Noise, conn: Connection, p2pProof: ProtoBuffer): Futu
p2psecret = p2pProof.buffer p2psecret = p2pProof.buffer
hs.ss.mixHash(p.commonPrologue) hs.ss.mixHash(p.commonPrologue)
hs.s.privateKey = p.noisePrivateKey hs.s = p.noiseKeys
hs.s.publicKey = p.noisePublicKey
# -> e # -> e
@ -418,7 +417,7 @@ method handshake*(p: Noise, conn: Connection, initiator: bool): Future[SecureCon
# https://github.com/libp2p/specs/tree/master/noise#libp2p-data-in-handshake-messages # https://github.com/libp2p/specs/tree/master/noise#libp2p-data-in-handshake-messages
let let
signedPayload = p.localPrivateKey.sign( signedPayload = p.localPrivateKey.sign(
PayloadString.toBytes & p.noisePublicKey.getBytes).tryGet() PayloadString.toBytes & p.noiseKeys.publicKey.getBytes).tryGet()
var var
libp2pProof = initProtoBuffer() libp2pProof = initProtoBuffer()
@ -485,12 +484,15 @@ method init*(p: Noise) {.gcsafe.} =
procCall Secure(p).init() procCall Secure(p).init()
p.codec = NoiseCodec p.codec = NoiseCodec
proc newNoise*(privateKey: PrivateKey; outgoing: bool = true; commonPrologue: seq[byte] = @[]): Noise = proc newNoise*(
new result rng: ref BrHmacDrbgContext, privateKey: PrivateKey;
result.outgoing = outgoing outgoing: bool = true; commonPrologue: seq[byte] = @[]): Noise =
result.localPrivateKey = privateKey result = Noise(
result.localPublicKey = privateKey.getKey().tryGet() rng: rng,
result.noisePrivateKey = Curve25519Key.random().tryGet() outgoing: outgoing,
result.noisePublicKey = result.noisePrivateKey.public() localPrivateKey: privateKey,
result.commonPrologue = commonPrologue localPublicKey: privateKey.getKey().tryGet(),
noiseKeys: genKeyPair(rng[]),
commonPrologue: commonPrologue,
)
result.init() result.init()

View File

@ -6,8 +6,8 @@
## at your option. ## at your option.
## This file may not be copied, modified, or distributed except according to ## This file may not be copied, modified, or distributed except according to
## those terms. ## those terms.
import chronos, chronicles, oids, stew/endians2 import chronos, chronicles, oids, stew/endians2, bearssl
import nimcrypto/[sysrand, hmac, sha2, sha, hash, rijndael, twofish, bcmode] import nimcrypto/[hmac, sha2, sha, hash, rijndael, twofish, bcmode]
import secure, import secure,
../../stream/connection, ../../stream/connection,
../../peerinfo, ../../peerinfo,
@ -32,6 +32,7 @@ const
type type
Secio = ref object of Secure Secio = ref object of Secure
rng: ref BrHmacDrbgContext
localPrivateKey: PrivateKey localPrivateKey: PrivateKey
localPublicKey: PublicKey localPublicKey: PublicKey
remotePublicKey: PublicKey remotePublicKey: PublicKey
@ -288,8 +289,7 @@ method handshake*(s: Secio, conn: Connection, initiator: bool = false): Future[S
localPeerId: PeerID localPeerId: PeerID
localBytesPubkey = s.localPublicKey.getBytes().tryGet() localBytesPubkey = s.localPublicKey.getBytes().tryGet()
if randomBytes(localNonce) != SecioNonceSize: brHmacDrbgGenerate(s.rng[], localNonce)
raise (ref SecioError)(msg: "Could not generate random data")
var request = createProposal(localNonce, var request = createProposal(localNonce,
localBytesPubkey, localBytesPubkey,
@ -340,7 +340,7 @@ method handshake*(s: Secio, conn: Connection, initiator: bool = false): Future[S
trace "Encryption scheme selected", scheme = scheme, cipher = cipher, trace "Encryption scheme selected", scheme = scheme, cipher = cipher,
hash = hash hash = hash
var ekeypair = ephemeral(scheme).tryGet() var ekeypair = ephemeral(scheme, s.rng[]).tryGet()
# We need EC public key in raw binary form # We need EC public key in raw binary form
var epubkey = ekeypair.pubkey.eckey.getRawBytes().tryGet() var epubkey = ekeypair.pubkey.eckey.getRawBytes().tryGet()
var localCorpus = request[4..^1] & answer & epubkey var localCorpus = request[4..^1] & answer & epubkey
@ -410,8 +410,10 @@ method init(s: Secio) {.gcsafe.} =
procCall Secure(s).init() procCall Secure(s).init()
s.codec = SecioCodec s.codec = SecioCodec
proc newSecio*(localPrivateKey: PrivateKey): Secio = proc newSecio*(rng: ref BrHmacDrbgContext, localPrivateKey: PrivateKey): Secio =
new result result = Secio(
result.localPrivateKey = localPrivateKey rng: rng,
result.localPublicKey = localPrivateKey.getKey().tryGet() localPrivateKey: localPrivateKey,
localPublicKey: localPrivateKey.getKey().tryGet(),
)
result.init() result.init()

View File

@ -8,7 +8,7 @@
## those terms. ## those terms.
import options import options
import chronos, chronicles import chronos, chronicles, bearssl
import ../protocol, import ../protocol,
../../stream/streamseq, ../../stream/streamseq,
../../stream/connection, ../../stream/connection,
@ -66,6 +66,8 @@ proc handleConn*(s: Secure, conn: Connection, initiator: bool): Future[Connectio
return sconn return sconn
method init*(s: Secure) {.gcsafe.} = method init*(s: Secure) {.gcsafe.} =
procCall LPProtocol(s).init()
proc handle(conn: Connection, proto: string) {.async, gcsafe.} = proc handle(conn: Connection, proto: string) {.async, gcsafe.} =
trace "handling connection upgrade", proto trace "handling connection upgrade", proto
try: try:

View File

@ -4,7 +4,7 @@ const
libp2p_pubsub_verify {.booldefine.} = true libp2p_pubsub_verify {.booldefine.} = true
import import
options, tables, chronos, options, tables, chronos, bearssl,
switch, peerid, peerinfo, stream/connection, multiaddress, switch, peerid, peerinfo, stream/connection, multiaddress,
crypto/crypto, transports/[transport, tcptransport], crypto/crypto, transports/[transport, tcptransport],
muxers/[muxer, mplex/mplex, mplex/types], muxers/[muxer, mplex/mplex, mplex/types],
@ -36,12 +36,16 @@ proc newStandardSwitch*(privKey = none(PrivateKey),
verifySignature = libp2p_pubsub_verify, verifySignature = libp2p_pubsub_verify,
sign = libp2p_pubsub_sign, sign = libp2p_pubsub_sign,
transportFlags: set[ServerFlags] = {}, transportFlags: set[ServerFlags] = {},
msgIdProvider: MsgIdProvider = defaultMsgIdProvider): Switch = msgIdProvider: MsgIdProvider = defaultMsgIdProvider,
rng = newRng()): Switch =
proc createMplex(conn: Connection): Muxer = proc createMplex(conn: Connection): Muxer =
newMplex(conn) newMplex(conn)
if rng == nil: # newRng could fail
raise (ref CatchableError)(msg: "Cannot initialize RNG")
let let
seckey = privKey.get(otherwise = PrivateKey.random(ECDSA).tryGet()) seckey = privKey.get(otherwise = PrivateKey.random(ECDSA, rng[]).tryGet())
peerInfo = PeerInfo.init(seckey, [address]) peerInfo = PeerInfo.init(seckey, [address])
mplexProvider = newMuxerProvider(createMplex, MplexCodec) mplexProvider = newMuxerProvider(createMplex, MplexCodec)
transports = @[Transport(TcpTransport.init(transportFlags))] transports = @[Transport(TcpTransport.init(transportFlags))]
@ -53,9 +57,9 @@ proc newStandardSwitch*(privKey = none(PrivateKey),
for sec in secureManagers: for sec in secureManagers:
case sec case sec
of SecureProtocol.Noise: of SecureProtocol.Noise:
secureManagerInstances &= newNoise(seckey).Secure secureManagerInstances &= newNoise(rng, seckey).Secure
of SecureProtocol.Secio: of SecureProtocol.Secio:
secureManagerInstances &= newSecio(seckey).Secure secureManagerInstances &= newSecio(rng, seckey).Secure
let pubSub = if gossip: let pubSub = if gossip:
newPubSub(GossipSub, newPubSub(GossipSub,

View File

@ -645,15 +645,19 @@ proc newSwitch*(peerInfo: PeerInfo,
muxers: Table[string, MuxerProvider], muxers: Table[string, MuxerProvider],
secureManagers: openarray[Secure] = [], secureManagers: openarray[Secure] = [],
pubSub: Option[PubSub] = none(PubSub)): Switch = pubSub: Option[PubSub] = none(PubSub)): Switch =
new result if secureManagers.len == 0:
result.peerInfo = peerInfo raise (ref CatchableError)(msg: "Provide at least one secure manager")
result.ms = newMultistream()
result.transports = transports result = Switch(
result.connections = initTable[string, seq[ConnectionHolder]]() peerInfo: peerInfo,
result.muxed = initTable[string, seq[MuxerHolder]]() ms: newMultistream(),
result.identity = identity transports: transports,
result.muxers = muxers connections: initTable[string, seq[ConnectionHolder]](),
result.secureManagers = @secureManagers muxed: initTable[string, seq[MuxerHolder]](),
identity: identity,
muxers: muxers,
secureManagers: @secureManagers,
)
let s = result # can't capture result let s = result # can't capture result
result.streamHandler = proc(stream: Connection) {.async, gcsafe.} = result.streamHandler = proc(stream: Connection) {.async, gcsafe.} =
@ -674,11 +678,6 @@ proc newSwitch*(peerInfo: PeerInfo,
val.muxerHandler = proc(muxer: Muxer): Future[void] = val.muxerHandler = proc(muxer: Muxer): Future[void] =
s.muxerHandler(muxer) s.muxerHandler(muxer)
if result.secureManagers.len <= 0:
# use plain text if no secure managers are provided
warn "no secure managers, falling back to plain text", codec = PlainTextCodec
result.secureManagers &= Secure(newPlainText())
if pubSub.isSome: if pubSub.isSome:
result.pubSub = pubSub result.pubSub = pubSub
result.mount(pubSub.get()) result.mount(pubSub.get())

View File

@ -1,7 +1,8 @@
import chronos import chronos, bearssl
import ../libp2p/transports/tcptransport import ../libp2p/transports/tcptransport
import ../libp2p/stream/bufferstream import ../libp2p/stream/bufferstream
import ../libp2p/crypto/crypto
import ../libp2p/stream/lpstream import ../libp2p/stream/lpstream
const const
@ -23,3 +24,20 @@ iterator testTrackers*(extras: openArray[string] = []): TrackerBase =
for name in extras: for name in extras:
let t = getTracker(name) let t = getTracker(name)
if not isNil(t): yield t if not isNil(t): yield t
type RngWrap = object
rng: ref BrHmacDrbgContext
var rngVar: RngWrap
proc getRng(): ref BrHmacDrbgContext =
# TODO if `rngVar` is a threadvar like it should be, there are random and
# spurious compile failures on mac - this is not gcsafe but for the
# purpose of the tests, it's ok as long as we only use a single thread
{.gcsafe.}:
if rngVar.rng.isNil:
rngVar.rng = newRng()
rngVar.rng
template rng*(): ref BrHmacDrbgContext =
getRng()

View File

@ -15,7 +15,6 @@ import utils,
../../libp2p/[errors, ../../libp2p/[errors,
switch, switch,
stream/connection, stream/connection,
stream/bufferstream,
crypto/crypto, crypto/crypto,
protocols/pubsub/pubsub, protocols/pubsub/pubsub,
protocols/pubsub/floodsub, protocols/pubsub/floodsub,

View File

@ -2,7 +2,7 @@ include ../../libp2p/protocols/pubsub/gossipsub
{.used.} {.used.}
import unittest import unittest, bearssl
import stew/byteutils import stew/byteutils
import ../../libp2p/errors import ../../libp2p/errors
import ../../libp2p/crypto/crypto import ../../libp2p/crypto/crypto
@ -15,6 +15,9 @@ type
proc noop(data: seq[byte]) {.async, gcsafe.} = discard proc noop(data: seq[byte]) {.async, gcsafe.} = discard
proc randomPeerInfo(): PeerInfo =
PeerInfo.init(PrivateKey.random(ECDSA, rng[]).get())
suite "GossipSub internal": suite "GossipSub internal":
teardown: teardown:
for tracker in testTrackers(): for tracker in testTrackers():
@ -23,8 +26,7 @@ suite "GossipSub internal":
test "`rebalanceMesh` Degree Lo": test "`rebalanceMesh` Degree Lo":
proc testRun(): Future[bool] {.async.} = proc testRun(): Future[bool] {.async.} =
let gossipSub = newPubSub(TestGossipSub, let gossipSub = newPubSub(TestGossipSub, randomPeerInfo())
PeerInfo.init(PrivateKey.random(ECDSA).get()))
let topic = "foobar" let topic = "foobar"
gossipSub.mesh[topic] = initHashSet[string]() gossipSub.mesh[topic] = initHashSet[string]()
@ -33,7 +35,7 @@ suite "GossipSub internal":
for i in 0..<15: for i in 0..<15:
let conn = newBufferStream(noop) let conn = newBufferStream(noop)
conns &= conn conns &= conn
let peerInfo = PeerInfo.init(PrivateKey.random(ECDSA).get()) let peerInfo = randomPeerInfo()
conn.peerInfo = peerInfo conn.peerInfo = peerInfo
gossipSub.peers[peerInfo.id] = newPubSubPeer(peerInfo, GossipSubCodec) gossipSub.peers[peerInfo.id] = newPubSubPeer(peerInfo, GossipSubCodec)
gossipSub.peers[peerInfo.id].conn = conn gossipSub.peers[peerInfo.id].conn = conn
@ -52,8 +54,7 @@ suite "GossipSub internal":
test "`rebalanceMesh` Degree Hi": test "`rebalanceMesh` Degree Hi":
proc testRun(): Future[bool] {.async.} = proc testRun(): Future[bool] {.async.} =
let gossipSub = newPubSub(TestGossipSub, let gossipSub = newPubSub(TestGossipSub, randomPeerInfo())
PeerInfo.init(PrivateKey.random(ECDSA).get()))
let topic = "foobar" let topic = "foobar"
gossipSub.gossipsub[topic] = initHashSet[string]() gossipSub.gossipsub[topic] = initHashSet[string]()
@ -62,7 +63,7 @@ suite "GossipSub internal":
for i in 0..<15: for i in 0..<15:
let conn = newBufferStream(noop) let conn = newBufferStream(noop)
conns &= conn conns &= conn
let peerInfo = PeerInfo.init(PrivateKey.random(ECDSA).get()) let peerInfo = PeerInfo.init(PrivateKey.random(ECDSA, rng[]).get())
conn.peerInfo = peerInfo conn.peerInfo = peerInfo
gossipSub.peers[peerInfo.id] = newPubSubPeer(peerInfo, GossipSubCodec) gossipSub.peers[peerInfo.id] = newPubSubPeer(peerInfo, GossipSubCodec)
gossipSub.peers[peerInfo.id].conn = conn gossipSub.peers[peerInfo.id].conn = conn
@ -81,8 +82,7 @@ suite "GossipSub internal":
test "`replenishFanout` Degree Lo": test "`replenishFanout` Degree Lo":
proc testRun(): Future[bool] {.async.} = proc testRun(): Future[bool] {.async.} =
let gossipSub = newPubSub(TestGossipSub, let gossipSub = newPubSub(TestGossipSub, randomPeerInfo())
PeerInfo.init(PrivateKey.random(ECDSA).get()))
proc handler(peer: PubSubPeer, msg: seq[RPCMsg]) {.async.} = proc handler(peer: PubSubPeer, msg: seq[RPCMsg]) {.async.} =
discard discard
@ -94,7 +94,7 @@ suite "GossipSub internal":
for i in 0..<15: for i in 0..<15:
let conn = newBufferStream(noop) let conn = newBufferStream(noop)
conns &= conn conns &= conn
var peerInfo = PeerInfo.init(PrivateKey.random(ECDSA).get()) var peerInfo = randomPeerInfo()
conn.peerInfo = peerInfo conn.peerInfo = peerInfo
gossipSub.peers[peerInfo.id] = newPubSubPeer(peerInfo, GossipSubCodec) gossipSub.peers[peerInfo.id] = newPubSubPeer(peerInfo, GossipSubCodec)
gossipSub.peers[peerInfo.id].handler = handler gossipSub.peers[peerInfo.id].handler = handler
@ -113,8 +113,7 @@ suite "GossipSub internal":
test "`dropFanoutPeers` drop expired fanout topics": test "`dropFanoutPeers` drop expired fanout topics":
proc testRun(): Future[bool] {.async.} = proc testRun(): Future[bool] {.async.} =
let gossipSub = newPubSub(TestGossipSub, let gossipSub = newPubSub(TestGossipSub, randomPeerInfo())
PeerInfo.init(PrivateKey.random(ECDSA).get()))
proc handler(peer: PubSubPeer, msg: seq[RPCMsg]) {.async.} = proc handler(peer: PubSubPeer, msg: seq[RPCMsg]) {.async.} =
discard discard
@ -128,7 +127,7 @@ suite "GossipSub internal":
for i in 0..<6: for i in 0..<6:
let conn = newBufferStream(noop) let conn = newBufferStream(noop)
conns &= conn conns &= conn
let peerInfo = PeerInfo.init(PrivateKey.random(ECDSA).get()) let peerInfo = PeerInfo.init(PrivateKey.random(ECDSA, rng[]).get())
conn.peerInfo = peerInfo conn.peerInfo = peerInfo
gossipSub.peers[peerInfo.id] = newPubSubPeer(peerInfo, GossipSubCodec) gossipSub.peers[peerInfo.id] = newPubSubPeer(peerInfo, GossipSubCodec)
gossipSub.peers[peerInfo.id].handler = handler gossipSub.peers[peerInfo.id].handler = handler
@ -148,8 +147,7 @@ suite "GossipSub internal":
test "`dropFanoutPeers` leave unexpired fanout topics": test "`dropFanoutPeers` leave unexpired fanout topics":
proc testRun(): Future[bool] {.async.} = proc testRun(): Future[bool] {.async.} =
let gossipSub = newPubSub(TestGossipSub, let gossipSub = newPubSub(TestGossipSub, randomPeerInfo())
PeerInfo.init(PrivateKey.random(ECDSA).get()))
proc handler(peer: PubSubPeer, msg: seq[RPCMsg]) {.async.} = proc handler(peer: PubSubPeer, msg: seq[RPCMsg]) {.async.} =
discard discard
@ -166,7 +164,7 @@ suite "GossipSub internal":
for i in 0..<6: for i in 0..<6:
let conn = newBufferStream(noop) let conn = newBufferStream(noop)
conns &= conn conns &= conn
let peerInfo = PeerInfo.init(PrivateKey.random(ECDSA).get()) let peerInfo = randomPeerInfo()
conn.peerInfo = peerInfo conn.peerInfo = peerInfo
gossipSub.peers[peerInfo.id] = newPubSubPeer(peerInfo, GossipSubCodec) gossipSub.peers[peerInfo.id] = newPubSubPeer(peerInfo, GossipSubCodec)
gossipSub.peers[peerInfo.id].handler = handler gossipSub.peers[peerInfo.id].handler = handler
@ -189,8 +187,7 @@ suite "GossipSub internal":
test "`getGossipPeers` - should gather up to degree D non intersecting peers": test "`getGossipPeers` - should gather up to degree D non intersecting peers":
proc testRun(): Future[bool] {.async.} = proc testRun(): Future[bool] {.async.} =
let gossipSub = newPubSub(TestGossipSub, let gossipSub = newPubSub(TestGossipSub, randomPeerInfo())
PeerInfo.init(PrivateKey.random(ECDSA).get()))
proc handler(peer: PubSubPeer, msg: seq[RPCMsg]) {.async.} = proc handler(peer: PubSubPeer, msg: seq[RPCMsg]) {.async.} =
discard discard
@ -205,7 +202,7 @@ suite "GossipSub internal":
for i in 0..<30: for i in 0..<30:
let conn = newBufferStream(noop) let conn = newBufferStream(noop)
conns &= conn conns &= conn
let peerInfo = PeerInfo.init(PrivateKey.random(ECDSA).get()) let peerInfo = randomPeerInfo()
conn.peerInfo = peerInfo conn.peerInfo = peerInfo
gossipSub.peers[peerInfo.id] = newPubSubPeer(peerInfo, GossipSubCodec) gossipSub.peers[peerInfo.id] = newPubSubPeer(peerInfo, GossipSubCodec)
gossipSub.peers[peerInfo.id].handler = handler gossipSub.peers[peerInfo.id].handler = handler
@ -218,7 +215,7 @@ suite "GossipSub internal":
for i in 0..<15: for i in 0..<15:
let conn = newBufferStream(noop) let conn = newBufferStream(noop)
conns &= conn conns &= conn
let peerInfo = PeerInfo.init(PrivateKey.random(ECDSA).get()) let peerInfo = randomPeerInfo()
conn.peerInfo = peerInfo conn.peerInfo = peerInfo
gossipSub.peers[peerInfo.id] = newPubSubPeer(peerInfo, GossipSubCodec) gossipSub.peers[peerInfo.id] = newPubSubPeer(peerInfo, GossipSubCodec)
gossipSub.peers[peerInfo.id].handler = handler gossipSub.peers[peerInfo.id].handler = handler
@ -228,7 +225,7 @@ suite "GossipSub internal":
for i in 0..5: for i in 0..5:
let conn = newBufferStream(noop) let conn = newBufferStream(noop)
conns &= conn conns &= conn
let peerInfo = PeerInfo.init(PrivateKey.random(ECDSA).get()) let peerInfo = randomPeerInfo()
conn.peerInfo = peerInfo conn.peerInfo = peerInfo
let msg = Message.init(peerInfo, ("HELLO" & $i).toBytes(), topic, false) let msg = Message.init(peerInfo, ("HELLO" & $i).toBytes(), topic, false)
gossipSub.mcache.put(gossipSub.msgIdProvider(msg), msg) gossipSub.mcache.put(gossipSub.msgIdProvider(msg), msg)
@ -252,8 +249,7 @@ suite "GossipSub internal":
test "`getGossipPeers` - should not crash on missing topics in mesh": test "`getGossipPeers` - should not crash on missing topics in mesh":
proc testRun(): Future[bool] {.async.} = proc testRun(): Future[bool] {.async.} =
let gossipSub = newPubSub(TestGossipSub, let gossipSub = newPubSub(TestGossipSub, randomPeerInfo())
PeerInfo.init(PrivateKey.random(ECDSA).get()))
proc handler(peer: PubSubPeer, msg: seq[RPCMsg]) {.async.} = proc handler(peer: PubSubPeer, msg: seq[RPCMsg]) {.async.} =
discard discard
@ -265,7 +261,7 @@ suite "GossipSub internal":
for i in 0..<30: for i in 0..<30:
let conn = newBufferStream(noop) let conn = newBufferStream(noop)
conns &= conn conns &= conn
let peerInfo = PeerInfo.init(PrivateKey.random(ECDSA).get()) let peerInfo = randomPeerInfo()
conn.peerInfo = peerInfo conn.peerInfo = peerInfo
gossipSub.peers[peerInfo.id] = newPubSubPeer(peerInfo, GossipSubCodec) gossipSub.peers[peerInfo.id] = newPubSubPeer(peerInfo, GossipSubCodec)
gossipSub.peers[peerInfo.id].handler = handler gossipSub.peers[peerInfo.id].handler = handler
@ -278,7 +274,7 @@ suite "GossipSub internal":
for i in 0..5: for i in 0..5:
let conn = newBufferStream(noop) let conn = newBufferStream(noop)
conns &= conn conns &= conn
let peerInfo = PeerInfo.init(PrivateKey.random(ECDSA).get()) let peerInfo = randomPeerInfo()
conn.peerInfo = peerInfo conn.peerInfo = peerInfo
let msg = Message.init(peerInfo, ("HELLO" & $i).toBytes(), topic, false) let msg = Message.init(peerInfo, ("HELLO" & $i).toBytes(), topic, false)
gossipSub.mcache.put(gossipSub.msgIdProvider(msg), msg) gossipSub.mcache.put(gossipSub.msgIdProvider(msg), msg)
@ -295,8 +291,7 @@ suite "GossipSub internal":
test "`getGossipPeers` - should not crash on missing topics in fanout": test "`getGossipPeers` - should not crash on missing topics in fanout":
proc testRun(): Future[bool] {.async.} = proc testRun(): Future[bool] {.async.} =
let gossipSub = newPubSub(TestGossipSub, let gossipSub = newPubSub(TestGossipSub, randomPeerInfo())
PeerInfo.init(PrivateKey.random(ECDSA).get()))
proc handler(peer: PubSubPeer, msg: seq[RPCMsg]) {.async.} = proc handler(peer: PubSubPeer, msg: seq[RPCMsg]) {.async.} =
discard discard
@ -308,7 +303,7 @@ suite "GossipSub internal":
for i in 0..<30: for i in 0..<30:
let conn = newBufferStream(noop) let conn = newBufferStream(noop)
conns &= conn conns &= conn
let peerInfo = PeerInfo.init(PrivateKey.random(ECDSA).get()) let peerInfo = randomPeerInfo()
conn.peerInfo = peerInfo conn.peerInfo = peerInfo
gossipSub.peers[peerInfo.id] = newPubSubPeer(peerInfo, GossipSubCodec) gossipSub.peers[peerInfo.id] = newPubSubPeer(peerInfo, GossipSubCodec)
gossipSub.peers[peerInfo.id].handler = handler gossipSub.peers[peerInfo.id].handler = handler
@ -321,7 +316,7 @@ suite "GossipSub internal":
for i in 0..5: for i in 0..5:
let conn = newBufferStream(noop) let conn = newBufferStream(noop)
conns &= conn conns &= conn
let peerInfo = PeerInfo.init(PrivateKey.random(ECDSA).get()) let peerInfo = randomPeerInfo()
conn.peerInfo = peerInfo conn.peerInfo = peerInfo
let msg = Message.init(peerInfo, ("HELLO" & $i).toBytes(), topic, false) let msg = Message.init(peerInfo, ("HELLO" & $i).toBytes(), topic, false)
gossipSub.mcache.put(gossipSub.msgIdProvider(msg), msg) gossipSub.mcache.put(gossipSub.msgIdProvider(msg), msg)
@ -338,8 +333,7 @@ suite "GossipSub internal":
test "`getGossipPeers` - should not crash on missing topics in gossip": test "`getGossipPeers` - should not crash on missing topics in gossip":
proc testRun(): Future[bool] {.async.} = proc testRun(): Future[bool] {.async.} =
let gossipSub = newPubSub(TestGossipSub, let gossipSub = newPubSub(TestGossipSub, randomPeerInfo())
PeerInfo.init(PrivateKey.random(ECDSA).get()))
proc handler(peer: PubSubPeer, msg: seq[RPCMsg]) {.async.} = proc handler(peer: PubSubPeer, msg: seq[RPCMsg]) {.async.} =
discard discard
@ -351,7 +345,7 @@ suite "GossipSub internal":
for i in 0..<30: for i in 0..<30:
let conn = newBufferStream(noop) let conn = newBufferStream(noop)
conns &= conn conns &= conn
let peerInfo = PeerInfo.init(PrivateKey.random(ECDSA).get()) let peerInfo = randomPeerInfo()
conn.peerInfo = peerInfo conn.peerInfo = peerInfo
gossipSub.peers[peerInfo.id] = newPubSubPeer(peerInfo, GossipSubCodec) gossipSub.peers[peerInfo.id] = newPubSubPeer(peerInfo, GossipSubCodec)
gossipSub.peers[peerInfo.id].handler = handler gossipSub.peers[peerInfo.id].handler = handler
@ -364,7 +358,7 @@ suite "GossipSub internal":
for i in 0..5: for i in 0..5:
let conn = newBufferStream(noop) let conn = newBufferStream(noop)
conns &= conn conns &= conn
let peerInfo = PeerInfo.init(PrivateKey.random(ECDSA).get()) let peerInfo = randomPeerInfo()
conn.peerInfo = peerInfo conn.peerInfo = peerInfo
let msg = Message.init(peerInfo, ("bar" & $i).toBytes(), topic, false) let msg = Message.init(peerInfo, ("bar" & $i).toBytes(), topic, false)
gossipSub.mcache.put(gossipSub.msgIdProvider(msg), msg) gossipSub.mcache.put(gossipSub.msgIdProvider(msg), msg)

View File

@ -17,7 +17,6 @@ import utils, ../../libp2p/[errors,
peerinfo, peerinfo,
stream/connection, stream/connection,
crypto/crypto, crypto/crypto,
stream/bufferstream,
protocols/pubsub/pubsub, protocols/pubsub/pubsub,
protocols/pubsub/gossipsub, protocols/pubsub/gossipsub,
protocols/pubsub/rpc/messages] protocols/pubsub/rpc/messages]

View File

@ -1,6 +1,6 @@
{.used.} {.used.}
import unittest, options, sets, sequtils import unittest, options, sets, sequtils, bearssl
import stew/byteutils import stew/byteutils
import ../../libp2p/[peerid, import ../../libp2p/[peerid,
crypto/crypto, crypto/crypto,
@ -8,11 +8,15 @@ import ../../libp2p/[peerid,
protocols/pubsub/rpc/message, protocols/pubsub/rpc/message,
protocols/pubsub/rpc/messages] protocols/pubsub/rpc/messages]
var rng = newRng()
proc randomPeerID(): PeerID =
PeerID.init(PrivateKey.random(ECDSA, rng[]).get()).get()
suite "MCache": suite "MCache":
test "put/get": test "put/get":
var mCache = newMCache(3, 5) var mCache = newMCache(3, 5)
var msg = Message(fromPeer: PeerID.init(PrivateKey.random(ECDSA).get()).get(), var msg = Message(fromPeer: randomPeerID(), seqno: "12345".toBytes())
seqno: "12345".toBytes())
let msgId = defaultMsgIdProvider(msg) let msgId = defaultMsgIdProvider(msg)
mCache.put(msgId, msg) mCache.put(msgId, msg)
check mCache.get(msgId).isSome and mCache.get(msgId).get() == msg check mCache.get(msgId).isSome and mCache.get(msgId).get() == msg
@ -21,13 +25,13 @@ suite "MCache":
var mCache = newMCache(3, 5) var mCache = newMCache(3, 5)
for i in 0..<3: for i in 0..<3:
var msg = Message(fromPeer: PeerID.init(PrivateKey.random(ECDSA).get()).get(), var msg = Message(fromPeer: randomPeerID(),
seqno: "12345".toBytes(), seqno: "12345".toBytes(),
topicIDs: @["foo"]) topicIDs: @["foo"])
mCache.put(defaultMsgIdProvider(msg), msg) mCache.put(defaultMsgIdProvider(msg), msg)
for i in 0..<5: for i in 0..<5:
var msg = Message(fromPeer: PeerID.init(PrivateKey.random(ECDSA).get()).get(), var msg = Message(fromPeer: randomPeerID(),
seqno: "12345".toBytes(), seqno: "12345".toBytes(),
topicIDs: @["bar"]) topicIDs: @["bar"])
mCache.put(defaultMsgIdProvider(msg), msg) mCache.put(defaultMsgIdProvider(msg), msg)
@ -42,7 +46,7 @@ suite "MCache":
var mCache = newMCache(1, 5) var mCache = newMCache(1, 5)
for i in 0..<3: for i in 0..<3:
var msg = Message(fromPeer: PeerID.init(PrivateKey.random(ECDSA).get()).get(), var msg = Message(fromPeer: randomPeerID(),
seqno: "12345".toBytes(), seqno: "12345".toBytes(),
topicIDs: @["foo"]) topicIDs: @["foo"])
mCache.put(defaultMsgIdProvider(msg), msg) mCache.put(defaultMsgIdProvider(msg), msg)
@ -51,7 +55,7 @@ suite "MCache":
check mCache.window("foo").len == 0 check mCache.window("foo").len == 0
for i in 0..<3: for i in 0..<3:
var msg = Message(fromPeer: PeerID.init(PrivateKey.random(ECDSA).get()).get(), var msg = Message(fromPeer: randomPeerID(),
seqno: "12345".toBytes(), seqno: "12345".toBytes(),
topicIDs: @["bar"]) topicIDs: @["bar"])
mCache.put(defaultMsgIdProvider(msg), msg) mCache.put(defaultMsgIdProvider(msg), msg)
@ -60,7 +64,7 @@ suite "MCache":
check mCache.window("bar").len == 0 check mCache.window("bar").len == 0
for i in 0..<3: for i in 0..<3:
var msg = Message(fromPeer: PeerID.init(PrivateKey.random(ECDSA).get()).get(), var msg = Message(fromPeer: randomPeerID(),
seqno: "12345".toBytes(), seqno: "12345".toBytes(),
topicIDs: @["baz"]) topicIDs: @["baz"])
mCache.put(defaultMsgIdProvider(msg), msg) mCache.put(defaultMsgIdProvider(msg), msg)
@ -72,19 +76,19 @@ suite "MCache":
var mCache = newMCache(1, 5) var mCache = newMCache(1, 5)
for i in 0..<3: for i in 0..<3:
var msg = Message(fromPeer: PeerID.init(PrivateKey.random(ECDSA).get()).get(), var msg = Message(fromPeer: randomPeerID(),
seqno: "12345".toBytes(), seqno: "12345".toBytes(),
topicIDs: @["foo"]) topicIDs: @["foo"])
mCache.put(defaultMsgIdProvider(msg), msg) mCache.put(defaultMsgIdProvider(msg), msg)
for i in 0..<3: for i in 0..<3:
var msg = Message(fromPeer: PeerID.init(PrivateKey.random(ECDSA).get()).get(), var msg = Message(fromPeer: randomPeerID(),
seqno: "12345".toBytes(), seqno: "12345".toBytes(),
topicIDs: @["bar"]) topicIDs: @["bar"])
mCache.put(defaultMsgIdProvider(msg), msg) mCache.put(defaultMsgIdProvider(msg), msg)
for i in 0..<3: for i in 0..<3:
var msg = Message(fromPeer: PeerID.init(PrivateKey.random(ECDSA).get()).get(), var msg = Message(fromPeer: randomPeerID(),
seqno: "12345".toBytes(), seqno: "12345".toBytes(),
topicIDs: @["baz"]) topicIDs: @["baz"])
mCache.put(defaultMsgIdProvider(msg), msg) mCache.put(defaultMsgIdProvider(msg), msg)

View File

@ -1,14 +1,18 @@
import unittest import unittest
{.used.}
import ../../libp2p/[peerid, peerinfo, import ../../libp2p/[peerid, peerinfo,
crypto/crypto, crypto/crypto,
protocols/pubsub/rpc/message, protocols/pubsub/rpc/message,
protocols/pubsub/rpc/messages] protocols/pubsub/rpc/messages]
let rng = newRng()
suite "Message": suite "Message":
test "signature": test "signature":
let let
peer = PeerInfo.init(PrivateKey.random(ECDSA).get()) peer = PeerInfo.init(PrivateKey.random(ECDSA, rng[]).get())
msg = Message.init(peer, @[], "topic", sign = true) msg = Message.init(peer, @[], "topic", sign = true)
check verify(msg, peer) check verify(msg, peer)

View File

@ -374,6 +374,8 @@ proc testStretcher(s, e: int, cs: string, ds: string): bool =
if not result: if not result:
break break
let rng = newRng()
suite "Key interface test suite": suite "Key interface test suite":
test "Go test vectors": test "Go test vectors":
@ -394,9 +396,9 @@ suite "Key interface test suite":
var bmsg = cast[seq[byte]](msg) var bmsg = cast[seq[byte]](msg)
for i in 0..<5: for i in 0..<5:
var seckey = PrivateKey.random(ECDSA).get() var seckey = PrivateKey.random(ECDSA, rng[]).get()
var pubkey = seckey.getKey().get() var pubkey = seckey.getKey().get()
var pair = KeyPair.random(ECDSA).get() var pair = KeyPair.random(ECDSA, rng[]).get()
var sig1 = pair.seckey.sign(bmsg).get() var sig1 = pair.seckey.sign(bmsg).get()
var sig2 = seckey.sign(bmsg).get() var sig2 = seckey.sign(bmsg).get()
var sersig1 = sig1.getBytes() var sersig1 = sig1.getBytes()
@ -414,9 +416,9 @@ suite "Key interface test suite":
recsig2.verify(bmsg, recpub2) == true recsig2.verify(bmsg, recpub2) == true
for i in 0..<5: for i in 0..<5:
var seckey = PrivateKey.random(Ed25519).get() var seckey = PrivateKey.random(Ed25519, rng[]).get()
var pubkey = seckey.getKey().get() var pubkey = seckey.getKey().get()
var pair = KeyPair.random(Ed25519).get() var pair = KeyPair.random(Ed25519, rng[]).get()
var sig1 = pair.seckey.sign(bmsg).get() var sig1 = pair.seckey.sign(bmsg).get()
var sig2 = seckey.sign(bmsg).get() var sig2 = seckey.sign(bmsg).get()
var sersig1 = sig1.getBytes() var sersig1 = sig1.getBytes()
@ -434,9 +436,9 @@ suite "Key interface test suite":
recsig2.verify(bmsg, recpub2) == true recsig2.verify(bmsg, recpub2) == true
for i in 0..<5: for i in 0..<5:
var seckey = PrivateKey.random(RSA, 512).get() var seckey = PrivateKey.random(RSA, rng[], 512).get()
var pubkey = seckey.getKey().get() var pubkey = seckey.getKey().get()
var pair = KeyPair.random(RSA, 512).get() var pair = KeyPair.random(RSA, rng[], 512).get()
var sig1 = pair.seckey.sign(bmsg).get() var sig1 = pair.seckey.sign(bmsg).get()
var sig2 = seckey.sign(bmsg).get() var sig2 = seckey.sign(bmsg).get()
var sersig1 = sig1.getBytes() var sersig1 = sig1.getBytes()

View File

@ -8,7 +8,7 @@
## those terms. ## those terms.
import unittest import unittest
import nimcrypto/utils import nimcrypto/utils
import ../libp2p/crypto/ecnist import ../libp2p/crypto/[crypto, ecnist]
import stew/results import stew/results
when defined(nimHasUsed): {.used.} when defined(nimHasUsed): {.used.}
@ -294,13 +294,14 @@ const
35ab""" 35ab"""
] ]
suite "EC NIST-P256/384/521 test suite": let rng = newRng()
suite "EC NIST-P256/384/521 test suite":
test "[secp256r1] Private key serialize/deserialize test": test "[secp256r1] Private key serialize/deserialize test":
for i in 0..<TestsCount: for i in 0..<TestsCount:
var rkey1, rkey2: EcPrivateKey var rkey1, rkey2: EcPrivateKey
var skey2 = newSeq[byte](256) var skey2 = newSeq[byte](256)
var key = EcPrivateKey.random(Secp256r1).expect("random key") var key = EcPrivateKey.random(Secp256r1, rng[]).expect("random key")
var skey1 = key.getBytes().expect("bytes") var skey1 = key.getBytes().expect("bytes")
check: check:
key.toBytes(skey2).expect("bytes") > 0 key.toBytes(skey2).expect("bytes") > 0
@ -319,7 +320,7 @@ suite "EC NIST-P256/384/521 test suite":
for i in 0..<TestsCount: for i in 0..<TestsCount:
var rkey1, rkey2: EcPublicKey var rkey1, rkey2: EcPublicKey
var skey2 = newSeq[byte](256) var skey2 = newSeq[byte](256)
var pair = EcKeyPair.random(Secp256r1).expect("random key") var pair = EcKeyPair.random(Secp256r1, rng[]).expect("random key")
var skey1 = pair.pubkey.getBytes().expect("bytes") var skey1 = pair.pubkey.getBytes().expect("bytes")
check: check:
pair.pubkey.toBytes(skey2).expect("bytes") > 0 pair.pubkey.toBytes(skey2).expect("bytes") > 0
@ -335,8 +336,8 @@ suite "EC NIST-P256/384/521 test suite":
test "[secp256r1] ECDHE test": test "[secp256r1] ECDHE test":
for i in 0..<TestsCount: for i in 0..<TestsCount:
var kp1 = EcKeyPair.random(Secp256r1).expect("random key") var kp1 = EcKeyPair.random(Secp256r1, rng[]).expect("random key")
var kp2 = EcKeyPair.random(Secp256r1).expect("random key") var kp2 = EcKeyPair.random(Secp256r1, rng[]).expect("random key")
var shared1 = kp2.pubkey.scalarMul(kp1.seckey) var shared1 = kp2.pubkey.scalarMul(kp1.seckey)
var shared2 = kp1.pubkey.scalarMul(kp2.seckey) var shared2 = kp1.pubkey.scalarMul(kp2.seckey)
check: check:
@ -390,7 +391,7 @@ suite "EC NIST-P256/384/521 test suite":
test "[secp256r1] Generate/Sign/Serialize/Deserialize/Verify test": test "[secp256r1] Generate/Sign/Serialize/Deserialize/Verify test":
var message = "message to sign" var message = "message to sign"
for i in 0..<TestsCount: for i in 0..<TestsCount:
var kp = EcKeyPair.random(Secp256r1).expect("random key") var kp = EcKeyPair.random(Secp256r1, rng[]).expect("random key")
var sig = kp.seckey.sign(message).expect("signature") var sig = kp.seckey.sign(message).expect("signature")
var sersk = kp.seckey.getBytes().expect("bytes") var sersk = kp.seckey.getBytes().expect("bytes")
var serpk = kp.pubkey.getBytes().expect("bytes") var serpk = kp.pubkey.getBytes().expect("bytes")
@ -407,7 +408,7 @@ suite "EC NIST-P256/384/521 test suite":
for i in 0..<TestsCount: for i in 0..<TestsCount:
var rkey1, rkey2: EcPrivateKey var rkey1, rkey2: EcPrivateKey
var skey2 = newSeq[byte](256) var skey2 = newSeq[byte](256)
var key = EcPrivateKey.random(Secp384r1).expect("random key") var key = EcPrivateKey.random(Secp384r1, rng[]).expect("random key")
var skey1 = key.getBytes().expect("bytes") var skey1 = key.getBytes().expect("bytes")
check: check:
key.toBytes(skey2).expect("bytes") > 0 key.toBytes(skey2).expect("bytes") > 0
@ -426,7 +427,7 @@ suite "EC NIST-P256/384/521 test suite":
for i in 0..<TestsCount: for i in 0..<TestsCount:
var rkey1, rkey2: EcPublicKey var rkey1, rkey2: EcPublicKey
var skey2 = newSeq[byte](256) var skey2 = newSeq[byte](256)
var pair = EcKeyPair.random(Secp384r1).expect("random key") var pair = EcKeyPair.random(Secp384r1, rng[]).expect("random key")
var skey1 = pair.pubkey.getBytes().expect("bytes") var skey1 = pair.pubkey.getBytes().expect("bytes")
check: check:
pair.pubkey.toBytes(skey2).expect("bytes") > 0 pair.pubkey.toBytes(skey2).expect("bytes") > 0
@ -442,8 +443,8 @@ suite "EC NIST-P256/384/521 test suite":
test "[secp384r1] ECDHE test": test "[secp384r1] ECDHE test":
for i in 0..<TestsCount: for i in 0..<TestsCount:
var kp1 = EcKeyPair.random(Secp384r1).expect("random key") var kp1 = EcKeyPair.random(Secp384r1, rng[]).expect("random key")
var kp2 = EcKeyPair.random(Secp384r1).expect("random key") var kp2 = EcKeyPair.random(Secp384r1, rng[]).expect("random key")
var shared1 = kp2.pubkey.scalarMul(kp1.seckey) var shared1 = kp2.pubkey.scalarMul(kp1.seckey)
var shared2 = kp1.pubkey.scalarMul(kp2.seckey) var shared2 = kp1.pubkey.scalarMul(kp2.seckey)
check: check:
@ -497,7 +498,7 @@ suite "EC NIST-P256/384/521 test suite":
test "[secp384r1] Generate/Sign/Serialize/Deserialize/Verify test": test "[secp384r1] Generate/Sign/Serialize/Deserialize/Verify test":
var message = "message to sign" var message = "message to sign"
for i in 0..<TestsCount: for i in 0..<TestsCount:
var kp = EcKeyPair.random(Secp384r1).expect("random key") var kp = EcKeyPair.random(Secp384r1, rng[]).expect("random key")
var sig = kp.seckey.sign(message).expect("signature") var sig = kp.seckey.sign(message).expect("signature")
var sersk = kp.seckey.getBytes().expect("bytes") var sersk = kp.seckey.getBytes().expect("bytes")
var serpk = kp.pubkey.getBytes().expect("bytes") var serpk = kp.pubkey.getBytes().expect("bytes")
@ -514,7 +515,7 @@ suite "EC NIST-P256/384/521 test suite":
for i in 0..<TestsCount: for i in 0..<TestsCount:
var rkey1, rkey2: EcPrivateKey var rkey1, rkey2: EcPrivateKey
var skey2 = newSeq[byte](256) var skey2 = newSeq[byte](256)
var key = EcPrivateKey.random(Secp521r1).expect("random key") var key = EcPrivateKey.random(Secp521r1, rng[]).expect("random key")
var skey1 = key.getBytes().expect("bytes") var skey1 = key.getBytes().expect("bytes")
check: check:
key.toBytes(skey2).expect("bytes") > 0 key.toBytes(skey2).expect("bytes") > 0
@ -533,7 +534,7 @@ suite "EC NIST-P256/384/521 test suite":
for i in 0..<TestsCount: for i in 0..<TestsCount:
var rkey1, rkey2: EcPublicKey var rkey1, rkey2: EcPublicKey
var skey2 = newSeq[byte](256) var skey2 = newSeq[byte](256)
var pair = EcKeyPair.random(Secp521r1).expect("random key") var pair = EcKeyPair.random(Secp521r1, rng[]).expect("random key")
var skey1 = pair.pubkey.getBytes().expect("bytes") var skey1 = pair.pubkey.getBytes().expect("bytes")
check: check:
pair.pubkey.toBytes(skey2).expect("bytes") > 0 pair.pubkey.toBytes(skey2).expect("bytes") > 0
@ -549,8 +550,8 @@ suite "EC NIST-P256/384/521 test suite":
test "[secp521r1] ECDHE test": test "[secp521r1] ECDHE test":
for i in 0..<TestsCount: for i in 0..<TestsCount:
var kp1 = EcKeyPair.random(Secp521r1).expect("random key") var kp1 = EcKeyPair.random(Secp521r1, rng[]).expect("random key")
var kp2 = EcKeyPair.random(Secp521r1).expect("random key") var kp2 = EcKeyPair.random(Secp521r1, rng[]).expect("random key")
var shared1 = kp2.pubkey.scalarMul(kp1.seckey) var shared1 = kp2.pubkey.scalarMul(kp1.seckey)
var shared2 = kp1.pubkey.scalarMul(kp2.seckey) var shared2 = kp1.pubkey.scalarMul(kp2.seckey)
check: check:
@ -604,7 +605,7 @@ suite "EC NIST-P256/384/521 test suite":
test "[secp521r1] Generate/Sign/Serialize/Deserialize/Verify test": test "[secp521r1] Generate/Sign/Serialize/Deserialize/Verify test":
var message = "message to sign" var message = "message to sign"
for i in 0..<TestsCount: for i in 0..<TestsCount:
var kp = EcKeyPair.random(Secp521r1).expect("random key") var kp = EcKeyPair.random(Secp521r1, rng[]).expect("random key")
var sig = kp.seckey.sign(message).expect("signature") var sig = kp.seckey.sign(message).expect("signature")
var sersk = kp.seckey.getBytes().expect("bytes") var sersk = kp.seckey.getBytes().expect("bytes")
var serpk = kp.pubkey.getBytes().expect("bytes") var serpk = kp.pubkey.getBytes().expect("bytes")

View File

@ -10,6 +10,7 @@
## Test vectors are from RFC 8032 (https://tools.ietf.org/html/rfc8032) ## Test vectors are from RFC 8032 (https://tools.ietf.org/html/rfc8032)
import unittest import unittest
import nimcrypto/utils import nimcrypto/utils
import ../libp2p/crypto/crypto
import ../libp2p/crypto/ed25519/ed25519 import ../libp2p/crypto/ed25519/ed25519
when defined(nimHasUsed): {.used.} when defined(nimHasUsed): {.used.}
@ -100,6 +101,8 @@ const GoodScalars = [
"ECD3F55C1A631258D69CF7A2DEF9DE1400000000000000000000000000000010", "ECD3F55C1A631258D69CF7A2DEF9DE1400000000000000000000000000000010",
] ]
let rng = newRng()
suite "Ed25519 test suite": suite "Ed25519 test suite":
test "Scalar check edge cases test": test "Scalar check edge cases test":
for item in FailScalars: for item in FailScalars:
@ -111,7 +114,7 @@ suite "Ed25519 test suite":
for i in 0..<TestsCount: for i in 0..<TestsCount:
var rkey1, rkey2: EdPrivateKey var rkey1, rkey2: EdPrivateKey
var skey2 = newSeq[byte](256) var skey2 = newSeq[byte](256)
var key = EdPrivateKey.random().expect("private key") var key = EdPrivateKey.random(rng[])
var skey1 = key.getBytes() var skey1 = key.getBytes()
check: check:
key.toBytes(skey2) > 0 key.toBytes(skey2) > 0
@ -135,7 +138,7 @@ suite "Ed25519 test suite":
for i in 0..<TestsCount: for i in 0..<TestsCount:
var rkey1, rkey2: EdPublicKey var rkey1, rkey2: EdPublicKey
var skey2 = newSeq[byte](256) var skey2 = newSeq[byte](256)
var pair = EdKeyPair.random().expect("random key pair") var pair = EdKeyPair.random(rng[])
var skey1 = pair.pubkey.getBytes() var skey1 = pair.pubkey.getBytes()
check: check:
pair.pubkey.toBytes(skey2) > 0 pair.pubkey.toBytes(skey2) > 0
@ -171,7 +174,7 @@ suite "Ed25519 test suite":
test "Generate/Sign/Serialize/Deserialize/Verify test": test "Generate/Sign/Serialize/Deserialize/Verify test":
var message = "message to sign" var message = "message to sign"
for i in 0..<TestsCount: for i in 0..<TestsCount:
var kp = EdKeyPair.random().expect("random key pair") var kp = EdKeyPair.random(rng[])
var sig = kp.seckey.sign(message) var sig = kp.seckey.sign(message)
var sersk = kp.seckey.getBytes() var sersk = kp.seckey.getBytes()
var serpk = kp.pubkey.getBytes() var serpk = kp.pubkey.getBytes()

View File

@ -1,4 +1,4 @@
import unittest, options import unittest, options, bearssl
import chronos, strutils import chronos, strutils
import ../libp2p/[protocols/identify, import ../libp2p/[protocols/identify,
multiaddress, multiaddress,
@ -22,7 +22,7 @@ suite "Identify":
test "handle identify message": test "handle identify message":
proc testHandle(): Future[bool] {.async.} = proc testHandle(): Future[bool] {.async.} =
let ma: MultiAddress = Multiaddress.init("/ip4/0.0.0.0/tcp/0").tryGet() let ma: MultiAddress = Multiaddress.init("/ip4/0.0.0.0/tcp/0").tryGet()
let remoteSecKey = PrivateKey.random(ECDSA).get() let remoteSecKey = PrivateKey.random(ECDSA, rng[]).get()
let remotePeerInfo = PeerInfo.init(remoteSecKey, let remotePeerInfo = PeerInfo.init(remoteSecKey,
[ma], [ma],
["/test/proto1/1.0.0", ["/test/proto1/1.0.0",
@ -42,7 +42,7 @@ suite "Identify":
let transport2: TcpTransport = TcpTransport.init() let transport2: TcpTransport = TcpTransport.init()
let conn = await transport2.dial(transport1.ma) let conn = await transport2.dial(transport1.ma)
var peerInfo = PeerInfo.init(PrivateKey.random(ECDSA).get(), [ma]) var peerInfo = PeerInfo.init(PrivateKey.random(ECDSA, rng[]).get(), [ma])
let identifyProto2 = newIdentify(peerInfo) let identifyProto2 = newIdentify(peerInfo)
discard await msDial.select(conn, IdentifyCodec) discard await msDial.select(conn, IdentifyCodec)
let id = await identifyProto2.identify(conn, remotePeerInfo) let id = await identifyProto2.identify(conn, remotePeerInfo)
@ -66,8 +66,8 @@ suite "Identify":
test "handle failed identify": test "handle failed identify":
proc testHandleError() {.async.} = proc testHandleError() {.async.} =
let ma: MultiAddress = Multiaddress.init("/ip4/0.0.0.0/tcp/0").tryGet() let ma = Multiaddress.init("/ip4/0.0.0.0/tcp/0").tryGet()
var remotePeerInfo = PeerInfo.init(PrivateKey.random(ECDSA).get(), [ma]) var remotePeerInfo = PeerInfo.init(PrivateKey.random(ECDSA, rng[]).get(), [ma])
let identifyProto1 = newIdentify(remotePeerInfo) let identifyProto1 = newIdentify(remotePeerInfo)
let msListen = newMultistream() let msListen = newMultistream()
@ -85,13 +85,13 @@ suite "Identify":
let msDial = newMultistream() let msDial = newMultistream()
let transport2: TcpTransport = TcpTransport.init() let transport2: TcpTransport = TcpTransport.init()
let conn = await transport2.dial(transport1.ma) let conn = await transport2.dial(transport1.ma)
var localPeerInfo = PeerInfo.init(PrivateKey.random(ECDSA, rng[]).get(), [ma])
var localPeerInfo = PeerInfo.init(PrivateKey.random(ECDSA).get(), [ma])
let identifyProto2 = newIdentify(localPeerInfo) let identifyProto2 = newIdentify(localPeerInfo)
try: try:
let pi2 = PeerInfo.init(PrivateKey.random(ECDSA, rng[]).get())
discard await msDial.select(conn, IdentifyCodec) discard await msDial.select(conn, IdentifyCodec)
discard await identifyProto2.identify(conn, PeerInfo.init(PrivateKey.random(ECDSA).get())) discard await identifyProto2.identify(conn, pi2)
finally: finally:
await done.wait(5000.millis) # when no issues will not wait that long! await done.wait(5000.millis) # when no issues will not wait that long!
await conn.close() await conn.close()

View File

@ -9,10 +9,9 @@
{.used.} {.used.}
import unittest, tables import unittest, tables, bearssl
import chronos, stew/byteutils import chronos, stew/byteutils
import chronicles import chronicles
import nimcrypto/sysrand
import ../libp2p/crypto/crypto import ../libp2p/crypto/crypto
import ../libp2p/[switch, import ../libp2p/[switch,
errors, errors,
@ -50,7 +49,7 @@ method init(p: TestProto) {.gcsafe.} =
p.handler = handle p.handler = handle
proc createSwitch(ma: MultiAddress; outgoing: bool): (Switch, PeerInfo) = proc createSwitch(ma: MultiAddress; outgoing: bool): (Switch, PeerInfo) =
var peerInfo: PeerInfo = PeerInfo.init(PrivateKey.random(ECDSA).get()) var peerInfo: PeerInfo = PeerInfo.init(PrivateKey.random(ECDSA, rng[]).get())
peerInfo.addrs.add(ma) peerInfo.addrs.add(ma)
let identify = newIdentify(peerInfo) let identify = newIdentify(peerInfo)
@ -60,7 +59,7 @@ proc createSwitch(ma: MultiAddress; outgoing: bool): (Switch, PeerInfo) =
let mplexProvider = newMuxerProvider(createMplex, MplexCodec) let mplexProvider = newMuxerProvider(createMplex, MplexCodec)
let transports = @[Transport(TcpTransport.init())] let transports = @[Transport(TcpTransport.init())]
let muxers = [(MplexCodec, mplexProvider)].toTable() let muxers = [(MplexCodec, mplexProvider)].toTable()
let secureManagers = [Secure(newNoise(peerInfo.privateKey, outgoing = outgoing))] let secureManagers = [Secure(newNoise(rng, peerInfo.privateKey, outgoing = outgoing))]
let switch = newSwitch(peerInfo, let switch = newSwitch(peerInfo,
transports, transports,
identify, identify,
@ -77,9 +76,9 @@ suite "Noise":
test "e2e: handle write + noise": test "e2e: handle write + noise":
proc testListenerDialer(): Future[bool] {.async.} = proc testListenerDialer(): Future[bool] {.async.} =
let let
server: MultiAddress = Multiaddress.init("/ip4/0.0.0.0/tcp/0").tryGet() server = Multiaddress.init("/ip4/0.0.0.0/tcp/0").tryGet()
serverInfo = PeerInfo.init(PrivateKey.random(ECDSA).get(), [server]) serverInfo = PeerInfo.init(PrivateKey.random(ECDSA, rng[]).get(), [server])
serverNoise = newNoise(serverInfo.privateKey, outgoing = false) serverNoise = newNoise(rng, serverInfo.privateKey, outgoing = false)
proc connHandler(conn: Connection) {.async, gcsafe.} = proc connHandler(conn: Connection) {.async, gcsafe.} =
let sconn = await serverNoise.secure(conn, false) let sconn = await serverNoise.secure(conn, false)
@ -95,8 +94,8 @@ suite "Noise":
let let
transport2: TcpTransport = TcpTransport.init() transport2: TcpTransport = TcpTransport.init()
clientInfo = PeerInfo.init(PrivateKey.random(ECDSA).get(), [transport1.ma]) clientInfo = PeerInfo.init(PrivateKey.random(ECDSA, rng[]).get(), [transport1.ma])
clientNoise = newNoise(clientInfo.privateKey, outgoing = true) clientNoise = newNoise(rng, clientInfo.privateKey, outgoing = true)
conn = await transport2.dial(transport1.ma) conn = await transport2.dial(transport1.ma)
sconn = await clientNoise.secure(conn, true) sconn = await clientNoise.secure(conn, true)
@ -116,9 +115,9 @@ suite "Noise":
test "e2e: handle read + noise": test "e2e: handle read + noise":
proc testListenerDialer(): Future[bool] {.async.} = proc testListenerDialer(): Future[bool] {.async.} =
let let
server: MultiAddress = Multiaddress.init("/ip4/0.0.0.0/tcp/0").tryGet() server = Multiaddress.init("/ip4/0.0.0.0/tcp/0").tryGet()
serverInfo = PeerInfo.init(PrivateKey.random(ECDSA).get(), [server]) serverInfo = PeerInfo.init(PrivateKey.random(ECDSA, rng[]).get(), [server])
serverNoise = newNoise(serverInfo.privateKey, outgoing = false) serverNoise = newNoise(rng, serverInfo.privateKey, outgoing = false)
readTask = newFuture[void]() readTask = newFuture[void]()
proc connHandler(conn: Connection) {.async, gcsafe.} = proc connHandler(conn: Connection) {.async, gcsafe.} =
@ -137,8 +136,8 @@ suite "Noise":
let let
transport2: TcpTransport = TcpTransport.init() transport2: TcpTransport = TcpTransport.init()
clientInfo = PeerInfo.init(PrivateKey.random(ECDSA).get(), [transport1.ma]) clientInfo = PeerInfo.init(PrivateKey.random(ECDSA, rng[]).get(), [transport1.ma])
clientNoise = newNoise(clientInfo.privateKey, outgoing = true) clientNoise = newNoise(rng, clientInfo.privateKey, outgoing = true)
conn = await transport2.dial(transport1.ma) conn = await transport2.dial(transport1.ma)
sconn = await clientNoise.secure(conn, true) sconn = await clientNoise.secure(conn, true)
@ -157,13 +156,13 @@ suite "Noise":
test "e2e: handle read + noise fragmented": test "e2e: handle read + noise fragmented":
proc testListenerDialer(): Future[bool] {.async.} = proc testListenerDialer(): Future[bool] {.async.} =
let let
server: MultiAddress = Multiaddress.init("/ip4/0.0.0.0/tcp/0").tryGet() server = Multiaddress.init("/ip4/0.0.0.0/tcp/0").tryGet()
serverInfo = PeerInfo.init(PrivateKey.random(ECDSA).get(), [server]) serverInfo = PeerInfo.init(PrivateKey.random(ECDSA, rng[]).get(), [server])
serverNoise = newNoise(serverInfo.privateKey, outgoing = false) serverNoise = newNoise(rng, serverInfo.privateKey, outgoing = false)
readTask = newFuture[void]() readTask = newFuture[void]()
var hugePayload = newSeq[byte](0xFFFFF) var hugePayload = newSeq[byte](0xFFFFF)
check randomBytes(hugePayload) == hugePayload.len brHmacDrbgGenerate(rng[], hugePayload)
trace "Sending huge payload", size = hugePayload.len trace "Sending huge payload", size = hugePayload.len
proc connHandler(conn: Connection) {.async, gcsafe.} = proc connHandler(conn: Connection) {.async, gcsafe.} =
@ -180,8 +179,8 @@ suite "Noise":
let let
transport2: TcpTransport = TcpTransport.init() transport2: TcpTransport = TcpTransport.init()
clientInfo = PeerInfo.init(PrivateKey.random(ECDSA).get(), [transport1.ma]) clientInfo = PeerInfo.init(PrivateKey.random(ECDSA, rng[]).get(), [transport1.ma])
clientNoise = newNoise(clientInfo.privateKey, outgoing = true) clientNoise = newNoise(rng, clientInfo.privateKey, outgoing = true)
conn = await transport2.dial(transport1.ma) conn = await transport2.dial(transport1.ma)
sconn = await clientNoise.secure(conn, true) sconn = await clientNoise.secure(conn, true)

View File

@ -1,14 +1,16 @@
{.used.} {.used.}
import unittest, options import unittest, options, bearssl
import chronos import chronos
import ../libp2p/crypto/crypto, import ../libp2p/crypto/crypto,
../libp2p/peerinfo, ../libp2p/peerinfo,
../libp2p/peerid ../libp2p/peerid
import ./helpers
suite "PeerInfo": suite "PeerInfo":
test "Should init with private key": test "Should init with private key":
let seckey = PrivateKey.random(ECDSA).get() let seckey = PrivateKey.random(ECDSA, rng[]).get()
var peerInfo = PeerInfo.init(seckey) var peerInfo = PeerInfo.init(seckey)
var peerId = PeerID.init(seckey).get() var peerId = PeerID.init(seckey).get()
@ -17,7 +19,7 @@ suite "PeerInfo":
check seckey.getKey().get() == peerInfo.publicKey.get() check seckey.getKey().get() == peerInfo.publicKey.get()
test "Should init with public key": test "Should init with public key":
let seckey = PrivateKey.random(ECDSA).get() let seckey = PrivateKey.random(ECDSA, rng[]).get()
var peerInfo = PeerInfo.init(seckey.getKey().get()) var peerInfo = PeerInfo.init(seckey.getKey().get())
var peerId = PeerID.init(seckey.getKey().get()).get() var peerId = PeerID.init(seckey.getKey().get()).get()
@ -25,7 +27,7 @@ suite "PeerInfo":
check seckey.getKey.get() == peerInfo.publicKey.get() check seckey.getKey.get() == peerInfo.publicKey.get()
test "Should init from PeerId with public key": test "Should init from PeerId with public key":
let seckey = PrivateKey.random(Ed25519).get() let seckey = PrivateKey.random(Ed25519, rng[]).get()
var peerInfo = PeerInfo.init(PeerID.init(seckey.getKey.get()).get()) var peerInfo = PeerInfo.init(PeerID.init(seckey.getKey.get()).get())
var peerId = PeerID.init(seckey.getKey.get()).get() var peerId = PeerID.init(seckey.getKey.get()).get()
@ -47,16 +49,16 @@ suite "PeerInfo":
# PeerID.init("bafzbeie5745rpv2m6tjyuugywy4d5ewrqgqqhfnf445he3omzpjbx5xqxe") == peerInfo.peerId # PeerID.init("bafzbeie5745rpv2m6tjyuugywy4d5ewrqgqqhfnf445he3omzpjbx5xqxe") == peerInfo.peerId
test "Should return none if pubkey is missing from id": test "Should return none if pubkey is missing from id":
let peerInfo = PeerInfo.init(PeerID.init(PrivateKey.random(ECDSA).get()).get()) let peerInfo = PeerInfo.init(PeerID.init(PrivateKey.random(ECDSA, rng[]).get()).get())
check peerInfo.publicKey.isNone check peerInfo.publicKey.isNone
test "Should return some if pubkey is present in id": test "Should return some if pubkey is present in id":
let peerInfo = PeerInfo.init(PeerID.init(PrivateKey.random(Ed25519).get()).get()) let peerInfo = PeerInfo.init(PeerID.init(PrivateKey.random(Ed25519, rng[]).get()).get())
check peerInfo.publicKey.isSome check peerInfo.publicKey.isSome
test "join() and isClosed() test": test "join() and isClosed() test":
proc testJoin(): Future[bool] {.async, gcsafe.} = proc testJoin(): Future[bool] {.async, gcsafe.} =
let peerInfo = PeerInfo.init(PeerID.init(PrivateKey.random(Ed25519).get()).get()) let peerInfo = PeerInfo.init(PeerID.init(PrivateKey.random(Ed25519, rng[]).get()).get())
check peerInfo.isClosed() == false check peerInfo.isClosed() == false
var joinFut = peerInfo.join() var joinFut = peerInfo.join()
check joinFut.finished() == false check joinFut.finished() == false

View File

@ -8,7 +8,7 @@
## those terms. ## those terms.
import unittest import unittest
import nimcrypto/utils import nimcrypto/utils
import ../libp2p/crypto/rsa import ../libp2p/crypto/[crypto, rsa]
when defined(nimHasUsed): {.used.} when defined(nimHasUsed): {.used.}
@ -267,13 +267,18 @@ const
ACB51807206B8332127E3692269013B96F0CABD95D7431805E48176ADC5D1366""" ACB51807206B8332127E3692269013B96F0CABD95D7431805E48176ADC5D1366"""
] ]
suite "RSA 512/1024/2048/4096 test suite": let rng = newRng()
type
RsaPrivateKey = rsa.RsaPrivateKey
RsaPublicKey = rsa.RsaPublicKey
suite "RSA 512/1024/2048/4096 test suite":
test "[rsa512] Private key serialize/deserialize test": test "[rsa512] Private key serialize/deserialize test":
for i in 0..<TestsCount: for i in 0..<TestsCount:
var rkey1, rkey2: RsaPrivateKey var rkey1, rkey2: RsaPrivateKey
var skey2 = newSeq[byte](4096) var skey2 = newSeq[byte](4096)
var key = RsaPrivateKey.random(512).expect("random key") var key = RsaPrivateKey.random(rng[], 512).expect("random key")
var skey1 = key.getBytes().expect("bytes") var skey1 = key.getBytes().expect("bytes")
check key.toBytes(skey2).expect("bytes") > 0 check key.toBytes(skey2).expect("bytes") > 0
check: check:
@ -291,7 +296,7 @@ suite "RSA 512/1024/2048/4096 test suite":
for i in 0..<TestsCount: for i in 0..<TestsCount:
var rkey1, rkey2: RsaPrivateKey var rkey1, rkey2: RsaPrivateKey
var skey2 = newSeq[byte](4096) var skey2 = newSeq[byte](4096)
var key = RsaPrivateKey.random(1024).expect("random failed") var key = RsaPrivateKey.random(rng[], 1024).expect("random failed")
var skey1 = key.getBytes().expect("bytes") var skey1 = key.getBytes().expect("bytes")
check key.toBytes(skey2).expect("bytes") > 0 check key.toBytes(skey2).expect("bytes") > 0
check: check:
@ -308,7 +313,7 @@ suite "RSA 512/1024/2048/4096 test suite":
test "[rsa2048] Private key serialize/deserialize test": test "[rsa2048] Private key serialize/deserialize test":
var rkey1, rkey2: RsaPrivateKey var rkey1, rkey2: RsaPrivateKey
var skey2 = newSeq[byte](4096) var skey2 = newSeq[byte](4096)
var key = RsaPrivateKey.random(2048).expect("random failed") var key = RsaPrivateKey.random(rng[], 2048).expect("random failed")
var skey1 = key.getBytes().expect("bytes") var skey1 = key.getBytes().expect("bytes")
check key.toBytes(skey2).expect("bytes") > 0 check key.toBytes(skey2).expect("bytes") > 0
check: check:
@ -327,7 +332,7 @@ suite "RSA 512/1024/2048/4096 test suite":
when defined(release): when defined(release):
var rkey1, rkey2: RsaPrivateKey var rkey1, rkey2: RsaPrivateKey
var skey2 = newSeq[byte](4096) var skey2 = newSeq[byte](4096)
var key = RsaPrivateKey.random(4096).expect("random failed") var key = RsaPrivateKey.random(rng[], 4096).expect("random failed")
var skey1 = key.getBytes().expect("bytes") var skey1 = key.getBytes().expect("bytes")
check key.toBytes(skey2).expect("bytes") > 0 check key.toBytes(skey2).expect("bytes") > 0
check: check:
@ -345,7 +350,7 @@ suite "RSA 512/1024/2048/4096 test suite":
for i in 0..<TestsCount: for i in 0..<TestsCount:
var rkey1, rkey2: RsaPublicKey var rkey1, rkey2: RsaPublicKey
var skey2 = newSeq[byte](4096) var skey2 = newSeq[byte](4096)
var pair = RsaKeyPair.random(512).expect("random failed") var pair = RsaKeyPair.random(rng[], 512).expect("random failed")
var skey1 = pair.pubkey().getBytes().expect("bytes") var skey1 = pair.pubkey().getBytes().expect("bytes")
check: check:
pair.pubkey.toBytes(skey2).expect("bytes") > 0 pair.pubkey.toBytes(skey2).expect("bytes") > 0
@ -363,7 +368,7 @@ suite "RSA 512/1024/2048/4096 test suite":
for i in 0..<TestsCount: for i in 0..<TestsCount:
var rkey1, rkey2: RsaPublicKey var rkey1, rkey2: RsaPublicKey
var skey2 = newSeq[byte](4096) var skey2 = newSeq[byte](4096)
var pair = RsaKeyPair.random(1024).expect("random failed") var pair = RsaKeyPair.random(rng[], 1024).expect("random failed")
var skey1 = pair.pubkey.getBytes().expect("bytes") var skey1 = pair.pubkey.getBytes().expect("bytes")
check: check:
pair.pubkey.toBytes(skey2).expect("bytes") > 0 pair.pubkey.toBytes(skey2).expect("bytes") > 0
@ -380,7 +385,7 @@ suite "RSA 512/1024/2048/4096 test suite":
test "[rsa2048] Public key serialize/deserialize test": test "[rsa2048] Public key serialize/deserialize test":
var rkey1, rkey2: RsaPublicKey var rkey1, rkey2: RsaPublicKey
var skey2 = newSeq[byte](4096) var skey2 = newSeq[byte](4096)
var pair = RsaKeyPair.random(2048).expect("random failed") var pair = RsaKeyPair.random(rng[], 2048).expect("random failed")
var skey1 = pair.pubkey.getBytes().expect("bytes") var skey1 = pair.pubkey.getBytes().expect("bytes")
check: check:
pair.pubkey.toBytes(skey2).expect("bytes") > 0 pair.pubkey.toBytes(skey2).expect("bytes") > 0
@ -398,7 +403,7 @@ suite "RSA 512/1024/2048/4096 test suite":
when defined(release): when defined(release):
var rkey1, rkey2: RsaPublicKey var rkey1, rkey2: RsaPublicKey
var skey2 = newSeq[byte](4096) var skey2 = newSeq[byte](4096)
var pair = RsaKeyPair.random(4096).expect("random failed") var pair = RsaKeyPair.random(rng[], 4096).expect("random failed")
var skey1 = pair.pubkey.getBytes().expect("bytes") var skey1 = pair.pubkey.getBytes().expect("bytes")
check: check:
pair.pubkey.toBytes(skey2).expect("bytes") > 0 pair.pubkey.toBytes(skey2).expect("bytes") > 0
@ -415,7 +420,7 @@ suite "RSA 512/1024/2048/4096 test suite":
test "[rsa512] Generate/Sign/Serialize/Deserialize/Verify test": test "[rsa512] Generate/Sign/Serialize/Deserialize/Verify test":
var message = "message to sign" var message = "message to sign"
for i in 0..<TestsCount: for i in 0..<TestsCount:
var kp = RsaKeyPair.random(512).expect("RsaKeyPair.random failed") var kp = RsaKeyPair.random(rng[], 512).expect("RsaKeyPair.random failed")
var sig = kp.seckey.sign(message).expect("signature") var sig = kp.seckey.sign(message).expect("signature")
var sersk = kp.seckey.getBytes().expect("bytes") var sersk = kp.seckey.getBytes().expect("bytes")
var serpk = kp.pubkey.getBytes().expect("bytes") var serpk = kp.pubkey.getBytes().expect("bytes")
@ -431,7 +436,7 @@ suite "RSA 512/1024/2048/4096 test suite":
test "[rsa1024] Generate/Sign/Serialize/Deserialize/Verify test": test "[rsa1024] Generate/Sign/Serialize/Deserialize/Verify test":
var message = "message to sign" var message = "message to sign"
for i in 0..<TestsCount: for i in 0..<TestsCount:
var kp = RsaKeyPair.random(1024).expect("RsaPrivateKey.random failed") var kp = RsaKeyPair.random(rng[], 1024).expect("RsaPrivateKey.random failed")
var sig = kp.seckey.sign(message).expect("signature") var sig = kp.seckey.sign(message).expect("signature")
var sersk = kp.seckey.getBytes().expect("bytes") var sersk = kp.seckey.getBytes().expect("bytes")
var serpk = kp.pubkey.getBytes().expect("bytes") var serpk = kp.pubkey.getBytes().expect("bytes")
@ -446,7 +451,7 @@ suite "RSA 512/1024/2048/4096 test suite":
test "[rsa2048] Generate/Sign/Serialize/Deserialize/Verify test": test "[rsa2048] Generate/Sign/Serialize/Deserialize/Verify test":
var message = "message to sign" var message = "message to sign"
var kp = RsaKeyPair.random(2048).expect("RsaPrivateKey.random failed") var kp = RsaKeyPair.random(rng[], 2048).expect("RsaPrivateKey.random failed")
var sig = kp.seckey.sign(message).expect("signature") var sig = kp.seckey.sign(message).expect("signature")
var sersk = kp.seckey.getBytes().expect("bytes") var sersk = kp.seckey.getBytes().expect("bytes")
var serpk = kp.pubkey.getBytes().expect("bytes") var serpk = kp.pubkey.getBytes().expect("bytes")
@ -462,7 +467,7 @@ suite "RSA 512/1024/2048/4096 test suite":
test "[rsa4096] Generate/Sign/Serialize/Deserialize/Verify test": test "[rsa4096] Generate/Sign/Serialize/Deserialize/Verify test":
when defined(release): when defined(release):
var message = "message to sign" var message = "message to sign"
var kp = RsaKeyPair.random(2048).expect("RsaPrivateKey.random failed") var kp = RsaKeyPair.random(rng[], 2048).expect("RsaPrivateKey.random failed")
var sig = kp.seckey.sign(message).expect("signature") var sig = kp.seckey.sign(message).expect("signature")
var sersk = kp.seckey.getBytes().expect("bytes") var sersk = kp.seckey.getBytes().expect("bytes")
var serpk = kp.pubkey.getBytes().expect("bytes") var serpk = kp.pubkey.getBytes().expect("bytes")

View File

@ -6,19 +6,22 @@
## at your option. ## at your option.
## This file may not be copied, modified, or distributed except according to ## This file may not be copied, modified, or distributed except according to
## those terms. ## those terms.
import unittest import unittest, bearssl
import ../libp2p/crypto/secp import ../libp2p/crypto/[crypto, secp]
import nimcrypto/utils import nimcrypto/utils
when defined(nimHasUsed): {.used.} when defined(nimHasUsed): {.used.}
let rng = newRng()
suite "Secp256k1 testing suite": suite "Secp256k1 testing suite":
const TestsCount = 20 const TestsCount = 20
test "Private key serialize/deserialize test": test "Private key serialize/deserialize test":
for i in 0..<TestsCount: for i in 0..<TestsCount:
var rkey1, rkey2: SkPrivateKey var rkey1, rkey2: SkPrivateKey
var skey2 = newSeq[byte](256) var skey2 = newSeq[byte](256)
var key = SkPrivateKey.random().expect("random key") var key = SkPrivateKey.random(rng[])
var skey1 = key.getBytes() var skey1 = key.getBytes()
check: check:
key.toBytes(skey2).expect("bytes len") > 0 key.toBytes(skey2).expect("bytes len") > 0
@ -36,7 +39,7 @@ suite "Secp256k1 testing suite":
for i in 0..<TestsCount: for i in 0..<TestsCount:
var rkey1, rkey2: SkPublicKey var rkey1, rkey2: SkPublicKey
var skey2 = newSeq[byte](256) var skey2 = newSeq[byte](256)
var pair = SkKeyPair.random().expect("random key pair") var pair = SkKeyPair.random(rng[])
var skey1 = pair.pubkey.getBytes() var skey1 = pair.pubkey.getBytes()
check: check:
pair.pubkey.toBytes(skey2).expect("bytes len") > 0 pair.pubkey.toBytes(skey2).expect("bytes len") > 0
@ -52,7 +55,7 @@ suite "Secp256k1 testing suite":
test "Generate/Sign/Serialize/Deserialize/Verify test": test "Generate/Sign/Serialize/Deserialize/Verify test":
var message = "message to sign" var message = "message to sign"
for i in 0..<TestsCount: for i in 0..<TestsCount:
var kp = SkKeyPair.random().expect("random key pair") var kp = SkKeyPair.random(rng[])
var sig = kp.seckey.sign(message) var sig = kp.seckey.sign(message)
var sersk = kp.seckey.getBytes() var sersk = kp.seckey.getBytes()
var serpk = kp.pubkey.getBytes() var serpk = kp.pubkey.getBytes()