parent
718374d890
commit
a7e335e1bb
2
.pinned
2
.pinned
|
@ -1,5 +1,5 @@
|
||||||
asynctest;https://github.com/markspanbroek/asynctest@#5347c59b4b057443a014722aa40800cd8bb95c69
|
asynctest;https://github.com/markspanbroek/asynctest@#5347c59b4b057443a014722aa40800cd8bb95c69
|
||||||
bearssl;https://github.com/status-im/nim-bearssl@#0ebb1d7a4af5f4b4d4756a9b6dbfe5d411fa55d9
|
bearssl;https://github.com/status-im/nim-bearssl@#c4aec8b664709356060b71b7e495be62ca446a65
|
||||||
chronicles;https://github.com/status-im/nim-chronicles@#2a2681b60289aaf7895b7056f22616081eb1a882
|
chronicles;https://github.com/status-im/nim-chronicles@#2a2681b60289aaf7895b7056f22616081eb1a882
|
||||||
chronos;https://github.com/status-im/nim-chronos@#875d7d8e6ef0803ae1c331dbf76b1981b0caeb15
|
chronos;https://github.com/status-im/nim-chronos@#875d7d8e6ef0803ae1c331dbf76b1981b0caeb15
|
||||||
dnsclient;https://github.com/ba0f3/dnsclient.nim@#fbb76f8af8a33ab818184a7d4406d9fee20993be
|
dnsclient;https://github.com/ba0f3/dnsclient.nim@#fbb76f8af8a33ab818184a7d4406d9fee20993be
|
||||||
|
|
|
@ -150,7 +150,7 @@ 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, rng: ref BrHmacDrbgContext) {.async.} =
|
proc processInput(rfd: AsyncFD, rng: ref HmacDrbgContext) {.async.} =
|
||||||
let transp = fromPipe(rfd)
|
let transp = fromPipe(rfd)
|
||||||
|
|
||||||
let seckey = PrivateKey.random(RSA, rng[]).get()
|
let seckey = PrivateKey.random(RSA, rng[]).get()
|
||||||
|
|
|
@ -2,7 +2,7 @@ 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
|
import
|
||||||
strformat, strutils, bearssl,
|
strformat, strutils,
|
||||||
stew/byteutils,
|
stew/byteutils,
|
||||||
chronos,
|
chronos,
|
||||||
../libp2p
|
../libp2p
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import bearssl
|
|
||||||
import chronos # an efficient library for async
|
import chronos # an efficient library for async
|
||||||
import stew/byteutils # various utils
|
import stew/byteutils # various utils
|
||||||
import ../libp2p # when installed through nimble, just use `import libp2p`
|
import ../libp2p # when installed through nimble, just use `import libp2p`
|
||||||
|
@ -26,7 +25,7 @@ proc new(T: typedesc[TestProto]): T =
|
||||||
##
|
##
|
||||||
# Helper to create a switch/node
|
# Helper to create a switch/node
|
||||||
##
|
##
|
||||||
proc createSwitch(ma: MultiAddress, rng: ref BrHmacDrbgContext): Switch =
|
proc createSwitch(ma: MultiAddress, rng: ref HmacDrbgContext): Switch =
|
||||||
var switch = SwitchBuilder
|
var switch = SwitchBuilder
|
||||||
.new()
|
.new()
|
||||||
.withRng(rng) # Give the application RNG
|
.withRng(rng) # Give the application RNG
|
||||||
|
|
|
@ -24,18 +24,16 @@ _TIP: You can extract the code from this tutorial by running `nim c -r tools/mar
|
||||||
|
|
||||||
Let's create a `part1.nim`, and import our dependencies:
|
Let's create a `part1.nim`, and import our dependencies:
|
||||||
```nim
|
```nim
|
||||||
import bearssl
|
|
||||||
import chronos
|
import chronos
|
||||||
|
|
||||||
import libp2p
|
import libp2p
|
||||||
import libp2p/protocols/ping
|
import libp2p/protocols/ping
|
||||||
```
|
```
|
||||||
[bearssl](https://github.com/status-im/nim-bearssl) is used as a [cryptographic pseudorandom number generator](https://en.wikipedia.org/wiki/Cryptographically-secure_pseudorandom_number_generator)
|
|
||||||
[chronos](https://github.com/status-im/nim-chronos) the asynchronous framework used by `nim-libp2p`
|
[chronos](https://github.com/status-im/nim-chronos) the asynchronous framework used by `nim-libp2p`
|
||||||
|
|
||||||
Next, we'll create an helper procedure to create our switches. A switch needs a bit of configuration, and it will be easier to do this configuration only once:
|
Next, we'll create an helper procedure to create our switches. A switch needs a bit of configuration, and it will be easier to do this configuration only once:
|
||||||
```nim
|
```nim
|
||||||
proc createSwitch(ma: MultiAddress, rng: ref BrHmacDrbgContext): Switch =
|
proc createSwitch(ma: MultiAddress, rng: ref HmacDrbgContext): Switch =
|
||||||
var switch = SwitchBuilder
|
var switch = SwitchBuilder
|
||||||
.new()
|
.new()
|
||||||
.withRng(rng) # Give the application RNG
|
.withRng(rng) # Give the application RNG
|
||||||
|
|
|
@ -5,7 +5,6 @@ We'll now look at how to create a custom protocol inside the libp2p
|
||||||
# Custom protocol in libp2p
|
# Custom protocol in libp2p
|
||||||
Let's create a `part2.nim`, and import our dependencies:
|
Let's create a `part2.nim`, and import our dependencies:
|
||||||
```nim
|
```nim
|
||||||
import bearssl
|
|
||||||
import chronos
|
import chronos
|
||||||
import stew/byteutils
|
import stew/byteutils
|
||||||
|
|
||||||
|
|
|
@ -30,11 +30,9 @@ import
|
||||||
crypto/crypto,
|
crypto/crypto,
|
||||||
protocols/pubsub]
|
protocols/pubsub]
|
||||||
|
|
||||||
import bearssl
|
|
||||||
|
|
||||||
export
|
export
|
||||||
minprotobuf, switch, peerid, peerinfo,
|
minprotobuf, switch, peerid, peerinfo,
|
||||||
connection, multiaddress, crypto, lpstream,
|
connection, multiaddress, crypto, lpstream,
|
||||||
bufferstream, bearssl, muxer, mplex, transport,
|
bufferstream, muxer, mplex, transport,
|
||||||
tcptransport, noise, errors, cid, multihash,
|
tcptransport, noise, errors, cid, multihash,
|
||||||
multicodec, builders, pubsub
|
multicodec, builders, pubsub
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
{.push raises: [Defect].}
|
{.push raises: [Defect].}
|
||||||
|
|
||||||
import
|
import
|
||||||
options, tables, chronos, chronicles, bearssl,
|
options, tables, chronos, chronicles,
|
||||||
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],
|
muxers/[muxer, mplex/mplex],
|
||||||
|
@ -39,7 +39,7 @@ type
|
||||||
secureManagers: seq[SecureProtocol]
|
secureManagers: seq[SecureProtocol]
|
||||||
mplexOpts: MplexOpts
|
mplexOpts: MplexOpts
|
||||||
transports: seq[TransportProvider]
|
transports: seq[TransportProvider]
|
||||||
rng: ref BrHmacDrbgContext
|
rng: ref HmacDrbgContext
|
||||||
maxConnections: int
|
maxConnections: int
|
||||||
maxIn: int
|
maxIn: int
|
||||||
sendSignedPeerRecord: bool
|
sendSignedPeerRecord: bool
|
||||||
|
@ -116,7 +116,7 @@ proc withTransport*(b: SwitchBuilder, prov: TransportProvider): SwitchBuilder =
|
||||||
proc withTcpTransport*(b: SwitchBuilder, flags: set[ServerFlags] = {}): SwitchBuilder =
|
proc withTcpTransport*(b: SwitchBuilder, flags: set[ServerFlags] = {}): SwitchBuilder =
|
||||||
b.withTransport(proc(upgr: Upgrade): Transport = TcpTransport.new(flags, upgr))
|
b.withTransport(proc(upgr: Upgrade): Transport = TcpTransport.new(flags, upgr))
|
||||||
|
|
||||||
proc withRng*(b: SwitchBuilder, rng: ref BrHmacDrbgContext): SwitchBuilder =
|
proc withRng*(b: SwitchBuilder, rng: ref HmacDrbgContext): SwitchBuilder =
|
||||||
b.rng = rng
|
b.rng = rng
|
||||||
b
|
b
|
||||||
|
|
||||||
|
|
|
@ -17,17 +17,10 @@
|
||||||
|
|
||||||
{.push raises: [Defect].}
|
{.push raises: [Defect].}
|
||||||
|
|
||||||
import bearssl
|
import bearssl/blockx
|
||||||
from stew/assign2 import assign
|
from stew/assign2 import assign
|
||||||
from stew/ranges/ptr_arith import baseAddr
|
from stew/ranges/ptr_arith import baseAddr
|
||||||
|
|
||||||
# have to do this due to a nim bug and raises[] on callbacks
|
|
||||||
# https://github.com/nim-lang/Nim/issues/13905
|
|
||||||
proc ourPoly1305CtmulRun*(key: pointer; iv: pointer; data: pointer; len: int;
|
|
||||||
aad: pointer; aadLen: int; tag: pointer; ichacha: pointer;
|
|
||||||
encrypt: cint) {.cdecl, importc: "br_poly1305_ctmul_run",
|
|
||||||
header: "bearssl_block.h".}
|
|
||||||
|
|
||||||
const
|
const
|
||||||
ChaChaPolyKeySize = 32
|
ChaChaPolyKeySize = 32
|
||||||
ChaChaPolyNonceSize = 12
|
ChaChaPolyNonceSize = 12
|
||||||
|
@ -67,15 +60,16 @@ proc encrypt*(_: type[ChaChaPoly],
|
||||||
else:
|
else:
|
||||||
nil
|
nil
|
||||||
|
|
||||||
ourPoly1305CtmulRun(
|
poly1305CtmulRun(
|
||||||
unsafeAddr key[0],
|
unsafeAddr key[0],
|
||||||
unsafeAddr nonce[0],
|
unsafeAddr nonce[0],
|
||||||
baseAddr(data),
|
baseAddr(data),
|
||||||
data.len,
|
uint(data.len),
|
||||||
ad,
|
ad,
|
||||||
aad.len,
|
uint(aad.len),
|
||||||
baseAddr(tag),
|
baseAddr(tag),
|
||||||
chacha20CtRun,
|
# cast is required to workaround https://github.com/nim-lang/Nim/issues/13905
|
||||||
|
cast[Chacha20Run](chacha20CtRun),
|
||||||
#[encrypt]# 1.cint)
|
#[encrypt]# 1.cint)
|
||||||
|
|
||||||
proc decrypt*(_: type[ChaChaPoly],
|
proc decrypt*(_: type[ChaChaPoly],
|
||||||
|
@ -90,13 +84,14 @@ proc decrypt*(_: type[ChaChaPoly],
|
||||||
else:
|
else:
|
||||||
nil
|
nil
|
||||||
|
|
||||||
ourPoly1305CtmulRun(
|
poly1305CtmulRun(
|
||||||
unsafeAddr key[0],
|
unsafeAddr key[0],
|
||||||
unsafeAddr nonce[0],
|
unsafeAddr nonce[0],
|
||||||
baseAddr(data),
|
baseAddr(data),
|
||||||
data.len,
|
uint(data.len),
|
||||||
ad,
|
ad,
|
||||||
aad.len,
|
uint(aad.len),
|
||||||
baseAddr(tag),
|
baseAddr(tag),
|
||||||
chacha20CtRun,
|
# cast is required to workaround https://github.com/nim-lang/Nim/issues/13905
|
||||||
|
cast[Chacha20Run](chacha20CtRun),
|
||||||
#[decrypt]# 0.cint)
|
#[decrypt]# 0.cint)
|
||||||
|
|
|
@ -69,7 +69,7 @@ when supported(PKScheme.Secp256k1):
|
||||||
# We are still importing `ecnist` because, it is used for SECIO handshake,
|
# We are still importing `ecnist` because, it is used for SECIO handshake,
|
||||||
# but it will be impossible to create ECNIST keys or import ECNIST keys.
|
# but it will be impossible to create ECNIST keys or import ECNIST keys.
|
||||||
|
|
||||||
import ecnist, bearssl
|
import ecnist, bearssl/rand, bearssl/hash as bhash
|
||||||
import ../protobuf/minprotobuf, ../vbuffer, ../multihash, ../multicodec
|
import ../protobuf/minprotobuf, ../vbuffer, ../multihash, ../multicodec
|
||||||
import nimcrypto/[rijndael, twofish, sha2, hash, hmac]
|
import nimcrypto/[rijndael, twofish, sha2, hash, hmac]
|
||||||
# We use `ncrutils` for constant-time hexadecimal encoding/decoding procedures.
|
# We use `ncrutils` for constant-time hexadecimal encoding/decoding procedures.
|
||||||
|
@ -79,7 +79,7 @@ import stew/results
|
||||||
export results
|
export results
|
||||||
|
|
||||||
# This is workaround for Nim's `import` bug
|
# This is workaround for Nim's `import` bug
|
||||||
export rijndael, twofish, sha2, hash, hmac, ncrutils
|
export rijndael, twofish, sha2, hash, hmac, ncrutils, rand
|
||||||
|
|
||||||
type
|
type
|
||||||
DigestSheme* = enum
|
DigestSheme* = enum
|
||||||
|
@ -158,26 +158,28 @@ type
|
||||||
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 newRng*(): ref BrHmacDrbgContext =
|
proc newRng*(): ref HmacDrbgContext =
|
||||||
# You should only create one instance of the RNG per application / library
|
# You should only create one instance of the RNG per application / library
|
||||||
# Ref is used so that it can be shared between components
|
# Ref is used so that it can be shared between components
|
||||||
# TODO consider moving to bearssl
|
# TODO consider moving to bearssl
|
||||||
var seeder = brPrngSeederSystem(nil)
|
var seeder = prngSeederSystem(nil)
|
||||||
if seeder == nil:
|
if seeder == nil:
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
var rng = (ref BrHmacDrbgContext)()
|
var rng = (ref HmacDrbgContext)()
|
||||||
brHmacDrbgInit(addr rng[], addr sha256Vtable, nil, 0)
|
hmacDrbgInit(rng[], addr sha256Vtable, nil, 0)
|
||||||
if seeder(addr rng.vtable) == 0:
|
if seeder(addr rng.vtable) == 0:
|
||||||
return nil
|
return nil
|
||||||
rng
|
rng
|
||||||
|
|
||||||
proc shuffle*[T](
|
proc shuffle*[T](
|
||||||
rng: ref BrHmacDrbgContext,
|
rng: ref HmacDrbgContext,
|
||||||
x: var openArray[T]) =
|
x: var openArray[T]) =
|
||||||
|
|
||||||
|
if x.len == 0: return
|
||||||
|
|
||||||
var randValues = newSeqUninitialized[byte](len(x) * 2)
|
var randValues = newSeqUninitialized[byte](len(x) * 2)
|
||||||
brHmacDrbgGenerate(rng[], randValues)
|
hmacDrbgGenerate(rng[], randValues)
|
||||||
|
|
||||||
for i in countdown(x.high, 1):
|
for i in countdown(x.high, 1):
|
||||||
let
|
let
|
||||||
|
@ -186,7 +188,7 @@ proc shuffle*[T](
|
||||||
swap(x[i], x[y])
|
swap(x[i], x[y])
|
||||||
|
|
||||||
proc random*(T: typedesc[PrivateKey], scheme: PKScheme,
|
proc random*(T: typedesc[PrivateKey], scheme: PKScheme,
|
||||||
rng: var BrHmacDrbgContext,
|
rng: var HmacDrbgContext,
|
||||||
bits = RsaDefaultKeySize): CryptoResult[PrivateKey] =
|
bits = RsaDefaultKeySize): CryptoResult[PrivateKey] =
|
||||||
## Generate random private key for scheme ``scheme``.
|
## Generate random private key for scheme ``scheme``.
|
||||||
##
|
##
|
||||||
|
@ -218,7 +220,7 @@ proc random*(T: typedesc[PrivateKey], scheme: PKScheme,
|
||||||
else:
|
else:
|
||||||
err(SchemeError)
|
err(SchemeError)
|
||||||
|
|
||||||
proc random*(T: typedesc[PrivateKey], rng: var BrHmacDrbgContext,
|
proc random*(T: typedesc[PrivateKey], rng: var HmacDrbgContext,
|
||||||
bits = RsaDefaultKeySize): CryptoResult[PrivateKey] =
|
bits = RsaDefaultKeySize): CryptoResult[PrivateKey] =
|
||||||
## Generate random private key using default public-key cryptography scheme.
|
## Generate random private key using default public-key cryptography scheme.
|
||||||
##
|
##
|
||||||
|
@ -242,7 +244,7 @@ proc random*(T: typedesc[PrivateKey], rng: var BrHmacDrbgContext,
|
||||||
err(SchemeError)
|
err(SchemeError)
|
||||||
|
|
||||||
proc random*(T: typedesc[KeyPair], scheme: PKScheme,
|
proc random*(T: typedesc[KeyPair], scheme: PKScheme,
|
||||||
rng: var BrHmacDrbgContext,
|
rng: var HmacDrbgContext,
|
||||||
bits = RsaDefaultKeySize): CryptoResult[KeyPair] =
|
bits = RsaDefaultKeySize): CryptoResult[KeyPair] =
|
||||||
## Generate random key pair for scheme ``scheme``.
|
## Generate random key pair for scheme ``scheme``.
|
||||||
##
|
##
|
||||||
|
@ -282,7 +284,7 @@ proc random*(T: typedesc[KeyPair], scheme: PKScheme,
|
||||||
else:
|
else:
|
||||||
err(SchemeError)
|
err(SchemeError)
|
||||||
|
|
||||||
proc random*(T: typedesc[KeyPair], rng: var BrHmacDrbgContext,
|
proc random*(T: typedesc[KeyPair], rng: var HmacDrbgContext,
|
||||||
bits = RsaDefaultKeySize): CryptoResult[KeyPair] =
|
bits = RsaDefaultKeySize): CryptoResult[KeyPair] =
|
||||||
## Generate random private pair of keys using default public-key cryptography
|
## Generate random private pair of keys using default public-key cryptography
|
||||||
## scheme.
|
## scheme.
|
||||||
|
@ -870,7 +872,7 @@ proc mac*(secret: Secret, id: int): seq[byte] {.inline.} =
|
||||||
|
|
||||||
proc ephemeral*(
|
proc ephemeral*(
|
||||||
scheme: ECDHEScheme,
|
scheme: ECDHEScheme,
|
||||||
rng: var BrHmacDrbgContext): CryptoResult[EcKeyPair] =
|
rng: var HmacDrbgContext): CryptoResult[EcKeyPair] =
|
||||||
## 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:
|
||||||
|
@ -882,7 +884,7 @@ proc ephemeral*(
|
||||||
ok(keypair)
|
ok(keypair)
|
||||||
|
|
||||||
proc ephemeral*(
|
proc ephemeral*(
|
||||||
scheme: string, rng: var BrHmacDrbgContext): CryptoResult[EcKeyPair] =
|
scheme: string, rng: var HmacDrbgContext): CryptoResult[EcKeyPair] =
|
||||||
## 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
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
{.push raises: [Defect].}
|
{.push raises: [Defect].}
|
||||||
|
|
||||||
import bearssl
|
import bearssl/[ec, rand, hash]
|
||||||
import stew/results
|
import stew/results
|
||||||
from stew/assign2 import assign
|
from stew/assign2 import assign
|
||||||
export results
|
export results
|
||||||
|
@ -46,7 +46,7 @@ proc byteswap(buf: var Curve25519Key) {.inline.} =
|
||||||
buf[31 - i] = x
|
buf[31 - i] = x
|
||||||
|
|
||||||
proc mul*(_: type[Curve25519], point: var Curve25519Key, multiplier: Curve25519Key) =
|
proc mul*(_: type[Curve25519], point: var Curve25519Key, multiplier: Curve25519Key) =
|
||||||
let defaultBrEc = brEcGetDefault()
|
let defaultBrEc = ecGetDefault()
|
||||||
|
|
||||||
# multiplier needs to be big-endian
|
# multiplier needs to be big-endian
|
||||||
var
|
var
|
||||||
|
@ -54,15 +54,15 @@ proc mul*(_: type[Curve25519], point: var Curve25519Key, multiplier: Curve25519K
|
||||||
multiplierBs.byteswap()
|
multiplierBs.byteswap()
|
||||||
let
|
let
|
||||||
res = defaultBrEc.mul(
|
res = defaultBrEc.mul(
|
||||||
cast[pcuchar](addr point[0]),
|
addr point[0],
|
||||||
Curve25519KeySize,
|
Curve25519KeySize,
|
||||||
cast[pcuchar](addr multiplierBs[0]),
|
addr multiplierBs[0],
|
||||||
Curve25519KeySize,
|
Curve25519KeySize,
|
||||||
EC_curve25519)
|
EC_curve25519)
|
||||||
assert res == 1
|
assert res == 1
|
||||||
|
|
||||||
proc mulgen(_: type[Curve25519], dst: var Curve25519Key, point: Curve25519Key) =
|
proc mulgen(_: type[Curve25519], dst: var Curve25519Key, point: Curve25519Key) =
|
||||||
let defaultBrEc = brEcGetDefault()
|
let defaultBrEc = ecGetDefault()
|
||||||
|
|
||||||
var
|
var
|
||||||
rpoint = point
|
rpoint = point
|
||||||
|
@ -70,8 +70,8 @@ proc mulgen(_: type[Curve25519], dst: var Curve25519Key, point: Curve25519Key) =
|
||||||
|
|
||||||
let
|
let
|
||||||
size = defaultBrEc.mulgen(
|
size = defaultBrEc.mulgen(
|
||||||
cast[pcuchar](addr dst[0]),
|
addr dst[0],
|
||||||
cast[pcuchar](addr rpoint[0]),
|
addr rpoint[0],
|
||||||
Curve25519KeySize,
|
Curve25519KeySize,
|
||||||
EC_curve25519)
|
EC_curve25519)
|
||||||
|
|
||||||
|
@ -80,10 +80,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], rng: var BrHmacDrbgContext): Curve25519Key =
|
proc random*(_: type[Curve25519Key], rng: var HmacDrbgContext): Curve25519Key =
|
||||||
var res: Curve25519Key
|
var res: Curve25519Key
|
||||||
let defaultBrEc = brEcGetDefault()
|
let defaultBrEc = ecGetDefault()
|
||||||
let len = brEcKeygen(
|
let len = ecKeygen(
|
||||||
addr rng.vtable, defaultBrEc, nil, addr res[0], EC_curve25519)
|
addr rng.vtable, defaultBrEc, nil, addr res[0], EC_curve25519)
|
||||||
# Per bearssl documentation, the keygen only fails if the curve is
|
# Per bearssl documentation, the keygen only fails if the curve is
|
||||||
# unrecognised -
|
# unrecognised -
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
{.push raises: [Defect].}
|
{.push raises: [Defect].}
|
||||||
|
|
||||||
import bearssl
|
import bearssl/[ec, rand, hash]
|
||||||
# We use `ncrutils` for constant-time hexadecimal encoding/decoding procedures.
|
# We use `ncrutils` for constant-time hexadecimal encoding/decoding procedures.
|
||||||
import nimcrypto/utils as ncrutils
|
import nimcrypto/utils as ncrutils
|
||||||
import minasn1
|
import minasn1
|
||||||
|
@ -40,12 +40,12 @@ const
|
||||||
|
|
||||||
type
|
type
|
||||||
EcPrivateKey* = ref object
|
EcPrivateKey* = ref object
|
||||||
buffer*: array[BR_EC_KBUF_PRIV_MAX_SIZE, byte]
|
buffer*: array[EC_KBUF_PRIV_MAX_SIZE, byte]
|
||||||
key*: BrEcPrivateKey
|
key*: ec.EcPrivateKey
|
||||||
|
|
||||||
EcPublicKey* = ref object
|
EcPublicKey* = ref object
|
||||||
buffer*: array[BR_EC_KBUF_PUB_MAX_SIZE, byte]
|
buffer*: array[EC_KBUF_PUB_MAX_SIZE, byte]
|
||||||
key*: BrEcPublicKey
|
key*: ec.EcPublicKey
|
||||||
|
|
||||||
EcKeyPair* = object
|
EcKeyPair* = object
|
||||||
seckey*: EcPrivateKey
|
seckey*: EcPrivateKey
|
||||||
|
@ -55,9 +55,9 @@ type
|
||||||
buffer*: seq[byte]
|
buffer*: seq[byte]
|
||||||
|
|
||||||
EcCurveKind* = enum
|
EcCurveKind* = enum
|
||||||
Secp256r1 = BR_EC_SECP256R1,
|
Secp256r1 = EC_SECP256R1,
|
||||||
Secp384r1 = BR_EC_SECP384R1,
|
Secp384r1 = EC_SECP384R1,
|
||||||
Secp521r1 = BR_EC_SECP521R1
|
Secp521r1 = EC_SECP521R1
|
||||||
|
|
||||||
EcPKI* = EcPrivateKey | EcPublicKey | EcSignature
|
EcPKI* = EcPrivateKey | EcPublicKey | EcSignature
|
||||||
|
|
||||||
|
@ -101,15 +101,15 @@ proc checkScalar(scalar: openArray[byte], curve: cint): uint32 =
|
||||||
## - ``scalar`` is lower than the curve ``order``.
|
## - ``scalar`` is lower than the curve ``order``.
|
||||||
##
|
##
|
||||||
## Otherwise, return ``0``.
|
## Otherwise, return ``0``.
|
||||||
var impl = brEcGetDefault()
|
var impl = ecGetDefault()
|
||||||
var orderlen = 0
|
var orderlen: uint = 0
|
||||||
var order = cast[ptr UncheckedArray[byte]](impl.order(curve, addr orderlen))
|
var order = cast[ptr UncheckedArray[byte]](impl.order(curve, orderlen))
|
||||||
|
|
||||||
var z = 0'u32
|
var z = 0'u32
|
||||||
var c = 0'i32
|
var c = 0'i32
|
||||||
for u in scalar:
|
for u in scalar:
|
||||||
z = z or u
|
z = z or u
|
||||||
if len(scalar) == orderlen:
|
if len(scalar) == int(orderlen):
|
||||||
for i in 0..<len(scalar):
|
for i in 0..<len(scalar):
|
||||||
c = c or (-(cast[int32](EQ0(c))) and CMP(scalar[i], order[i]))
|
c = c or (-(cast[int32](EQ0(c))) and CMP(scalar[i], order[i]))
|
||||||
else:
|
else:
|
||||||
|
@ -119,12 +119,12 @@ proc checkScalar(scalar: openArray[byte], curve: cint): uint32 =
|
||||||
proc checkPublic(key: openArray[byte], curve: cint): uint32 =
|
proc checkPublic(key: openArray[byte], curve: cint): uint32 =
|
||||||
## Return ``1`` if public key ``key`` is on curve.
|
## Return ``1`` if public key ``key`` is on curve.
|
||||||
var ckey = @key
|
var ckey = @key
|
||||||
var x = [0x00'u8, 0x01'u8]
|
var x = [byte 0x00, 0x01]
|
||||||
var impl = brEcGetDefault()
|
var impl = ecGetDefault()
|
||||||
var orderlen = 0
|
var orderlen: uint = 0
|
||||||
discard impl.order(curve, addr orderlen)
|
discard impl.order(curve, orderlen)
|
||||||
result = impl.mul(cast[ptr char](unsafeAddr ckey[0]), len(ckey),
|
result = impl.mul(unsafeAddr ckey[0], uint(len(ckey)),
|
||||||
cast[ptr char](addr x[0]), len(x), curve)
|
addr x[0], uint(len(x)), curve)
|
||||||
|
|
||||||
proc getOffset(pubkey: EcPublicKey): int {.inline.} =
|
proc getOffset(pubkey: EcPublicKey): int {.inline.} =
|
||||||
let o = cast[uint](pubkey.key.q) - cast[uint](unsafeAddr pubkey.buffer[0])
|
let o = cast[uint](pubkey.key.q) - cast[uint](unsafeAddr pubkey.buffer[0])
|
||||||
|
@ -174,7 +174,7 @@ proc copy*[T: EcPKI](dst: var T, src: T): bool =
|
||||||
dst.buffer = src.buffer
|
dst.buffer = src.buffer
|
||||||
dst.key.curve = src.key.curve
|
dst.key.curve = src.key.curve
|
||||||
dst.key.xlen = length
|
dst.key.xlen = length
|
||||||
dst.key.x = cast[ptr char](addr dst.buffer[offset])
|
dst.key.x = addr dst.buffer[offset]
|
||||||
result = true
|
result = true
|
||||||
elif T is EcPublicKey:
|
elif T is EcPublicKey:
|
||||||
let length = src.key.qlen
|
let length = src.key.qlen
|
||||||
|
@ -184,7 +184,7 @@ proc copy*[T: EcPKI](dst: var T, src: T): bool =
|
||||||
dst.buffer = src.buffer
|
dst.buffer = src.buffer
|
||||||
dst.key.curve = src.key.curve
|
dst.key.curve = src.key.curve
|
||||||
dst.key.qlen = length
|
dst.key.qlen = length
|
||||||
dst.key.q = cast[ptr char](addr dst.buffer[offset])
|
dst.key.q = addr dst.buffer[offset]
|
||||||
result = true
|
result = true
|
||||||
else:
|
else:
|
||||||
let length = len(src.buffer)
|
let length = len(src.buffer)
|
||||||
|
@ -230,15 +230,15 @@ proc clear*[T: EcPKI|EcKeyPair](pki: var T) =
|
||||||
|
|
||||||
proc random*(
|
proc random*(
|
||||||
T: typedesc[EcPrivateKey], kind: EcCurveKind,
|
T: typedesc[EcPrivateKey], kind: EcCurveKind,
|
||||||
rng: var BrHmacDrbgContext): EcResult[EcPrivateKey] =
|
rng: var HmacDrbgContext): 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 ecimp = brEcGetDefault()
|
var ecimp = ecGetDefault()
|
||||||
var res = new EcPrivateKey
|
var res = new EcPrivateKey
|
||||||
if brEcKeygen(addr rng.vtable, ecimp,
|
if ecKeygen(addr rng.vtable, ecimp,
|
||||||
addr res.key, addr res.buffer[0],
|
addr res.key, addr res.buffer[0],
|
||||||
cast[cint](kind)) == 0:
|
cast[cint](kind)) == 0:
|
||||||
err(EcKeyGenError)
|
err(EcKeyGenError)
|
||||||
|
@ -250,12 +250,12 @@ proc getPublicKey*(seckey: EcPrivateKey): EcResult[EcPublicKey] =
|
||||||
if isNil(seckey):
|
if isNil(seckey):
|
||||||
return err(EcKeyIncorrectError)
|
return err(EcKeyIncorrectError)
|
||||||
|
|
||||||
var ecimp = brEcGetDefault()
|
var ecimp = ecGetDefault()
|
||||||
if seckey.key.curve in EcSupportedCurvesCint:
|
if seckey.key.curve in EcSupportedCurvesCint:
|
||||||
var res = new EcPublicKey
|
var res = new EcPublicKey
|
||||||
assert res.buffer.len > getPublicKeyLength(cast[EcCurveKind](seckey.key.curve))
|
assert res.buffer.len > getPublicKeyLength(cast[EcCurveKind](seckey.key.curve))
|
||||||
if brEcComputePublicKey(ecimp, addr res.key,
|
if ecComputePub(ecimp, addr res.key,
|
||||||
addr res.buffer[0], unsafeAddr seckey.key) == 0:
|
addr res.buffer[0], unsafeAddr seckey.key) == 0:
|
||||||
err(EcKeyIncorrectError)
|
err(EcKeyIncorrectError)
|
||||||
else:
|
else:
|
||||||
ok(res)
|
ok(res)
|
||||||
|
@ -264,7 +264,7 @@ proc getPublicKey*(seckey: EcPrivateKey): EcResult[EcPublicKey] =
|
||||||
|
|
||||||
proc random*(
|
proc random*(
|
||||||
T: typedesc[EcKeyPair], kind: EcCurveKind,
|
T: typedesc[EcKeyPair], kind: EcCurveKind,
|
||||||
rng: var BrHmacDrbgContext): EcResult[T] =
|
rng: var HmacDrbgContext): 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.
|
||||||
##
|
##
|
||||||
|
@ -373,24 +373,24 @@ proc toBytes*(seckey: EcPrivateKey, data: var openArray[byte]): EcResult[int] =
|
||||||
var p = Asn1Composite.init(Asn1Tag.Sequence)
|
var p = Asn1Composite.init(Asn1Tag.Sequence)
|
||||||
var c0 = Asn1Composite.init(0)
|
var c0 = Asn1Composite.init(0)
|
||||||
var c1 = Asn1Composite.init(1)
|
var c1 = Asn1Composite.init(1)
|
||||||
if seckey.key.curve == BR_EC_SECP256R1:
|
if seckey.key.curve == EC_SECP256R1:
|
||||||
c0.write(Asn1Tag.Oid, Asn1OidSecp256r1)
|
c0.write(Asn1Tag.Oid, Asn1OidSecp256r1)
|
||||||
elif seckey.key.curve == BR_EC_SECP384R1:
|
elif seckey.key.curve == EC_SECP384R1:
|
||||||
c0.write(Asn1Tag.Oid, Asn1OidSecp384r1)
|
c0.write(Asn1Tag.Oid, Asn1OidSecp384r1)
|
||||||
elif seckey.key.curve == BR_EC_SECP521R1:
|
elif seckey.key.curve == EC_SECP521R1:
|
||||||
c0.write(Asn1Tag.Oid, Asn1OidSecp521r1)
|
c0.write(Asn1Tag.Oid, Asn1OidSecp521r1)
|
||||||
c0.finish()
|
c0.finish()
|
||||||
offset = pubkey.getOffset()
|
offset = pubkey.getOffset()
|
||||||
if offset < 0:
|
if offset < 0:
|
||||||
return err(EcKeyIncorrectError)
|
return err(EcKeyIncorrectError)
|
||||||
length = pubkey.key.qlen
|
length = int(pubkey.key.qlen)
|
||||||
c1.write(Asn1Tag.BitString,
|
c1.write(Asn1Tag.BitString,
|
||||||
pubkey.buffer.toOpenArray(offset, offset + length - 1))
|
pubkey.buffer.toOpenArray(offset, offset + length - 1))
|
||||||
c1.finish()
|
c1.finish()
|
||||||
offset = seckey.getOffset()
|
offset = seckey.getOffset()
|
||||||
if offset < 0:
|
if offset < 0:
|
||||||
return err(EcKeyIncorrectError)
|
return err(EcKeyIncorrectError)
|
||||||
length = seckey.key.xlen
|
length = int(seckey.key.xlen)
|
||||||
p.write(1'u64)
|
p.write(1'u64)
|
||||||
p.write(Asn1Tag.OctetString,
|
p.write(Asn1Tag.OctetString,
|
||||||
seckey.buffer.toOpenArray(offset, offset + length - 1))
|
seckey.buffer.toOpenArray(offset, offset + length - 1))
|
||||||
|
@ -421,18 +421,18 @@ proc toBytes*(pubkey: EcPublicKey, data: var openArray[byte]): EcResult[int] =
|
||||||
var p = Asn1Composite.init(Asn1Tag.Sequence)
|
var p = Asn1Composite.init(Asn1Tag.Sequence)
|
||||||
var c = Asn1Composite.init(Asn1Tag.Sequence)
|
var c = Asn1Composite.init(Asn1Tag.Sequence)
|
||||||
c.write(Asn1Tag.Oid, Asn1OidEcPublicKey)
|
c.write(Asn1Tag.Oid, Asn1OidEcPublicKey)
|
||||||
if pubkey.key.curve == BR_EC_SECP256R1:
|
if pubkey.key.curve == EC_SECP256R1:
|
||||||
c.write(Asn1Tag.Oid, Asn1OidSecp256r1)
|
c.write(Asn1Tag.Oid, Asn1OidSecp256r1)
|
||||||
elif pubkey.key.curve == BR_EC_SECP384R1:
|
elif pubkey.key.curve == EC_SECP384R1:
|
||||||
c.write(Asn1Tag.Oid, Asn1OidSecp384r1)
|
c.write(Asn1Tag.Oid, Asn1OidSecp384r1)
|
||||||
elif pubkey.key.curve == BR_EC_SECP521R1:
|
elif pubkey.key.curve == EC_SECP521R1:
|
||||||
c.write(Asn1Tag.Oid, Asn1OidSecp521r1)
|
c.write(Asn1Tag.Oid, Asn1OidSecp521r1)
|
||||||
c.finish()
|
c.finish()
|
||||||
p.write(c)
|
p.write(c)
|
||||||
let offset = getOffset(pubkey)
|
let offset = getOffset(pubkey)
|
||||||
if offset < 0:
|
if offset < 0:
|
||||||
return err(EcKeyIncorrectError)
|
return err(EcKeyIncorrectError)
|
||||||
let length = pubkey.key.qlen
|
let length = int(pubkey.key.qlen)
|
||||||
p.write(Asn1Tag.BitString,
|
p.write(Asn1Tag.BitString,
|
||||||
pubkey.buffer.toOpenArray(offset, offset + length - 1))
|
pubkey.buffer.toOpenArray(offset, offset + length - 1))
|
||||||
p.finish()
|
p.finish()
|
||||||
|
@ -638,8 +638,8 @@ proc init*(key: var EcPrivateKey, data: openArray[byte]): Result[void, Asn1Error
|
||||||
if checkScalar(raw.toOpenArray(), curve) == 1'u32:
|
if checkScalar(raw.toOpenArray(), curve) == 1'u32:
|
||||||
key = new EcPrivateKey
|
key = new EcPrivateKey
|
||||||
copyMem(addr key.buffer[0], addr raw.buffer[raw.offset], raw.length)
|
copyMem(addr key.buffer[0], addr raw.buffer[raw.offset], raw.length)
|
||||||
key.key.x = cast[ptr char](addr key.buffer[0])
|
key.key.x = addr key.buffer[0]
|
||||||
key.key.xlen = raw.length
|
key.key.xlen = uint(raw.length)
|
||||||
key.key.curve = curve
|
key.key.curve = curve
|
||||||
ok()
|
ok()
|
||||||
else:
|
else:
|
||||||
|
@ -697,8 +697,8 @@ proc init*(pubkey: var EcPublicKey, data: openArray[byte]): Result[void, Asn1Err
|
||||||
if checkPublic(raw.toOpenArray(), curve) != 0:
|
if checkPublic(raw.toOpenArray(), curve) != 0:
|
||||||
pubkey = new EcPublicKey
|
pubkey = new EcPublicKey
|
||||||
copyMem(addr pubkey.buffer[0], addr raw.buffer[raw.offset], raw.length)
|
copyMem(addr pubkey.buffer[0], addr raw.buffer[raw.offset], raw.length)
|
||||||
pubkey.key.q = cast[ptr char](addr pubkey.buffer[0])
|
pubkey.key.q = addr pubkey.buffer[0]
|
||||||
pubkey.key.qlen = raw.length
|
pubkey.key.qlen = uint(raw.length)
|
||||||
pubkey.key.curve = curve
|
pubkey.key.curve = curve
|
||||||
ok()
|
ok()
|
||||||
else:
|
else:
|
||||||
|
@ -785,8 +785,8 @@ proc initRaw*(key: var EcPrivateKey, data: openArray[byte]): bool =
|
||||||
let length = len(data)
|
let length = len(data)
|
||||||
key = new EcPrivateKey
|
key = new EcPrivateKey
|
||||||
copyMem(addr key.buffer[0], unsafeAddr data[0], length)
|
copyMem(addr key.buffer[0], unsafeAddr data[0], length)
|
||||||
key.key.x = cast[ptr char](addr key.buffer[0])
|
key.key.x = addr key.buffer[0]
|
||||||
key.key.xlen = length
|
key.key.xlen = uint(length)
|
||||||
key.key.curve = curve
|
key.key.curve = curve
|
||||||
result = true
|
result = true
|
||||||
|
|
||||||
|
@ -816,8 +816,8 @@ proc initRaw*(pubkey: var EcPublicKey, data: openArray[byte]): bool =
|
||||||
let length = len(data)
|
let length = len(data)
|
||||||
pubkey = new EcPublicKey
|
pubkey = new EcPublicKey
|
||||||
copyMem(addr pubkey.buffer[0], unsafeAddr data[0], length)
|
copyMem(addr pubkey.buffer[0], unsafeAddr data[0], length)
|
||||||
pubkey.key.q = cast[ptr char](addr pubkey.buffer[0])
|
pubkey.key.q = addr pubkey.buffer[0]
|
||||||
pubkey.key.qlen = length
|
pubkey.key.qlen = uint(length)
|
||||||
pubkey.key.curve = curve
|
pubkey.key.curve = curve
|
||||||
result = true
|
result = true
|
||||||
|
|
||||||
|
@ -883,7 +883,7 @@ proc scalarMul*(pub: EcPublicKey, sec: EcPrivateKey): EcPublicKey =
|
||||||
##
|
##
|
||||||
## Returns point in curve as ``pub * sec`` or ``nil`` otherwise.
|
## Returns point in curve as ``pub * sec`` or ``nil`` otherwise.
|
||||||
doAssert((not isNil(pub)) and (not isNil(sec)))
|
doAssert((not isNil(pub)) and (not isNil(sec)))
|
||||||
var impl = brEcGetDefault()
|
var impl = ecGetDefault()
|
||||||
if sec.key.curve in EcSupportedCurvesCint:
|
if sec.key.curve in EcSupportedCurvesCint:
|
||||||
if pub.key.curve == sec.key.curve:
|
if pub.key.curve == sec.key.curve:
|
||||||
var key = new EcPublicKey
|
var key = new EcPublicKey
|
||||||
|
@ -891,9 +891,9 @@ proc scalarMul*(pub: EcPublicKey, sec: EcPrivateKey): EcPublicKey =
|
||||||
let poffset = key.getOffset()
|
let poffset = key.getOffset()
|
||||||
let soffset = sec.getOffset()
|
let soffset = sec.getOffset()
|
||||||
if poffset >= 0 and soffset >= 0:
|
if poffset >= 0 and soffset >= 0:
|
||||||
let res = impl.mul(cast[ptr char](addr key.buffer[poffset]),
|
let res = impl.mul(addr key.buffer[poffset],
|
||||||
key.key.qlen,
|
key.key.qlen,
|
||||||
cast[ptr char](unsafeAddr sec.buffer[soffset]),
|
unsafeAddr sec.buffer[soffset],
|
||||||
sec.key.xlen,
|
sec.key.xlen,
|
||||||
key.key.curve)
|
key.key.curve)
|
||||||
if res != 0:
|
if res != 0:
|
||||||
|
@ -913,11 +913,11 @@ proc toSecret*(pubkey: EcPublicKey, seckey: EcPrivateKey,
|
||||||
doAssert((not isNil(pubkey)) and (not isNil(seckey)))
|
doAssert((not isNil(pubkey)) and (not isNil(seckey)))
|
||||||
var mult = scalarMul(pubkey, seckey)
|
var mult = scalarMul(pubkey, seckey)
|
||||||
if not isNil(mult):
|
if not isNil(mult):
|
||||||
if seckey.key.curve == BR_EC_SECP256R1:
|
if seckey.key.curve == EC_SECP256R1:
|
||||||
result = Secret256Length
|
result = Secret256Length
|
||||||
elif seckey.key.curve == BR_EC_SECP384R1:
|
elif seckey.key.curve == EC_SECP384R1:
|
||||||
result = Secret384Length
|
result = Secret384Length
|
||||||
elif seckey.key.curve == BR_EC_SECP521R1:
|
elif seckey.key.curve == EC_SECP521R1:
|
||||||
result = Secret521Length
|
result = Secret521Length
|
||||||
if len(data) >= result:
|
if len(data) >= result:
|
||||||
var qplus1 = cast[pointer](cast[uint](mult.key.q) + 1'u)
|
var qplus1 = cast[pointer](cast[uint](mult.key.q) + 1'u)
|
||||||
|
@ -941,20 +941,20 @@ proc sign*[T: byte|char](seckey: EcPrivateKey,
|
||||||
## Get ECDSA signature of data ``message`` using private key ``seckey``.
|
## Get ECDSA signature of data ``message`` using private key ``seckey``.
|
||||||
if isNil(seckey):
|
if isNil(seckey):
|
||||||
return err(EcKeyIncorrectError)
|
return err(EcKeyIncorrectError)
|
||||||
var hc: BrHashCompatContext
|
var hc: HashCompatContext
|
||||||
var hash: array[32, byte]
|
var hash: array[32, byte]
|
||||||
var impl = brEcGetDefault()
|
var impl = ecGetDefault()
|
||||||
if seckey.key.curve in EcSupportedCurvesCint:
|
if seckey.key.curve in EcSupportedCurvesCint:
|
||||||
var sig = new EcSignature
|
var sig = new EcSignature
|
||||||
sig.buffer = newSeq[byte](256)
|
sig.buffer = newSeq[byte](256)
|
||||||
var kv = addr sha256Vtable
|
var kv = addr sha256Vtable
|
||||||
kv.init(addr hc.vtable)
|
kv.init(addr hc.vtable)
|
||||||
if len(message) > 0:
|
if len(message) > 0:
|
||||||
kv.update(addr hc.vtable, unsafeAddr message[0], len(message))
|
kv.update(addr hc.vtable, unsafeAddr message[0], uint(len(message)))
|
||||||
else:
|
else:
|
||||||
kv.update(addr hc.vtable, nil, 0)
|
kv.update(addr hc.vtable, nil, 0)
|
||||||
kv.output(addr hc.vtable, addr hash[0])
|
kv.out(addr hc.vtable, addr hash[0])
|
||||||
let res = brEcdsaSignAsn1(impl, kv, addr hash[0], addr seckey.key,
|
let res = ecdsaI31SignAsn1(impl, kv, addr hash[0], addr seckey.key,
|
||||||
addr sig.buffer[0])
|
addr sig.buffer[0])
|
||||||
# Clear context with initial value
|
# Clear context with initial value
|
||||||
kv.init(addr hc.vtable)
|
kv.init(addr hc.vtable)
|
||||||
|
@ -974,20 +974,20 @@ proc verify*[T: byte|char](sig: EcSignature, message: openArray[T],
|
||||||
## Return ``true`` if message verification succeeded, ``false`` if
|
## Return ``true`` if message verification succeeded, ``false`` if
|
||||||
## verification failed.
|
## verification failed.
|
||||||
doAssert((not isNil(sig)) and (not isNil(pubkey)))
|
doAssert((not isNil(sig)) and (not isNil(pubkey)))
|
||||||
var hc: BrHashCompatContext
|
var hc: HashCompatContext
|
||||||
var hash: array[32, byte]
|
var hash: array[32, byte]
|
||||||
var impl = brEcGetDefault()
|
var impl = ecGetDefault()
|
||||||
if pubkey.key.curve in EcSupportedCurvesCint:
|
if pubkey.key.curve in EcSupportedCurvesCint:
|
||||||
var kv = addr sha256Vtable
|
var kv = addr sha256Vtable
|
||||||
kv.init(addr hc.vtable)
|
kv.init(addr hc.vtable)
|
||||||
if len(message) > 0:
|
if len(message) > 0:
|
||||||
kv.update(addr hc.vtable, unsafeAddr message[0], len(message))
|
kv.update(addr hc.vtable, unsafeAddr message[0], uint(len(message)))
|
||||||
else:
|
else:
|
||||||
kv.update(addr hc.vtable, nil, 0)
|
kv.update(addr hc.vtable, nil, 0)
|
||||||
kv.output(addr hc.vtable, addr hash[0])
|
kv.out(addr hc.vtable, addr hash[0])
|
||||||
let res = brEcdsaVerifyAsn1(impl, addr hash[0], len(hash),
|
let res = ecdsaI31VrfyAsn1(impl, addr hash[0], uint(len(hash)),
|
||||||
unsafeAddr pubkey.key,
|
unsafeAddr pubkey.key,
|
||||||
addr sig.buffer[0], len(sig.buffer))
|
addr sig.buffer[0], uint(len(sig.buffer)))
|
||||||
# Clear context with initial value
|
# Clear context with initial value
|
||||||
kv.init(addr hc.vtable)
|
kv.init(addr hc.vtable)
|
||||||
result = (res == 1)
|
result = (res == 1)
|
||||||
|
|
|
@ -13,7 +13,8 @@
|
||||||
|
|
||||||
{.push raises: Defect.}
|
{.push raises: Defect.}
|
||||||
|
|
||||||
import constants, bearssl
|
import bearssl/rand
|
||||||
|
import constants
|
||||||
import nimcrypto/[hash, sha2]
|
import nimcrypto/[hash, sha2]
|
||||||
# We use `ncrutils` for constant-time hexadecimal encoding/decoding procedures.
|
# We use `ncrutils` for constant-time hexadecimal encoding/decoding procedures.
|
||||||
import nimcrypto/utils as ncrutils
|
import nimcrypto/utils as ncrutils
|
||||||
|
@ -21,7 +22,7 @@ import stew/[results, ctops]
|
||||||
export results
|
export results
|
||||||
|
|
||||||
# This workaround needed because of some bugs in Nim Static[T].
|
# This workaround needed because of some bugs in Nim Static[T].
|
||||||
export hash, sha2
|
export hash, sha2, rand
|
||||||
|
|
||||||
const
|
const
|
||||||
EdPrivateKeySize* = 64
|
EdPrivateKeySize* = 64
|
||||||
|
@ -1644,14 +1645,14 @@ 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], rng: var BrHmacDrbgContext): EdPrivateKey =
|
proc random*(t: typedesc[EdPrivateKey], rng: var HmacDrbgContext): EdPrivateKey =
|
||||||
## Generate new random ED25519 private key using the given random number generator
|
## 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
|
||||||
|
|
||||||
brHmacDrbgGenerate(addr rng, addr res.data[0], 32)
|
hmacDrbgGenerate(rng, res.data.toOpenArray(0, 31))
|
||||||
|
|
||||||
var hh = sha512.digest(res.data.toOpenArray(0, 31))
|
var hh = sha512.digest(res.data.toOpenArray(0, 31))
|
||||||
hh.data[0] = hh.data[0] and 0xF8'u8
|
hh.data[0] = hh.data[0] and 0xF8'u8
|
||||||
|
@ -1663,14 +1664,14 @@ proc random*(t: typedesc[EdPrivateKey], rng: var BrHmacDrbgContext): EdPrivateKe
|
||||||
|
|
||||||
res
|
res
|
||||||
|
|
||||||
proc random*(t: typedesc[EdKeyPair], rng: var BrHmacDrbgContext): EdKeyPair =
|
proc random*(t: typedesc[EdKeyPair], rng: var HmacDrbgContext): 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
|
||||||
|
|
||||||
brHmacDrbgGenerate(addr rng, addr res.seckey.data[0], 32)
|
hmacDrbgGenerate(rng, res.seckey.data.toOpenArray(0, 31))
|
||||||
|
|
||||||
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
|
||||||
|
|
|
@ -12,29 +12,22 @@
|
||||||
{.push raises: [Defect].}
|
{.push raises: [Defect].}
|
||||||
|
|
||||||
import nimcrypto
|
import nimcrypto
|
||||||
import bearssl
|
import bearssl/[kdf, rand, hash]
|
||||||
|
|
||||||
type
|
type HkdfResult*[len: static int] = array[len, byte]
|
||||||
BearHKDFContext {.importc: "br_hkdf_context", header: "bearssl_kdf.h".} = object
|
|
||||||
HKDFResult*[len: static int] = array[len, byte]
|
|
||||||
|
|
||||||
proc br_hkdf_init(ctx: ptr BearHKDFContext; hashClass: ptr HashClass; salt: pointer; len: csize_t) {.importc: "br_hkdf_init", header: "bearssl_kdf.h", raises: [].}
|
proc hkdf*[T: sha256; len: static int](_: type[T]; salt, ikm, info: openArray[byte]; outputs: var openArray[HkdfResult[len]]) =
|
||||||
proc br_hkdf_inject(ctx: ptr BearHKDFContext; ikm: pointer; len: csize_t) {.importc: "br_hkdf_inject", header: "bearssl_kdf.h", raises: [].}
|
|
||||||
proc br_hkdf_flip(ctx: ptr BearHKDFContext) {.importc: "br_hkdf_flip", header: "bearssl_kdf.h", raises: [].}
|
|
||||||
proc br_hkdf_produce(ctx: ptr BearHKDFContext; info: pointer; infoLen: csize_t; output: pointer; outputLen: csize_t) {.importc: "br_hkdf_produce", header: "bearssl_kdf.h", raises: [].}
|
|
||||||
|
|
||||||
proc hkdf*[T: sha256; len: static int](_: type[T]; salt, ikm, info: openArray[byte]; outputs: var openArray[HKDFResult[len]]) =
|
|
||||||
var
|
var
|
||||||
ctx: BearHKDFContext
|
ctx: HkdfContext
|
||||||
br_hkdf_init(
|
hkdfInit(
|
||||||
addr ctx, addr sha256Vtable,
|
ctx, addr sha256Vtable,
|
||||||
if salt.len > 0: unsafeAddr salt[0] else: nil, csize_t(salt.len))
|
if salt.len > 0: unsafeAddr salt[0] else: nil, csize_t(salt.len))
|
||||||
br_hkdf_inject(
|
hkdfInject(
|
||||||
addr ctx, if ikm.len > 0: unsafeAddr ikm[0] else: nil, csize_t(ikm.len))
|
ctx, if ikm.len > 0: unsafeAddr ikm[0] else: nil, csize_t(ikm.len))
|
||||||
br_hkdf_flip(addr ctx)
|
hkdfFlip(ctx)
|
||||||
for i in 0..outputs.high:
|
for i in 0..outputs.high:
|
||||||
br_hkdf_produce(
|
discard hkdfProduce(
|
||||||
addr ctx,
|
ctx,
|
||||||
if info.len > 0: unsafeAddr info[0]
|
if info.len > 0: unsafeAddr info[0]
|
||||||
else: nil, csize_t(info.len),
|
else: nil, csize_t(info.len),
|
||||||
addr outputs[i][0], csize_t(outputs[i].len))
|
addr outputs[i][0], csize_t(outputs[i].len))
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
## Copyright(C) 2018 Thomas Pornin <pornin@bolet.org>.
|
## Copyright(C) 2018 Thomas Pornin <pornin@bolet.org>.
|
||||||
|
|
||||||
{.push raises: Defect.}
|
{.push raises: Defect.}
|
||||||
import bearssl
|
import bearssl/[rsa, rand, hash]
|
||||||
import minasn1
|
import minasn1
|
||||||
import stew/[results, ctops]
|
import stew/[results, ctops]
|
||||||
# We use `ncrutils` for constant-time hexadecimal encoding/decoding procedures.
|
# We use `ncrutils` for constant-time hexadecimal encoding/decoding procedures.
|
||||||
|
@ -33,41 +33,41 @@ const
|
||||||
## Default RSA key size in bits.
|
## Default RSA key size in bits.
|
||||||
|
|
||||||
RsaOidSha1* = [
|
RsaOidSha1* = [
|
||||||
0x05'u8, 0x2B'u8, 0x0E'u8, 0x03'u8, 0x02'u8, 0x1A'u8
|
byte 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A
|
||||||
]
|
]
|
||||||
## RSA PKCS#1.5 SHA-1 hash object identifier.
|
## RSA PKCS#1.5 SHA-1 hash object identifier.
|
||||||
RsaOidSha224* = [
|
RsaOidSha224* = [
|
||||||
0x09'u8, 0x60'u8, 0x86'u8, 0x48'u8, 0x01'u8, 0x65'u8, 0x03'u8, 0x04'u8,
|
byte 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04,
|
||||||
0x02'u8, 0x04'u8
|
0x02, 0x04
|
||||||
]
|
]
|
||||||
## RSA PKCS#1.5 SHA-224 hash object identifier.
|
## RSA PKCS#1.5 SHA-224 hash object identifier.
|
||||||
RsaOidSha256* = [
|
RsaOidSha256* = [
|
||||||
0x09'u8, 0x60'u8, 0x86'u8, 0x48'u8, 0x01'u8, 0x65'u8, 0x03'u8, 0x04'u8,
|
byte 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04,
|
||||||
0x02'u8, 0x01'u8
|
0x02, 0x01
|
||||||
]
|
]
|
||||||
## RSA PKCS#1.5 SHA-256 hash object identifier.
|
## RSA PKCS#1.5 SHA-256 hash object identifier.
|
||||||
RsaOidSha384* = [
|
RsaOidSha384* = [
|
||||||
0x09'u8, 0x60'u8, 0x86'u8, 0x48'u8, 0x01'u8, 0x65'u8, 0x03'u8, 0x04'u8,
|
byte 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04,
|
||||||
0x02'u8, 0x02'u8
|
0x02, 0x02
|
||||||
]
|
]
|
||||||
## RSA PKCS#1.5 SHA-384 hash object identifier.
|
## RSA PKCS#1.5 SHA-384 hash object identifier.
|
||||||
RsaOidSha512* = [
|
RsaOidSha512* = [
|
||||||
0x09'u8, 0x60'u8, 0x86'u8, 0x48'u8, 0x01'u8, 0x65'u8, 0x03'u8, 0x04'u8,
|
byte 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04,
|
||||||
0x02'u8, 0x03'u8
|
0x02, 0x03
|
||||||
]
|
]
|
||||||
## RSA PKCS#1.5 SHA-512 hash object identifier.
|
## RSA PKCS#1.5 SHA-512 hash object identifier.
|
||||||
|
|
||||||
type
|
type
|
||||||
RsaPrivateKey* = ref object
|
RsaPrivateKey* = ref object
|
||||||
buffer*: seq[byte]
|
buffer*: seq[byte]
|
||||||
seck*: BrRsaPrivateKey
|
seck*: rsa.RsaPrivateKey
|
||||||
pubk*: BrRsaPublicKey
|
pubk*: rsa.RsaPublicKey
|
||||||
pexp*: ptr char
|
pexp*: ptr byte
|
||||||
pexplen*: int
|
pexplen*: uint
|
||||||
|
|
||||||
RsaPublicKey* = ref object
|
RsaPublicKey* = ref object
|
||||||
buffer*: seq[byte]
|
buffer*: seq[byte]
|
||||||
key*: BrRsaPublicKey
|
key*: rsa.RsaPublicKey
|
||||||
|
|
||||||
RsaKeyPair* = RsaPrivateKey
|
RsaKeyPair* = RsaPrivateKey
|
||||||
|
|
||||||
|
@ -99,8 +99,8 @@ template getFinish(bs, os, ls: untyped): untyped =
|
||||||
var eo = -1
|
var eo = -1
|
||||||
if p >= s:
|
if p >= s:
|
||||||
let so = cast[int](p - s)
|
let so = cast[int](p - s)
|
||||||
if so + ls <= len(bs):
|
if so + int(ls) <= len(bs):
|
||||||
eo = so + ls - 1
|
eo = so + int(ls) - 1
|
||||||
eo
|
eo
|
||||||
|
|
||||||
template getArray*(bs, os, ls: untyped): untyped =
|
template getArray*(bs, os, ls: untyped): untyped =
|
||||||
|
@ -109,12 +109,12 @@ template getArray*(bs, os, ls: untyped): untyped =
|
||||||
template trimZeroes(b: seq[byte], pt, ptlen: untyped) =
|
template trimZeroes(b: seq[byte], pt, ptlen: untyped) =
|
||||||
var length = ptlen
|
var length = ptlen
|
||||||
for i in 0..<length:
|
for i in 0..<length:
|
||||||
if pt[] != cast[char](0x00'u8):
|
if pt[] != byte(0x00):
|
||||||
break
|
break
|
||||||
pt = cast[ptr char](cast[uint](pt) + 1)
|
pt = cast[ptr byte](cast[uint](pt) + 1)
|
||||||
ptlen -= 1
|
ptlen -= 1
|
||||||
|
|
||||||
proc random*[T: RsaKP](t: typedesc[T], rng: var BrHmacDrbgContext,
|
proc random*[T: RsaKP](t: typedesc[T], rng: var HmacDrbgContext,
|
||||||
bits = DefaultKeySize,
|
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
|
||||||
|
@ -129,14 +129,14 @@ proc random*[T: RsaKP](t: typedesc[T], rng: var BrHmacDrbgContext,
|
||||||
|
|
||||||
let
|
let
|
||||||
sko = 0
|
sko = 0
|
||||||
pko = brRsaPrivateKeyBufferSize(bits)
|
pko = rsaKbufPrivSize(bits)
|
||||||
eko = pko + brRsaPublicKeyBufferSize(bits)
|
eko = pko + rsaKbufPubSize(bits)
|
||||||
length = eko + ((bits + 7) shr 3)
|
length = eko + ((bits + 7) shr 3)
|
||||||
|
|
||||||
let res = new T
|
let res = new T
|
||||||
res.buffer = newSeq[byte](length)
|
res.buffer = newSeq[byte](length)
|
||||||
|
|
||||||
var keygen = brRsaKeygenGetDefault()
|
var keygen = rsaKeygenGetDefault()
|
||||||
|
|
||||||
if keygen(addr rng.vtable,
|
if keygen(addr rng.vtable,
|
||||||
addr res.seck, addr res.buffer[sko],
|
addr res.seck, addr res.buffer[sko],
|
||||||
|
@ -145,12 +145,12 @@ proc random*[T: RsaKP](t: typedesc[T], rng: var BrHmacDrbgContext,
|
||||||
return err(RsaGenError)
|
return err(RsaGenError)
|
||||||
|
|
||||||
let
|
let
|
||||||
compute = brRsaComputePrivexpGetDefault()
|
compute = rsaComputePrivexpGetDefault()
|
||||||
computed = compute(addr res.buffer[eko], addr res.seck, pubexp)
|
computed = compute(addr res.buffer[eko], addr res.seck, pubexp)
|
||||||
if computed == 0:
|
if computed == 0:
|
||||||
return err(RsaGenError)
|
return err(RsaGenError)
|
||||||
|
|
||||||
res.pexp = cast[ptr char](addr res.buffer[eko])
|
res.pexp = addr res.buffer[eko]
|
||||||
res.pexplen = computed
|
res.pexplen = computed
|
||||||
|
|
||||||
trimZeroes(res.buffer, res.seck.p, res.seck.plen)
|
trimZeroes(res.buffer, res.seck.p, res.seck.plen)
|
||||||
|
@ -169,12 +169,12 @@ proc copy*[T: RsaPKI](key: T): T =
|
||||||
doAssert(not isNil(key))
|
doAssert(not isNil(key))
|
||||||
when T is RsaPrivateKey:
|
when T is RsaPrivateKey:
|
||||||
if len(key.buffer) > 0:
|
if len(key.buffer) > 0:
|
||||||
let length = key.seck.plen + key.seck.qlen + key.seck.dplen +
|
let length = key.seck.plen.uint + key.seck.qlen.uint + key.seck.dplen.uint +
|
||||||
key.seck.dqlen + key.seck.iqlen + key.pubk.nlen +
|
key.seck.dqlen.uint + key.seck.iqlen.uint + key.pubk.nlen.uint +
|
||||||
key.pubk.elen + key.pexplen
|
key.pubk.elen.uint + key.pexplen.uint
|
||||||
result = new RsaPrivateKey
|
result = new RsaPrivateKey
|
||||||
result.buffer = newSeq[byte](length)
|
result.buffer = newSeq[byte](length)
|
||||||
let po = 0
|
let po: uint = 0
|
||||||
let qo = po + key.seck.plen
|
let qo = po + key.seck.plen
|
||||||
let dpo = qo + key.seck.qlen
|
let dpo = qo + key.seck.qlen
|
||||||
let dqo = dpo + key.seck.dplen
|
let dqo = dpo + key.seck.dplen
|
||||||
|
@ -190,14 +190,14 @@ proc copy*[T: RsaPKI](key: T): T =
|
||||||
copyMem(addr result.buffer[no], key.pubk.n, key.pubk.nlen)
|
copyMem(addr result.buffer[no], key.pubk.n, key.pubk.nlen)
|
||||||
copyMem(addr result.buffer[eo], key.pubk.e, key.pubk.elen)
|
copyMem(addr result.buffer[eo], key.pubk.e, key.pubk.elen)
|
||||||
copyMem(addr result.buffer[peo], key.pexp, key.pexplen)
|
copyMem(addr result.buffer[peo], key.pexp, key.pexplen)
|
||||||
result.seck.p = cast[ptr char](addr result.buffer[po])
|
result.seck.p = addr result.buffer[po]
|
||||||
result.seck.q = cast[ptr char](addr result.buffer[qo])
|
result.seck.q = addr result.buffer[qo]
|
||||||
result.seck.dp = cast[ptr char](addr result.buffer[dpo])
|
result.seck.dp = addr result.buffer[dpo]
|
||||||
result.seck.dq = cast[ptr char](addr result.buffer[dqo])
|
result.seck.dq = addr result.buffer[dqo]
|
||||||
result.seck.iq = cast[ptr char](addr result.buffer[iqo])
|
result.seck.iq = addr result.buffer[iqo]
|
||||||
result.pubk.n = cast[ptr char](addr result.buffer[no])
|
result.pubk.n = addr result.buffer[no]
|
||||||
result.pubk.e = cast[ptr char](addr result.buffer[eo])
|
result.pubk.e = addr result.buffer[eo]
|
||||||
result.pexp = cast[ptr char](addr result.buffer[peo])
|
result.pexp = addr result.buffer[peo]
|
||||||
result.seck.plen = key.seck.plen
|
result.seck.plen = key.seck.plen
|
||||||
result.seck.qlen = key.seck.qlen
|
result.seck.qlen = key.seck.qlen
|
||||||
result.seck.dplen = key.seck.dplen
|
result.seck.dplen = key.seck.dplen
|
||||||
|
@ -231,8 +231,8 @@ proc getPublicKey*(key: RsaPrivateKey): RsaPublicKey =
|
||||||
let length = key.pubk.nlen + key.pubk.elen
|
let length = key.pubk.nlen + key.pubk.elen
|
||||||
result = new RsaPublicKey
|
result = new RsaPublicKey
|
||||||
result.buffer = newSeq[byte](length)
|
result.buffer = newSeq[byte](length)
|
||||||
result.key.n = cast[ptr char](addr result.buffer[0])
|
result.key.n = addr result.buffer[0]
|
||||||
result.key.e = cast[ptr char](addr result.buffer[key.pubk.nlen])
|
result.key.e = addr result.buffer[key.pubk.nlen]
|
||||||
copyMem(addr result.buffer[0], cast[pointer](key.pubk.n), key.pubk.nlen)
|
copyMem(addr result.buffer[0], cast[pointer](key.pubk.n), key.pubk.nlen)
|
||||||
copyMem(addr result.buffer[key.pubk.nlen], cast[pointer](key.pubk.e),
|
copyMem(addr result.buffer[key.pubk.nlen], cast[pointer](key.pubk.e),
|
||||||
key.pubk.elen)
|
key.pubk.elen)
|
||||||
|
@ -472,22 +472,22 @@ proc init*(key: var RsaPrivateKey, data: openArray[byte]): Result[void, Asn1Erro
|
||||||
len(rawdp) > 0 and len(rawdq) > 0 and len(rawiq) > 0:
|
len(rawdp) > 0 and len(rawdq) > 0 and len(rawiq) > 0:
|
||||||
key = new RsaPrivateKey
|
key = new RsaPrivateKey
|
||||||
key.buffer = @data
|
key.buffer = @data
|
||||||
key.pubk.n = cast[ptr char](addr key.buffer[rawn.offset])
|
key.pubk.n = addr key.buffer[rawn.offset]
|
||||||
key.pubk.e = cast[ptr char](addr key.buffer[rawpube.offset])
|
key.pubk.e = addr key.buffer[rawpube.offset]
|
||||||
key.seck.p = cast[ptr char](addr key.buffer[rawp.offset])
|
key.seck.p = addr key.buffer[rawp.offset]
|
||||||
key.seck.q = cast[ptr char](addr key.buffer[rawq.offset])
|
key.seck.q = addr key.buffer[rawq.offset]
|
||||||
key.seck.dp = cast[ptr char](addr key.buffer[rawdp.offset])
|
key.seck.dp = addr key.buffer[rawdp.offset]
|
||||||
key.seck.dq = cast[ptr char](addr key.buffer[rawdq.offset])
|
key.seck.dq = addr key.buffer[rawdq.offset]
|
||||||
key.seck.iq = cast[ptr char](addr key.buffer[rawiq.offset])
|
key.seck.iq = addr key.buffer[rawiq.offset]
|
||||||
key.pexp = cast[ptr char](addr key.buffer[rawprie.offset])
|
key.pexp = addr key.buffer[rawprie.offset]
|
||||||
key.pubk.nlen = len(rawn)
|
key.pubk.nlen = uint(len(rawn))
|
||||||
key.pubk.elen = len(rawpube)
|
key.pubk.elen = uint(len(rawpube))
|
||||||
key.seck.plen = len(rawp)
|
key.seck.plen = uint(len(rawp))
|
||||||
key.seck.qlen = len(rawq)
|
key.seck.qlen = uint(len(rawq))
|
||||||
key.seck.dplen = len(rawdp)
|
key.seck.dplen = uint(len(rawdp))
|
||||||
key.seck.dqlen = len(rawdq)
|
key.seck.dqlen = uint(len(rawdq))
|
||||||
key.seck.iqlen = len(rawiq)
|
key.seck.iqlen = uint(len(rawiq))
|
||||||
key.pexplen = len(rawprie)
|
key.pexplen = uint(len(rawprie))
|
||||||
key.seck.nBitlen = cast[uint32](len(rawn) shl 3)
|
key.seck.nBitlen = cast[uint32](len(rawn) shl 3)
|
||||||
ok()
|
ok()
|
||||||
else:
|
else:
|
||||||
|
@ -554,10 +554,10 @@ proc init*(key: var RsaPublicKey, data: openArray[byte]): Result[void, Asn1Error
|
||||||
if len(rawn) >= (MinKeySize shr 3) and len(rawe) > 0:
|
if len(rawn) >= (MinKeySize shr 3) and len(rawe) > 0:
|
||||||
key = new RsaPublicKey
|
key = new RsaPublicKey
|
||||||
key.buffer = @data
|
key.buffer = @data
|
||||||
key.key.n = cast[ptr char](addr key.buffer[rawn.offset])
|
key.key.n = addr key.buffer[rawn.offset]
|
||||||
key.key.e = cast[ptr char](addr key.buffer[rawe.offset])
|
key.key.e = addr key.buffer[rawe.offset]
|
||||||
key.key.nlen = len(rawn)
|
key.key.nlen = uint(len(rawn))
|
||||||
key.key.elen = len(rawe)
|
key.key.elen = uint(len(rawe))
|
||||||
ok()
|
ok()
|
||||||
else:
|
else:
|
||||||
err(Asn1Error.Incorrect)
|
err(Asn1Error.Incorrect)
|
||||||
|
@ -749,22 +749,22 @@ proc sign*[T: byte|char](key: RsaPrivateKey,
|
||||||
if isNil(key):
|
if isNil(key):
|
||||||
return err(RsaKeyIncorrectError)
|
return err(RsaKeyIncorrectError)
|
||||||
|
|
||||||
var hc: BrHashCompatContext
|
var hc: HashCompatContext
|
||||||
var hash: array[32, byte]
|
var hash: array[32, byte]
|
||||||
let impl = BrRsaPkcs1SignGetDefault()
|
let impl = rsaPkcs1SignGetDefault()
|
||||||
var res = new RsaSignature
|
var res = new RsaSignature
|
||||||
res.buffer = newSeq[byte]((key.seck.nBitlen + 7) shr 3)
|
res.buffer = newSeq[byte]((key.seck.nBitlen + 7) shr 3)
|
||||||
var kv = addr sha256Vtable
|
var kv = addr sha256Vtable
|
||||||
kv.init(addr hc.vtable)
|
kv.init(addr hc.vtable)
|
||||||
if len(message) > 0:
|
if len(message) > 0:
|
||||||
kv.update(addr hc.vtable, unsafeAddr message[0], len(message))
|
kv.update(addr hc.vtable, unsafeAddr message[0], uint(len(message)))
|
||||||
else:
|
else:
|
||||||
kv.update(addr hc.vtable, nil, 0)
|
kv.update(addr hc.vtable, nil, 0)
|
||||||
kv.output(addr hc.vtable, addr hash[0])
|
kv.out(addr hc.vtable, addr hash[0])
|
||||||
var oid = RsaOidSha256
|
var oid = RsaOidSha256
|
||||||
let implRes = impl(cast[ptr char](addr oid[0]),
|
let implRes = impl(addr oid[0],
|
||||||
cast[ptr char](addr hash[0]), len(hash),
|
addr hash[0], uint(len(hash)),
|
||||||
addr key.seck, cast[ptr char](addr res.buffer[0]))
|
addr key.seck, addr res.buffer[0])
|
||||||
if implRes == 0:
|
if implRes == 0:
|
||||||
err(RsaSignatureError)
|
err(RsaSignatureError)
|
||||||
else:
|
else:
|
||||||
|
@ -779,20 +779,20 @@ proc verify*[T: byte|char](sig: RsaSignature, message: openArray[T],
|
||||||
## verification failed.
|
## verification failed.
|
||||||
doAssert((not isNil(sig)) and (not isNil(pubkey)))
|
doAssert((not isNil(sig)) and (not isNil(pubkey)))
|
||||||
if len(sig.buffer) > 0:
|
if len(sig.buffer) > 0:
|
||||||
var hc: BrHashCompatContext
|
var hc: HashCompatContext
|
||||||
var hash: array[32, byte]
|
var hash: array[32, byte]
|
||||||
var check: array[32, byte]
|
var check: array[32, byte]
|
||||||
var impl = BrRsaPkcs1VrfyGetDefault()
|
var impl = rsaPkcs1VrfyGetDefault()
|
||||||
var kv = addr sha256Vtable
|
var kv = addr sha256Vtable
|
||||||
kv.init(addr hc.vtable)
|
kv.init(addr hc.vtable)
|
||||||
if len(message) > 0:
|
if len(message) > 0:
|
||||||
kv.update(addr hc.vtable, unsafeAddr message[0], len(message))
|
kv.update(addr hc.vtable, unsafeAddr message[0], uint(len(message)))
|
||||||
else:
|
else:
|
||||||
kv.update(addr hc.vtable, nil, 0)
|
kv.update(addr hc.vtable, nil, 0)
|
||||||
kv.output(addr hc.vtable, addr hash[0])
|
kv.out(addr hc.vtable, addr hash[0])
|
||||||
var oid = RsaOidSha256
|
var oid = RsaOidSha256
|
||||||
let res = impl(cast[ptr char](addr sig.buffer[0]), len(sig.buffer),
|
let res = impl(addr sig.buffer[0], uint(len(sig.buffer)),
|
||||||
cast[ptr char](addr oid[0]),
|
addr oid[0],
|
||||||
len(check), addr pubkey.key, cast[ptr char](addr check[0]))
|
uint(len(check)), addr pubkey.key, addr check[0])
|
||||||
if res == 1:
|
if res == 1:
|
||||||
result = equalMem(addr check[0], addr hash[0], len(hash))
|
result = equalMem(addr check[0], addr hash[0], len(hash))
|
||||||
|
|
|
@ -9,12 +9,13 @@
|
||||||
|
|
||||||
{.push raises: [Defect].}
|
{.push raises: [Defect].}
|
||||||
|
|
||||||
|
import bearssl/rand
|
||||||
import
|
import
|
||||||
secp256k1, bearssl,
|
secp256k1,
|
||||||
stew/[byteutils, results],
|
stew/[byteutils, results],
|
||||||
nimcrypto/[hash, sha2]
|
nimcrypto/[hash, sha2]
|
||||||
|
|
||||||
export sha2, results
|
export sha2, results, rand
|
||||||
|
|
||||||
const
|
const
|
||||||
SkRawPrivateKeySize* = 256 div 8
|
SkRawPrivateKeySize* = 256 div 8
|
||||||
|
@ -34,17 +35,18 @@ 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], rng: var BrHmacDrbgContext): SkPrivateKey =
|
proc random*(t: typedesc[SkPrivateKey], rng: var HmacDrbgContext): SkPrivateKey =
|
||||||
let rngPtr = unsafeAddr rng # doesn't escape
|
#TODO is there a better way?
|
||||||
|
var rngPtr = addr rng
|
||||||
proc callRng(data: var openArray[byte]) =
|
proc callRng(data: var openArray[byte]) =
|
||||||
brHmacDrbgGenerate(rngPtr[], data)
|
hmacDrbgGenerate(rngPtr[], data)
|
||||||
|
|
||||||
SkPrivateKey(SkSecretKey.random(callRng))
|
SkPrivateKey(SkSecretKey.random(callRng))
|
||||||
|
|
||||||
proc random*(t: typedesc[SkKeyPair], rng: var BrHmacDrbgContext): SkKeyPair =
|
proc random*(t: typedesc[SkKeyPair], rng: var HmacDrbgContext): SkKeyPair =
|
||||||
let rngPtr = unsafeAddr rng # doesn't escape
|
let rngPtr = addr rng
|
||||||
proc callRng(data: var openArray[byte]) =
|
proc callRng(data: var openArray[byte]) =
|
||||||
brHmacDrbgGenerate(rngPtr[], data)
|
hmacDrbgGenerate(rngPtr[], data)
|
||||||
|
|
||||||
SkKeyPair(secp256k1.SkKeyPair.random(callRng))
|
SkKeyPair(secp256k1.SkKeyPair.random(callRng))
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,8 @@
|
||||||
|
|
||||||
{.push raises: [Defect].}
|
{.push raises: [Defect].}
|
||||||
|
|
||||||
import chronos, chronicles, bearssl
|
import chronos, chronicles
|
||||||
|
import bearssl/[rand, hash]
|
||||||
import ../protobuf/minprotobuf,
|
import ../protobuf/minprotobuf,
|
||||||
../peerinfo,
|
../peerinfo,
|
||||||
../stream/connection,
|
../stream/connection,
|
||||||
|
@ -19,6 +20,8 @@ import ../protobuf/minprotobuf,
|
||||||
../protocols/protocol,
|
../protocols/protocol,
|
||||||
../errors
|
../errors
|
||||||
|
|
||||||
|
export chronicles, rand, connection
|
||||||
|
|
||||||
logScope:
|
logScope:
|
||||||
topics = "libp2p ping"
|
topics = "libp2p ping"
|
||||||
|
|
||||||
|
@ -37,9 +40,9 @@ type
|
||||||
|
|
||||||
Ping* = ref object of LPProtocol
|
Ping* = ref object of LPProtocol
|
||||||
pingHandler*: PingHandler
|
pingHandler*: PingHandler
|
||||||
rng: ref BrHmacDrbgContext
|
rng: ref HmacDrbgContext
|
||||||
|
|
||||||
proc new*(T: typedesc[Ping], handler: PingHandler = nil, rng: ref BrHmacDrbgContext = newRng()): T =
|
proc new*(T: typedesc[Ping], handler: PingHandler = nil, rng: ref HmacDrbgContext = newRng()): T =
|
||||||
let ping = Ping(pinghandler: handler, rng: rng)
|
let ping = Ping(pinghandler: handler, rng: rng)
|
||||||
ping.init()
|
ping.init()
|
||||||
ping
|
ping
|
||||||
|
@ -76,7 +79,7 @@ proc ping*(
|
||||||
randomBuf: array[PingSize, byte]
|
randomBuf: array[PingSize, byte]
|
||||||
resultBuf: array[PingSize, byte]
|
resultBuf: array[PingSize, byte]
|
||||||
|
|
||||||
p.rng[].brHmacDrbgGenerate(randomBuf)
|
hmacDrbgGenerate(p.rng[], randomBuf)
|
||||||
|
|
||||||
let startTime = Moment.now()
|
let startTime = Moment.now()
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
{.push raises: [Defect].}
|
{.push raises: [Defect].}
|
||||||
|
|
||||||
import std/[sequtils, sets, hashes, tables]
|
import std/[sequtils, sets, hashes, tables]
|
||||||
import chronos, chronicles, metrics, bearssl
|
import chronos, chronicles, metrics
|
||||||
import ./pubsub,
|
import ./pubsub,
|
||||||
./pubsubpeer,
|
./pubsubpeer,
|
||||||
./timedcache,
|
./timedcache,
|
||||||
|
@ -226,6 +226,6 @@ method initPubSub*(f: FloodSub)
|
||||||
procCall PubSub(f).initPubSub()
|
procCall PubSub(f).initPubSub()
|
||||||
f.seen = TimedCache[MessageID].init(2.minutes)
|
f.seen = TimedCache[MessageID].init(2.minutes)
|
||||||
f.seenSalt = newSeqUninitialized[byte](sizeof(Hash))
|
f.seenSalt = newSeqUninitialized[byte](sizeof(Hash))
|
||||||
brHmacDrbgGenerate(f.rng[], f.seenSalt)
|
hmacDrbgGenerate(f.rng[], f.seenSalt)
|
||||||
|
|
||||||
f.init()
|
f.init()
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
{.push raises: [Defect].}
|
{.push raises: [Defect].}
|
||||||
|
|
||||||
import std/[tables, sequtils, sets, strutils]
|
import std/[tables, sequtils, sets, strutils]
|
||||||
import chronos, chronicles, metrics, bearssl
|
import chronos, chronicles, metrics
|
||||||
import ./errors as pubsub_errors,
|
import ./errors as pubsub_errors,
|
||||||
./pubsubpeer,
|
./pubsubpeer,
|
||||||
./rpc/[message, messages, protobuf],
|
./rpc/[message, messages, protobuf],
|
||||||
|
@ -114,7 +114,7 @@ type
|
||||||
## lead to issues, from descoring to connection drops
|
## lead to issues, from descoring to connection drops
|
||||||
##
|
##
|
||||||
## defaults to 1mB
|
## defaults to 1mB
|
||||||
rng*: ref BrHmacDrbgContext
|
rng*: ref HmacDrbgContext
|
||||||
|
|
||||||
knownTopics*: HashSet[string]
|
knownTopics*: HashSet[string]
|
||||||
|
|
||||||
|
@ -553,7 +553,7 @@ proc init*[PubParams: object | bool](
|
||||||
msgIdProvider: MsgIdProvider = defaultMsgIdProvider,
|
msgIdProvider: MsgIdProvider = defaultMsgIdProvider,
|
||||||
subscriptionValidator: SubscriptionValidator = nil,
|
subscriptionValidator: SubscriptionValidator = nil,
|
||||||
maxMessageSize: int = 1024 * 1024,
|
maxMessageSize: int = 1024 * 1024,
|
||||||
rng: ref BrHmacDrbgContext = newRng(),
|
rng: ref HmacDrbgContext = newRng(),
|
||||||
parameters: PubParams = false): P
|
parameters: PubParams = false): P
|
||||||
{.raises: [Defect, InitializationError].} =
|
{.raises: [Defect, InitializationError].} =
|
||||||
let pubsub =
|
let pubsub =
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
import std/[oids, strformat]
|
import std/[oids, strformat]
|
||||||
import chronos
|
import chronos
|
||||||
import chronicles
|
import chronicles
|
||||||
import bearssl
|
import bearssl/[rand, hash]
|
||||||
import stew/[endians2, byteutils]
|
import stew/[endians2, byteutils]
|
||||||
import nimcrypto/[utils, sha2, hmac]
|
import nimcrypto/[utils, sha2, hmac]
|
||||||
import ../../stream/[connection, streamseq]
|
import ../../stream/[connection, streamseq]
|
||||||
|
@ -78,7 +78,7 @@ type
|
||||||
rs: Curve25519Key
|
rs: Curve25519Key
|
||||||
|
|
||||||
Noise* = ref object of Secure
|
Noise* = ref object of Secure
|
||||||
rng: ref BrHmacDrbgContext
|
rng: ref HmacDrbgContext
|
||||||
localPrivateKey: PrivateKey
|
localPrivateKey: PrivateKey
|
||||||
localPublicKey: seq[byte]
|
localPublicKey: seq[byte]
|
||||||
noiseKeys: KeyPair
|
noiseKeys: KeyPair
|
||||||
|
@ -106,7 +106,7 @@ func shortLog*(conn: NoiseConnection): auto =
|
||||||
|
|
||||||
chronicles.formatIt(NoiseConnection): shortLog(it)
|
chronicles.formatIt(NoiseConnection): shortLog(it)
|
||||||
|
|
||||||
proc genKeyPair(rng: var BrHmacDrbgContext): KeyPair =
|
proc genKeyPair(rng: var HmacDrbgContext): KeyPair =
|
||||||
result.privateKey = Curve25519Key.random(rng)
|
result.privateKey = Curve25519Key.random(rng)
|
||||||
result.publicKey = result.privateKey.public()
|
result.publicKey = result.privateKey.public()
|
||||||
|
|
||||||
|
@ -602,7 +602,7 @@ method init*(p: Noise) {.gcsafe.} =
|
||||||
|
|
||||||
proc new*(
|
proc new*(
|
||||||
T: typedesc[Noise],
|
T: typedesc[Noise],
|
||||||
rng: ref BrHmacDrbgContext,
|
rng: ref HmacDrbgContext,
|
||||||
privateKey: PrivateKey,
|
privateKey: PrivateKey,
|
||||||
outgoing: bool = true,
|
outgoing: bool = true,
|
||||||
commonPrologue: seq[byte] = @[]): T =
|
commonPrologue: seq[byte] = @[]): T =
|
||||||
|
|
|
@ -10,7 +10,8 @@
|
||||||
{.push raises: [Defect].}
|
{.push raises: [Defect].}
|
||||||
|
|
||||||
import std/[oids, strformat]
|
import std/[oids, strformat]
|
||||||
import chronos, chronicles, stew/endians2, bearssl
|
import bearssl/rand
|
||||||
|
import chronos, chronicles, stew/endians2
|
||||||
import nimcrypto/[hmac, sha2, sha, hash, rijndael, twofish, bcmode]
|
import nimcrypto/[hmac, sha2, sha, hash, rijndael, twofish, bcmode]
|
||||||
import secure,
|
import secure,
|
||||||
../../stream/connection,
|
../../stream/connection,
|
||||||
|
@ -37,7 +38,7 @@ const
|
||||||
|
|
||||||
type
|
type
|
||||||
Secio* = ref object of Secure
|
Secio* = ref object of Secure
|
||||||
rng: ref BrHmacDrbgContext
|
rng: ref HmacDrbgContext
|
||||||
localPrivateKey: PrivateKey
|
localPrivateKey: PrivateKey
|
||||||
localPublicKey: PublicKey
|
localPublicKey: PublicKey
|
||||||
remotePublicKey: PublicKey
|
remotePublicKey: PublicKey
|
||||||
|
@ -304,7 +305,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()
|
||||||
|
|
||||||
brHmacDrbgGenerate(s.rng[], localNonce)
|
hmacDrbgGenerate(s.rng[], localNonce)
|
||||||
|
|
||||||
var request = createProposal(localNonce,
|
var request = createProposal(localNonce,
|
||||||
localBytesPubkey,
|
localBytesPubkey,
|
||||||
|
@ -428,7 +429,7 @@ method init(s: Secio) {.gcsafe.} =
|
||||||
|
|
||||||
proc new*(
|
proc new*(
|
||||||
T: typedesc[Secio],
|
T: typedesc[Secio],
|
||||||
rng: ref BrHmacDrbgContext,
|
rng: ref HmacDrbgContext,
|
||||||
localPrivateKey: PrivateKey): T =
|
localPrivateKey: PrivateKey): T =
|
||||||
let pkRes = localPrivateKey.getPublicKey()
|
let pkRes = localPrivateKey.getPublicKey()
|
||||||
if pkRes.isErr:
|
if pkRes.isErr:
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
{.push raises: [Defect].}
|
{.push raises: [Defect].}
|
||||||
|
|
||||||
import std/[strformat]
|
import std/[strformat]
|
||||||
import chronos, chronicles, bearssl
|
import chronos, chronicles
|
||||||
import ../protocol,
|
import ../protocol,
|
||||||
../../stream/streamseq,
|
../../stream/streamseq,
|
||||||
../../stream/connection,
|
../../stream/connection,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{.push raises: [Defect].}
|
{.push raises: [Defect].}
|
||||||
|
|
||||||
import chronos, bearssl
|
import chronos
|
||||||
|
|
||||||
import ../libp2p/transports/tcptransport
|
import ../libp2p/transports/tcptransport
|
||||||
import ../libp2p/stream/bufferstream
|
import ../libp2p/stream/bufferstream
|
||||||
|
@ -58,11 +58,11 @@ template checkTrackers*() =
|
||||||
except: discard
|
except: discard
|
||||||
|
|
||||||
type RngWrap = object
|
type RngWrap = object
|
||||||
rng: ref BrHmacDrbgContext
|
rng: ref HmacDrbgContext
|
||||||
|
|
||||||
var rngVar: RngWrap
|
var rngVar: RngWrap
|
||||||
|
|
||||||
proc getRng(): ref BrHmacDrbgContext =
|
proc getRng(): ref HmacDrbgContext =
|
||||||
# TODO if `rngVar` is a threadvar like it should be, there are random and
|
# 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
|
# 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
|
# purpose of the tests, it's ok as long as we only use a single thread
|
||||||
|
@ -71,7 +71,7 @@ proc getRng(): ref BrHmacDrbgContext =
|
||||||
rngVar.rng = newRng()
|
rngVar.rng = newRng()
|
||||||
rngVar.rng
|
rngVar.rng
|
||||||
|
|
||||||
template rng*(): ref BrHmacDrbgContext =
|
template rng*(): ref HmacDrbgContext =
|
||||||
getRng()
|
getRng()
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
|
@ -3,7 +3,6 @@ include ../../libp2p/protocols/pubsub/gossipsub
|
||||||
{.used.}
|
{.used.}
|
||||||
|
|
||||||
import options
|
import options
|
||||||
import bearssl
|
|
||||||
import stew/byteutils
|
import stew/byteutils
|
||||||
import ../../libp2p/builders
|
import ../../libp2p/builders
|
||||||
import ../../libp2p/errors
|
import ../../libp2p/errors
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{.used.}
|
{.used.}
|
||||||
|
|
||||||
import unittest2, options, sets, sequtils, bearssl
|
import unittest2, options, sets, sequtils
|
||||||
import stew/byteutils
|
import stew/byteutils
|
||||||
import ../../libp2p/[peerid,
|
import ../../libp2p/[peerid,
|
||||||
crypto/crypto,
|
crypto/crypto,
|
||||||
|
|
|
@ -10,9 +10,9 @@
|
||||||
## Test vectors was made using Go implementation
|
## Test vectors was made using Go implementation
|
||||||
## https://github.com/libp2p/go-libp2p-crypto/blob/master/key.go
|
## https://github.com/libp2p/go-libp2p-crypto/blob/master/key.go
|
||||||
import unittest2
|
import unittest2
|
||||||
|
import bearssl/hash
|
||||||
import nimcrypto/[utils, sysrand]
|
import nimcrypto/[utils, sysrand]
|
||||||
import ../libp2p/crypto/[crypto, chacha20poly1305, curve25519, hkdf]
|
import ../libp2p/crypto/[crypto, chacha20poly1305, curve25519, hkdf]
|
||||||
import bearssl
|
|
||||||
|
|
||||||
when defined(nimHasUsed): {.used.}
|
when defined(nimHasUsed): {.used.}
|
||||||
|
|
||||||
|
@ -560,7 +560,7 @@ suite "Key interface test suite":
|
||||||
|
|
||||||
test "shuffle":
|
test "shuffle":
|
||||||
var cards = ["Ace", "King", "Queen", "Jack", "Ten"]
|
var cards = ["Ace", "King", "Queen", "Jack", "Ten"]
|
||||||
var rng = (ref BrHmacDrbgContext)()
|
var rng = (ref HmacDrbgContext)()
|
||||||
brHmacDrbgInit(addr rng[], addr sha256Vtable, nil, 0)
|
hmacDrbgInit(rng[], addr sha256Vtable, nil, 0)
|
||||||
rng.shuffle(cards)
|
rng.shuffle(cards)
|
||||||
check cards == ["King", "Ten", "Ace", "Queen", "Jack"]
|
check cards == ["King", "Ten", "Ace", "Queen", "Jack"]
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import options, bearssl
|
import options
|
||||||
import chronos, strutils, sequtils, sets, algorithm
|
import chronos, strutils, sequtils, sets, algorithm
|
||||||
import ../libp2p/[protocols/identify,
|
import ../libp2p/[protocols/identify,
|
||||||
multiaddress,
|
multiaddress,
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
{.used.}
|
{.used.}
|
||||||
|
|
||||||
import tables, bearssl
|
import tables
|
||||||
import chronos, stew/byteutils
|
import chronos, stew/byteutils
|
||||||
import chronicles
|
import chronicles
|
||||||
import ../libp2p/[switch,
|
import ../libp2p/[switch,
|
||||||
|
@ -214,7 +214,7 @@ suite "Noise":
|
||||||
readTask = newFuture[void]()
|
readTask = newFuture[void]()
|
||||||
|
|
||||||
var hugePayload = newSeq[byte](0xFFFFF)
|
var hugePayload = newSeq[byte](0xFFFFF)
|
||||||
brHmacDrbgGenerate(rng[], hugePayload)
|
hmacDrbgGenerate(rng[], hugePayload)
|
||||||
trace "Sending huge payload", size = hugePayload.len
|
trace "Sending huge payload", size = hugePayload.len
|
||||||
|
|
||||||
let
|
let
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{.used.}
|
{.used.}
|
||||||
|
|
||||||
import options, bearssl
|
import options
|
||||||
import chronos, stew/byteutils
|
import chronos, stew/byteutils
|
||||||
import ../libp2p/crypto/crypto,
|
import ../libp2p/crypto/crypto,
|
||||||
../libp2p/multicodec,
|
../libp2p/multicodec,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import options, bearssl
|
import options
|
||||||
import chronos, strutils
|
import chronos, strutils
|
||||||
import ../libp2p/[protocols/identify,
|
import ../libp2p/[protocols/identify,
|
||||||
protocols/ping,
|
protocols/ping,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{.used.}
|
{.used.}
|
||||||
|
|
||||||
import options, bearssl, chronos
|
import options, chronos
|
||||||
import stew/byteutils
|
import stew/byteutils
|
||||||
import ../libp2p/[protocols/relay,
|
import ../libp2p/[protocols/relay,
|
||||||
multiaddress,
|
multiaddress,
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
## 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 unittest2, bearssl
|
import unittest2
|
||||||
import ../libp2p/crypto/[crypto, secp]
|
import ../libp2p/crypto/[crypto, secp]
|
||||||
import nimcrypto/utils
|
import nimcrypto/utils
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue