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:
parent
b49c619ca8
commit
d522537b19
|
@ -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())
|
||||||
|
|
|
@ -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 =
|
||||||
|
|
|
@ -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)
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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``.
|
||||||
|
|
|
@ -17,8 +17,6 @@ import nimcrypto/utils
|
||||||
|
|
||||||
type
|
type
|
||||||
Asn1Error* {.pure.} = enum
|
Asn1Error* {.pure.} = enum
|
||||||
None,
|
|
||||||
Error,
|
|
||||||
Overflow,
|
Overflow,
|
||||||
Incomplete,
|
Incomplete,
|
||||||
Indefinite,
|
Indefinite,
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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.}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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())
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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]
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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")
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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")
|
||||||
|
|
|
@ -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()
|
||||||
|
|
Loading…
Reference in New Issue