Crypto utilities resultification (#150)
This commit is contained in:
parent
167f42ed45
commit
7dcb807f64
|
@ -152,7 +152,7 @@ proc readInput(wfd: AsyncFD) {.thread.} =
|
||||||
proc processInput(rfd: AsyncFD) {.async.} =
|
proc processInput(rfd: AsyncFD) {.async.} =
|
||||||
let transp = fromPipe(rfd)
|
let transp = fromPipe(rfd)
|
||||||
|
|
||||||
let seckey = PrivateKey.random(RSA)
|
let seckey = PrivateKey.random(RSA).get()
|
||||||
let peerInfo = PeerInfo.init(seckey)
|
let peerInfo = PeerInfo.init(seckey)
|
||||||
var localAddress = DefaultAddr
|
var localAddress = DefaultAddr
|
||||||
while true:
|
while true:
|
||||||
|
|
|
@ -95,7 +95,7 @@ proc decode(data: openarray[byte], cid: var Cid): CidStatus =
|
||||||
if mcodec == InvalidMultiCodec:
|
if mcodec == InvalidMultiCodec:
|
||||||
return CidStatus.Incorrect
|
return CidStatus.Incorrect
|
||||||
if not MultiHash.validate(vb.buffer.toOpenArray(vb.offset,
|
if not MultiHash.validate(vb.buffer.toOpenArray(vb.offset,
|
||||||
len(vb.buffer) - 1)):
|
vb.buffer.high)):
|
||||||
return CidStatus.Incorrect
|
return CidStatus.Incorrect
|
||||||
vb.finish()
|
vb.finish()
|
||||||
cid.cidver = CIDv1
|
cid.cidver = CIDv1
|
||||||
|
@ -133,7 +133,7 @@ proc validate*(ctype: typedesc[Cid], data: openarray[byte]): bool =
|
||||||
var res: VarintStatus
|
var res: VarintStatus
|
||||||
if len(data) < 2:
|
if len(data) < 2:
|
||||||
return false
|
return false
|
||||||
let last = len(data) - 1
|
let last = data.high
|
||||||
if len(data) == 34:
|
if len(data) == 34:
|
||||||
if data[0] == 0x12'u8 and data[1] == 0x20'u8:
|
if data[0] == 0x12'u8 and data[1] == 0x20'u8:
|
||||||
return true
|
return true
|
||||||
|
@ -161,8 +161,8 @@ proc mhash*(cid: Cid): MultiHash =
|
||||||
## Returns MultiHash part of CID.
|
## Returns MultiHash part of CID.
|
||||||
if cid.cidver notin {CIDv0, CIDv1}:
|
if cid.cidver notin {CIDv0, CIDv1}:
|
||||||
raise newException(CidError, "Incorrect CID!")
|
raise newException(CidError, "Incorrect CID!")
|
||||||
result = MultiHash.init(cid.data.buffer.toOpenArray(cid.hpos,
|
result = MultiHash.init(
|
||||||
len(cid.data) - 1))
|
cid.data.buffer.toOpenArray(cid.hpos, cid.data.high)).tryGet()
|
||||||
|
|
||||||
proc contentType*(cid: Cid): MultiCodec =
|
proc contentType*(cid: Cid): MultiCodec =
|
||||||
## Returns content type part of CID
|
## Returns content type part of CID
|
||||||
|
@ -221,11 +221,11 @@ proc `==`*(a: Cid, b: Cid): bool =
|
||||||
## are equal, ``false`` otherwise.
|
## are equal, ``false`` otherwise.
|
||||||
if a.mcodec == b.mcodec:
|
if a.mcodec == b.mcodec:
|
||||||
var ah, bh: MultiHash
|
var ah, bh: MultiHash
|
||||||
if MultiHash.decode(a.data.buffer.toOpenArray(a.hpos,
|
if MultiHash.decode(
|
||||||
len(a.data) - 1), ah) == -1:
|
a.data.buffer.toOpenArray(a.hpos, a.data.high), ah).isErr:
|
||||||
return false
|
return false
|
||||||
if MultiHash.decode(b.data.buffer.toOpenArray(b.hpos,
|
if MultiHash.decode(
|
||||||
len(b.data) - 1), bh) == -1:
|
b.data.buffer.toOpenArray(b.hpos, b.data.high), bh).isErr:
|
||||||
return false
|
return false
|
||||||
result = (ah == bh)
|
result = (ah == bh)
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,9 @@
|
||||||
## those terms.
|
## those terms.
|
||||||
|
|
||||||
## This module implements Public Key and Private Key interface for libp2p.
|
## This module implements Public Key and Private Key interface for libp2p.
|
||||||
|
|
||||||
|
{.push raises: [Defect].}
|
||||||
|
|
||||||
import rsa, ecnist, ed25519/ed25519, secp
|
import rsa, ecnist, ed25519/ed25519, secp
|
||||||
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]
|
||||||
|
@ -79,172 +82,177 @@ type
|
||||||
Signature* = object
|
Signature* = object
|
||||||
data*: seq[byte]
|
data*: seq[byte]
|
||||||
|
|
||||||
P2pKeyError* = object of CatchableError
|
CryptoError* = enum
|
||||||
P2pSigError* = object of CatchableError
|
KeyError,
|
||||||
|
SigError,
|
||||||
|
HashError,
|
||||||
|
SchemeError
|
||||||
|
|
||||||
|
CryptoResult*[T] = Result[T, CryptoError]
|
||||||
|
|
||||||
const
|
const
|
||||||
SupportedSchemes* = {RSA, Ed25519, Secp256k1, ECDSA}
|
SupportedSchemes* = {RSA, Ed25519, Secp256k1, ECDSA}
|
||||||
SupportedSchemesInt* = {int8(RSA), int8(Ed25519), int8(Secp256k1),
|
SupportedSchemesInt* = {int8(RSA), int8(Ed25519), int8(Secp256k1),
|
||||||
int8(ECDSA)}
|
int8(ECDSA)}
|
||||||
|
|
||||||
|
template orError(exp: untyped, err: CryptoError): untyped =
|
||||||
|
(exp.mapErr do (_: auto) -> auto: err)
|
||||||
|
|
||||||
proc random*(t: typedesc[PrivateKey], scheme: PKScheme,
|
proc random*(t: typedesc[PrivateKey], scheme: PKScheme,
|
||||||
bits = DefaultKeySize): PrivateKey =
|
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.
|
||||||
doAssert(scheme in SupportedSchemes)
|
case scheme
|
||||||
result = PrivateKey(scheme: scheme)
|
of RSA:
|
||||||
if scheme == RSA:
|
let rsakey = ? RsaPrivateKey.random(bits).orError(KeyError)
|
||||||
result.rsakey = RsaPrivateKey.random(bits)
|
ok(PrivateKey(scheme: scheme, rsakey: rsakey))
|
||||||
elif scheme == Ed25519:
|
of Ed25519:
|
||||||
result.edkey = EdPrivateKey.random()
|
let edkey = ? EdPrivateKey.random().orError(KeyError)
|
||||||
elif scheme == ECDSA:
|
ok(PrivateKey(scheme: scheme, edkey: edkey))
|
||||||
result.eckey = EcPrivateKey.random(Secp256r1)
|
of ECDSA:
|
||||||
elif scheme == Secp256k1:
|
let eckey = ? EcPrivateKey.random(Secp256r1).orError(KeyError)
|
||||||
result.skkey = SkPrivateKey.random()
|
ok(PrivateKey(scheme: scheme, eckey: eckey))
|
||||||
|
of Secp256k1:
|
||||||
|
let skkey = ? SkPrivateKey.random().orError(KeyError)
|
||||||
|
ok(PrivateKey(scheme: scheme, skkey: skkey))
|
||||||
|
else:
|
||||||
|
err(SchemeError)
|
||||||
|
|
||||||
proc random*(t: typedesc[KeyPair], scheme: PKScheme,
|
proc random*(t: typedesc[KeyPair], scheme: PKScheme,
|
||||||
bits = DefaultKeySize): KeyPair =
|
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.
|
||||||
doAssert(scheme in SupportedSchemes)
|
case scheme
|
||||||
result.seckey = PrivateKey(scheme: scheme)
|
of RSA:
|
||||||
result.pubkey = PublicKey(scheme: scheme)
|
let pair = ? RsaKeyPair.random(bits).orError(KeyError)
|
||||||
if scheme == RSA:
|
ok(KeyPair(
|
||||||
var pair = RsaKeyPair.random(bits)
|
seckey: PrivateKey(scheme: scheme, rsakey: pair.seckey),
|
||||||
result.seckey.rsakey = pair.seckey
|
pubkey: PublicKey(scheme: scheme, rsakey: pair.pubkey)))
|
||||||
result.pubkey.rsakey = pair.pubkey
|
of Ed25519:
|
||||||
elif scheme == Ed25519:
|
let pair = ? EdKeyPair.random().orError(KeyError)
|
||||||
var pair = EdKeyPair.random()
|
ok(KeyPair(
|
||||||
result.seckey.edkey = pair.seckey
|
seckey: PrivateKey(scheme: scheme, edkey: pair.seckey),
|
||||||
result.pubkey.edkey = pair.pubkey
|
pubkey: PublicKey(scheme: scheme, edkey: pair.pubkey)))
|
||||||
elif scheme == ECDSA:
|
of ECDSA:
|
||||||
var pair = EcKeyPair.random(Secp256r1)
|
let pair = ? EcKeyPair.random(Secp256r1).orError(KeyError)
|
||||||
result.seckey.eckey = pair.seckey
|
ok(KeyPair(
|
||||||
result.pubkey.eckey = pair.pubkey
|
seckey: PrivateKey(scheme: scheme, eckey: pair.seckey),
|
||||||
elif scheme == Secp256k1:
|
pubkey: PublicKey(scheme: scheme, eckey: pair.pubkey)))
|
||||||
var pair = SkKeyPair.random()
|
of Secp256k1:
|
||||||
result.seckey.skkey = pair.seckey
|
let pair = ? SkKeyPair.random().orError(KeyError)
|
||||||
result.pubkey.skkey = pair.pubkey
|
ok(KeyPair(
|
||||||
|
seckey: PrivateKey(scheme: scheme, skkey: pair.seckey),
|
||||||
|
pubkey: PublicKey(scheme: scheme, skkey: pair.pubkey)))
|
||||||
|
else:
|
||||||
|
err(SchemeError)
|
||||||
|
|
||||||
proc getKey*(key: PrivateKey): PublicKey =
|
proc getKey*(key: PrivateKey): CryptoResult[PublicKey] =
|
||||||
## Get public key from corresponding private key ``key``.
|
## Get public key from corresponding private key ``key``.
|
||||||
result = PublicKey(scheme: key.scheme)
|
case key.scheme
|
||||||
if key.scheme == RSA:
|
of RSA:
|
||||||
result.rsakey = key.rsakey.getKey()
|
let rsakey = key.rsakey.getKey()
|
||||||
elif key.scheme == Ed25519:
|
ok(PublicKey(scheme: RSA, rsakey: rsakey))
|
||||||
result.edkey = key.edkey.getKey()
|
of Ed25519:
|
||||||
elif key.scheme == ECDSA:
|
let edkey = key.edkey.getKey()
|
||||||
result.eckey = key.eckey.getKey()
|
ok(PublicKey(scheme: Ed25519, edkey: edkey))
|
||||||
elif key.scheme == Secp256k1:
|
of ECDSA:
|
||||||
result.skkey = key.skkey.getKey()
|
let eckey = ? key.eckey.getKey().orError(KeyError)
|
||||||
|
ok(PublicKey(scheme: ECDSA, eckey: eckey))
|
||||||
|
of Secp256k1:
|
||||||
|
let skkey = ? key.skkey.getKey().orError(KeyError)
|
||||||
|
ok(PublicKey(scheme: Secp256k1, skkey: skkey))
|
||||||
|
else:
|
||||||
|
err(KeyError)
|
||||||
|
|
||||||
proc toRawBytes*(key: PrivateKey, data: var openarray[byte]): int =
|
proc toRawBytes*(key: PrivateKey | PublicKey, data: var openarray[byte]): CryptoResult[int] =
|
||||||
## Serialize private key ``key`` (using scheme's own serialization) and store
|
## Serialize private key ``key`` (using scheme's own serialization) and store
|
||||||
## it to ``data``.
|
## it to ``data``.
|
||||||
##
|
##
|
||||||
## Returns number of bytes (octets) needed to store private key ``key``.
|
## Returns number of bytes (octets) needed to store private key ``key``.
|
||||||
if key.scheme == RSA:
|
case key.scheme
|
||||||
result = key.rsakey.toBytes(data)
|
of RSA:
|
||||||
elif key.scheme == Ed25519:
|
key.rsakey.toBytes(data).orError(KeyError)
|
||||||
result = key.edkey.toBytes(data)
|
of Ed25519:
|
||||||
elif key.scheme == ECDSA:
|
ok(key.edkey.toBytes(data))
|
||||||
result = key.eckey.toBytes(data)
|
of ECDSA:
|
||||||
elif key.scheme == Secp256k1:
|
key.eckey.toBytes(data).orError(KeyError)
|
||||||
result = key.skkey.toBytes(data)
|
of Secp256k1:
|
||||||
|
key.skkey.toBytes(data).orError(KeyError)
|
||||||
|
else:
|
||||||
|
err(KeyError)
|
||||||
|
|
||||||
proc toRawBytes*(key: PublicKey, data: var openarray[byte]): int =
|
proc getRawBytes*(key: PrivateKey | PublicKey): CryptoResult[seq[byte]] =
|
||||||
## Serialize public key ``key`` (using scheme's own serialization) and store
|
|
||||||
## it to ``data``.
|
|
||||||
##
|
|
||||||
## Returns number of bytes (octets) needed to store public key ``key``.
|
|
||||||
if key.scheme == RSA:
|
|
||||||
result = key.rsakey.toBytes(data)
|
|
||||||
elif key.scheme == Ed25519:
|
|
||||||
result = key.edkey.toBytes(data)
|
|
||||||
elif key.scheme == ECDSA:
|
|
||||||
result = key.eckey.toBytes(data)
|
|
||||||
elif key.scheme == Secp256k1:
|
|
||||||
result = key.skkey.toBytes(data)
|
|
||||||
|
|
||||||
proc getRawBytes*(key: PrivateKey): seq[byte] =
|
|
||||||
## Return private key ``key`` in binary form (using scheme's own
|
## Return private key ``key`` in binary form (using scheme's own
|
||||||
## serialization).
|
## serialization).
|
||||||
if key.scheme == RSA:
|
case key.scheme
|
||||||
result = key.rsakey.getBytes()
|
of RSA:
|
||||||
elif key.scheme == Ed25519:
|
key.rsakey.getBytes().orError(KeyError)
|
||||||
result = key.edkey.getBytes()
|
of Ed25519:
|
||||||
elif key.scheme == ECDSA:
|
ok(key.edkey.getBytes())
|
||||||
result = key.eckey.getBytes()
|
of ECDSA:
|
||||||
elif key.scheme == Secp256k1:
|
key.eckey.getBytes().orError(KeyError)
|
||||||
result = key.skkey.getBytes()
|
of Secp256k1:
|
||||||
|
ok(key.skkey.getBytes())
|
||||||
|
else:
|
||||||
|
err(KeyError)
|
||||||
|
|
||||||
proc getRawBytes*(key: PublicKey): seq[byte] =
|
proc toBytes*(key: PrivateKey, data: var openarray[byte]): CryptoResult[int] =
|
||||||
## Return public key ``key`` in binary form (using scheme's own
|
|
||||||
## serialization).
|
|
||||||
if key.scheme == RSA:
|
|
||||||
result = key.rsakey.getBytes()
|
|
||||||
elif key.scheme == Ed25519:
|
|
||||||
result = key.edkey.getBytes()
|
|
||||||
elif key.scheme == ECDSA:
|
|
||||||
result = key.eckey.getBytes()
|
|
||||||
elif key.scheme == Secp256k1:
|
|
||||||
result = key.skkey.getBytes()
|
|
||||||
|
|
||||||
proc toBytes*(key: PrivateKey, data: var openarray[byte]): int =
|
|
||||||
## Serialize private key ``key`` (using libp2p protobuf scheme) and store
|
## Serialize private key ``key`` (using libp2p protobuf scheme) and store
|
||||||
## it to ``data``.
|
## it to ``data``.
|
||||||
##
|
##
|
||||||
## Returns number of bytes (octets) needed to store private key ``key``.
|
## Returns number of bytes (octets) needed to store private key ``key``.
|
||||||
var msg = initProtoBuffer()
|
var msg = initProtoBuffer()
|
||||||
msg.write(initProtoField(1, cast[uint64](key.scheme)))
|
msg.write(initProtoField(1, cast[uint64](key.scheme)))
|
||||||
msg.write(initProtoField(2, key.getRawBytes()))
|
msg.write(initProtoField(2, ? key.getRawBytes()))
|
||||||
msg.finish()
|
msg.finish()
|
||||||
result = len(msg.buffer)
|
var blen = len(msg.buffer)
|
||||||
if len(data) >= result:
|
if len(data) >= blen:
|
||||||
copyMem(addr data[0], addr msg.buffer[0], len(msg.buffer))
|
copyMem(addr data[0], addr msg.buffer[0], blen)
|
||||||
|
ok(blen)
|
||||||
|
|
||||||
proc toBytes*(key: PublicKey, data: var openarray[byte]): int =
|
proc toBytes*(key: PublicKey, data: var openarray[byte]): CryptoResult[int] =
|
||||||
## Serialize public key ``key`` (using libp2p protobuf scheme) and store
|
## Serialize public key ``key`` (using libp2p protobuf scheme) and store
|
||||||
## it to ``data``.
|
## it to ``data``.
|
||||||
##
|
##
|
||||||
## Returns number of bytes (octets) needed to store public key ``key``.
|
## Returns number of bytes (octets) needed to store public key ``key``.
|
||||||
var msg = initProtoBuffer()
|
var msg = initProtoBuffer()
|
||||||
msg.write(initProtoField(1, cast[uint64](key.scheme)))
|
msg.write(initProtoField(1, cast[uint64](key.scheme)))
|
||||||
msg.write(initProtoField(2, key.getRawBytes()))
|
msg.write(initProtoField(2, ? key.getRawBytes()))
|
||||||
msg.finish()
|
msg.finish()
|
||||||
result = len(msg.buffer)
|
var blen = len(msg.buffer)
|
||||||
if len(data) >= result:
|
if len(data) >= blen and blen > 0:
|
||||||
copyMem(addr data[0], addr msg.buffer[0], len(msg.buffer))
|
copyMem(addr data[0], addr msg.buffer[0], blen)
|
||||||
|
ok(blen)
|
||||||
|
|
||||||
proc toBytes*(sig: Signature, data: var openarray[byte]): int =
|
proc toBytes*(sig: Signature, data: var openarray[byte]): int =
|
||||||
## Serialize signature ``sig`` and store it to ``data``.
|
## Serialize signature ``sig`` and store it to ``data``.
|
||||||
##
|
##
|
||||||
## Returns number of bytes (octets) needed to store signature ``sig``.
|
## Returns number of bytes (octets) needed to store signature ``sig``.
|
||||||
result = len(sig.data)
|
result = len(sig.data)
|
||||||
if len(data) >= result:
|
if len(data) >= result and result > 0:
|
||||||
copyMem(addr data[0], unsafeAddr sig.data[0], len(sig.data))
|
copyMem(addr data[0], unsafeAddr sig.data[0], len(sig.data))
|
||||||
|
|
||||||
proc getBytes*(key: PrivateKey): seq[byte] =
|
proc getBytes*(key: PrivateKey): CryptoResult[seq[byte]] =
|
||||||
## Return private key ``key`` in binary form (using libp2p's protobuf
|
## Return private key ``key`` in binary form (using libp2p's protobuf
|
||||||
## serialization).
|
## serialization).
|
||||||
var msg = initProtoBuffer()
|
var msg = initProtoBuffer()
|
||||||
msg.write(initProtoField(1, cast[uint64](key.scheme)))
|
msg.write(initProtoField(1, cast[uint64](key.scheme)))
|
||||||
msg.write(initProtoField(2, key.getRawBytes()))
|
msg.write(initProtoField(2, ? key.getRawBytes()))
|
||||||
msg.finish()
|
msg.finish()
|
||||||
result = msg.buffer
|
ok(msg.buffer)
|
||||||
|
|
||||||
proc getBytes*(key: PublicKey): seq[byte] =
|
proc getBytes*(key: PublicKey): CryptoResult[seq[byte]] =
|
||||||
## Return public key ``key`` in binary form (using libp2p's protobuf
|
## Return public key ``key`` in binary form (using libp2p's protobuf
|
||||||
## serialization).
|
## serialization).
|
||||||
var msg = initProtoBuffer()
|
var msg = initProtoBuffer()
|
||||||
msg.write(initProtoField(1, cast[uint64](key.scheme)))
|
msg.write(initProtoField(1, cast[uint64](key.scheme)))
|
||||||
msg.write(initProtoField(2, key.getRawBytes()))
|
msg.write(initProtoField(2, ? key.getRawBytes()))
|
||||||
msg.finish()
|
msg.finish()
|
||||||
result = msg.buffer
|
ok(msg.buffer)
|
||||||
|
|
||||||
proc getBytes*(sig: Signature): seq[byte] =
|
proc getBytes*(sig: Signature): seq[byte] =
|
||||||
## Return signature ``sig`` in binary form.
|
## Return signature ``sig`` in binary form.
|
||||||
|
@ -277,7 +285,7 @@ proc init*(key: var PrivateKey, data: openarray[byte]): bool =
|
||||||
key = nkey
|
key = nkey
|
||||||
result = true
|
result = true
|
||||||
elif scheme == Secp256k1:
|
elif scheme == Secp256k1:
|
||||||
if init(nkey.skkey, buffer):
|
if init(nkey.skkey, buffer).isOk:
|
||||||
key = nkey
|
key = nkey
|
||||||
result = true
|
result = true
|
||||||
|
|
||||||
|
@ -308,7 +316,7 @@ proc init*(key: var PublicKey, data: openarray[byte]): bool =
|
||||||
key = nkey
|
key = nkey
|
||||||
result = true
|
result = true
|
||||||
elif scheme == Secp256k1:
|
elif scheme == Secp256k1:
|
||||||
if init(nkey.skkey, buffer):
|
if init(nkey.skkey, buffer).isOk:
|
||||||
key = nkey
|
key = nkey
|
||||||
result = true
|
result = true
|
||||||
|
|
||||||
|
@ -325,50 +333,77 @@ proc init*(key: var PrivateKey, data: string): bool =
|
||||||
## hexadecimal string representation.
|
## hexadecimal string representation.
|
||||||
##
|
##
|
||||||
## Returns ``true`` on success.
|
## Returns ``true`` on success.
|
||||||
result = key.init(fromHex(data))
|
try:
|
||||||
|
key.init(fromHex(data))
|
||||||
|
except ValueError:
|
||||||
|
false
|
||||||
|
|
||||||
proc init*(key: var PublicKey, data: string): bool =
|
proc init*(key: var PublicKey, data: string): bool =
|
||||||
## Initialize public key ``key`` from libp2p's protobuf serialized
|
## Initialize public key ``key`` from libp2p's protobuf serialized
|
||||||
## hexadecimal string representation.
|
## hexadecimal string representation.
|
||||||
##
|
##
|
||||||
## Returns ``true`` on success.
|
## Returns ``true`` on success.
|
||||||
result = key.init(fromHex(data))
|
try:
|
||||||
|
key.init(fromHex(data))
|
||||||
|
except ValueError:
|
||||||
|
false
|
||||||
|
|
||||||
proc init*(sig: var Signature, data: string): bool =
|
proc init*(sig: var Signature, data: string): bool =
|
||||||
## Initialize signature ``sig`` from serialized hexadecimal string
|
## Initialize signature ``sig`` from serialized hexadecimal string
|
||||||
## representation.
|
## representation.
|
||||||
##
|
##
|
||||||
## Returns ``true`` on success.
|
## Returns ``true`` on success.
|
||||||
result = sig.init(fromHex(data))
|
try:
|
||||||
|
sig.init(fromHex(data))
|
||||||
|
except ValueError:
|
||||||
|
false
|
||||||
|
|
||||||
proc init*(t: typedesc[PrivateKey], data: openarray[byte]): PrivateKey =
|
proc init*(t: typedesc[PrivateKey], data: openarray[byte]): CryptoResult[PrivateKey] =
|
||||||
## Create new private key from libp2p's protobuf serialized binary form.
|
## Create new private key from libp2p's protobuf serialized binary form.
|
||||||
if not result.init(data):
|
var res: t
|
||||||
raise newException(P2pKeyError, "Incorrect binary form")
|
if not res.init(data):
|
||||||
|
err(KeyError)
|
||||||
|
else:
|
||||||
|
ok(res)
|
||||||
|
|
||||||
proc init*(t: typedesc[PublicKey], data: openarray[byte]): PublicKey =
|
proc init*(t: typedesc[PublicKey], data: openarray[byte]): CryptoResult[PublicKey] =
|
||||||
## Create new public key from libp2p's protobuf serialized binary form.
|
## Create new public key from libp2p's protobuf serialized binary form.
|
||||||
if not result.init(data):
|
var res: t
|
||||||
raise newException(P2pKeyError, "Incorrect binary form")
|
if not res.init(data):
|
||||||
|
err(KeyError)
|
||||||
|
else:
|
||||||
|
ok(res)
|
||||||
|
|
||||||
proc init*(t: typedesc[Signature], data: openarray[byte]): Signature =
|
proc init*(t: typedesc[Signature], data: openarray[byte]): CryptoResult[Signature] =
|
||||||
## Create new public key from libp2p's protobuf serialized binary form.
|
## Create new public key from libp2p's protobuf serialized binary form.
|
||||||
if not result.init(data):
|
var res: t
|
||||||
raise newException(P2pSigError, "Incorrect binary form")
|
if not res.init(data):
|
||||||
|
err(SigError)
|
||||||
|
else:
|
||||||
|
ok(res)
|
||||||
|
|
||||||
proc init*(t: typedesc[PrivateKey], data: string): PrivateKey =
|
proc init*(t: typedesc[PrivateKey], data: string): CryptoResult[PrivateKey] =
|
||||||
## Create new private key from libp2p's protobuf serialized hexadecimal string
|
## Create new private key from libp2p's protobuf serialized hexadecimal string
|
||||||
## form.
|
## form.
|
||||||
result = t.init(fromHex(data))
|
try:
|
||||||
|
t.init(fromHex(data))
|
||||||
|
except ValueError:
|
||||||
|
err(KeyError)
|
||||||
|
|
||||||
proc init*(t: typedesc[PublicKey], data: string): PublicKey =
|
proc init*(t: typedesc[PublicKey], data: string): CryptoResult[PublicKey] =
|
||||||
## Create new public key from libp2p's protobuf serialized hexadecimal string
|
## Create new public key from libp2p's protobuf serialized hexadecimal string
|
||||||
## form.
|
## form.
|
||||||
result = t.init(fromHex(data))
|
try:
|
||||||
|
t.init(fromHex(data))
|
||||||
|
except ValueError:
|
||||||
|
err(KeyError)
|
||||||
|
|
||||||
proc init*(t: typedesc[Signature], data: string): Signature =
|
proc init*(t: typedesc[Signature], data: string): CryptoResult[Signature] =
|
||||||
## Create new signature from serialized hexadecimal string form.
|
## Create new signature from serialized hexadecimal string form.
|
||||||
result = t.init(fromHex(data))
|
try:
|
||||||
|
t.init(fromHex(data))
|
||||||
|
except ValueError:
|
||||||
|
err(SigError)
|
||||||
|
|
||||||
proc `==`*(key1, key2: PublicKey): bool =
|
proc `==`*(key1, key2: PublicKey): bool =
|
||||||
## Return ``true`` if two public keys ``key1`` and ``key2`` of the same
|
## Return ``true`` if two public keys ``key1`` and ``key2`` of the same
|
||||||
|
@ -464,24 +499,30 @@ proc `$`*(sig: Signature): string =
|
||||||
## Get string representation of signature ``sig``.
|
## Get string representation of signature ``sig``.
|
||||||
result = toHex(sig.data)
|
result = toHex(sig.data)
|
||||||
|
|
||||||
proc sign*(key: PrivateKey, data: openarray[byte]): Signature {.gcsafe.} =
|
proc sign*(key: PrivateKey, data: openarray[byte]): CryptoResult[Signature] {.gcsafe.} =
|
||||||
## Sign message ``data`` using private key ``key`` and return generated
|
## Sign message ``data`` using private key ``key`` and return generated
|
||||||
## signature in raw binary form.
|
## signature in raw binary form.
|
||||||
|
var res: Signature
|
||||||
if key.scheme == RSA:
|
if key.scheme == RSA:
|
||||||
var sig = key.rsakey.sign(data)
|
let sig = ? key.rsakey.sign(data).orError(SigError)
|
||||||
result.data = sig.getBytes()
|
res.data = ? sig.getBytes().orError(SigError)
|
||||||
|
ok(res)
|
||||||
elif key.scheme == Ed25519:
|
elif key.scheme == Ed25519:
|
||||||
var sig = key.edkey.sign(data)
|
let sig = key.edkey.sign(data)
|
||||||
result.data = sig.getBytes()
|
res.data = sig.getBytes()
|
||||||
|
ok(res)
|
||||||
elif key.scheme == ECDSA:
|
elif key.scheme == ECDSA:
|
||||||
var sig = key.eckey.sign(data)
|
let sig = ? key.eckey.sign(data).orError(SigError)
|
||||||
result.data = sig.getBytes()
|
res.data = ? sig.getBytes().orError(SigError)
|
||||||
|
ok(res)
|
||||||
elif key.scheme == Secp256k1:
|
elif key.scheme == Secp256k1:
|
||||||
var sig = key.skkey.sign(data)
|
let sig = ? key.skkey.sign(data).orError(SigError)
|
||||||
result.data = sig.getBytes()
|
res.data = sig.getBytes()
|
||||||
|
ok(res)
|
||||||
|
else:
|
||||||
|
err(SigError)
|
||||||
|
|
||||||
proc verify*(sig: Signature, message: openarray[byte],
|
proc verify*(sig: Signature, message: openarray[byte], key: PublicKey): bool =
|
||||||
key: PublicKey): bool =
|
|
||||||
## Verify signature ``sig`` using message ``message`` and public key ``key``.
|
## Verify signature ``sig`` using message ``message`` and public key ``key``.
|
||||||
## Return ``true`` if message signature is valid.
|
## Return ``true`` if message signature is valid.
|
||||||
if key.scheme == RSA:
|
if key.scheme == RSA:
|
||||||
|
@ -498,7 +539,7 @@ proc verify*(sig: Signature, message: openarray[byte],
|
||||||
result = signature.verify(message, key.eckey)
|
result = signature.verify(message, key.eckey)
|
||||||
elif key.scheme == Secp256k1:
|
elif key.scheme == Secp256k1:
|
||||||
var signature: SkSignature
|
var signature: SkSignature
|
||||||
if signature.init(sig.data):
|
if signature.init(sig.data).isOk:
|
||||||
result = signature.verify(message, key.skkey)
|
result = signature.verify(message, key.skkey)
|
||||||
|
|
||||||
template makeSecret(buffer, hmactype, secret, seed: untyped) {.dirty.}=
|
template makeSecret(buffer, hmactype, secret, seed: untyped) {.dirty.}=
|
||||||
|
@ -510,11 +551,11 @@ template makeSecret(buffer, hmactype, secret, seed: untyped) {.dirty.}=
|
||||||
if secret[i] != 0x00'u8:
|
if secret[i] != 0x00'u8:
|
||||||
break
|
break
|
||||||
inc(offset)
|
inc(offset)
|
||||||
ctx.init(secret.toOpenArray(offset, len(secret) - 1))
|
ctx.init(secret.toOpenArray(offset, secret.high))
|
||||||
ctx.update(seed)
|
ctx.update(seed)
|
||||||
var a = ctx.finish()
|
var a = ctx.finish()
|
||||||
while j < len(buffer):
|
while j < len(buffer):
|
||||||
ctx.init(secret.toOpenArray(offset, len(secret) - 1))
|
ctx.init(secret.toOpenArray(offset, secret.high))
|
||||||
ctx.update(a.data)
|
ctx.update(a.data)
|
||||||
ctx.update(seed)
|
ctx.update(seed)
|
||||||
var b = ctx.finish()
|
var b = ctx.finish()
|
||||||
|
@ -523,7 +564,7 @@ template makeSecret(buffer, hmactype, secret, seed: untyped) {.dirty.}=
|
||||||
todo = len(buffer) - j
|
todo = len(buffer) - j
|
||||||
copyMem(addr buffer[j], addr b.data[0], todo)
|
copyMem(addr buffer[j], addr b.data[0], todo)
|
||||||
j += todo
|
j += todo
|
||||||
ctx.init(secret.toOpenArray(offset, len(secret) - 1))
|
ctx.init(secret.toOpenArray(offset, secret.high))
|
||||||
ctx.update(a.data)
|
ctx.update(a.data)
|
||||||
a = ctx.finish()
|
a = ctx.finish()
|
||||||
|
|
||||||
|
@ -588,33 +629,32 @@ 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): KeyPair =
|
proc ephemeral*(scheme: ECDHEScheme): 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)
|
keypair = ? EcKeyPair.random(Secp256r1).orError(KeyError)
|
||||||
elif scheme == Secp384r1:
|
elif scheme == Secp384r1:
|
||||||
keypair = EcKeyPair.random(Secp384r1)
|
keypair = ? EcKeyPair.random(Secp384r1).orError(KeyError)
|
||||||
elif scheme == Secp521r1:
|
elif scheme == Secp521r1:
|
||||||
keypair = EcKeyPair.random(Secp521r1)
|
keypair = ? EcKeyPair.random(Secp521r1).orError(KeyError)
|
||||||
result.seckey = PrivateKey(scheme: ECDSA)
|
ok(KeyPair(
|
||||||
result.pubkey = PublicKey(scheme: ECDSA)
|
seckey: PrivateKey(scheme: ECDSA, eckey: keypair.seckey),
|
||||||
result.seckey.eckey = keypair.seckey
|
pubkey: PublicKey(scheme: ECDSA, eckey: keypair.pubkey)))
|
||||||
result.pubkey.eckey = keypair.pubkey
|
|
||||||
|
|
||||||
proc ephemeral*(scheme: string): KeyPair {.inline.} =
|
proc ephemeral*(scheme: string): CryptoResult[KeyPair] {.inline.} =
|
||||||
## 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":
|
||||||
result = ephemeral(Secp256r1)
|
ephemeral(Secp256r1)
|
||||||
elif scheme == "P-384":
|
elif scheme == "P-384":
|
||||||
result = ephemeral(Secp384r1)
|
ephemeral(Secp384r1)
|
||||||
elif scheme == "P-521":
|
elif scheme == "P-521":
|
||||||
result = ephemeral(Secp521r1)
|
ephemeral(Secp521r1)
|
||||||
else:
|
else:
|
||||||
result = ephemeral(Secp521r1)
|
ephemeral(Secp521r1)
|
||||||
|
|
||||||
proc makeSecret*(remoteEPublic: PublicKey, localEPrivate: PrivateKey,
|
proc makeSecret*(remoteEPublic: PublicKey, localEPrivate: PrivateKey,
|
||||||
data: var openarray[byte]): int =
|
data: var openarray[byte]): int =
|
||||||
|
@ -644,7 +684,7 @@ proc getSecret*(remoteEPublic: PublicKey,
|
||||||
result = getSecret(remoteEPublic.eckey, localEPrivate.eckey)
|
result = getSecret(remoteEPublic.eckey, localEPrivate.eckey)
|
||||||
|
|
||||||
proc getOrder*(remotePubkey, localNonce: openarray[byte],
|
proc getOrder*(remotePubkey, localNonce: openarray[byte],
|
||||||
localPubkey, remoteNonce: openarray[byte]): int =
|
localPubkey, remoteNonce: openarray[byte]): CryptoResult[int] =
|
||||||
## Compare values and calculate `order` parameter.
|
## Compare values and calculate `order` parameter.
|
||||||
var ctx: sha256
|
var ctx: sha256
|
||||||
ctx.init()
|
ctx.init()
|
||||||
|
@ -655,16 +695,18 @@ proc getOrder*(remotePubkey, localNonce: openarray[byte],
|
||||||
ctx.update(localPubkey)
|
ctx.update(localPubkey)
|
||||||
ctx.update(remoteNonce)
|
ctx.update(remoteNonce)
|
||||||
var digest2 = ctx.finish()
|
var digest2 = ctx.finish()
|
||||||
var mh1 = MultiHash.init(multiCodec("sha2-256"), digest1)
|
var mh1 = ? MultiHash.init(multiCodec("sha2-256"), digest1).orError(HashError)
|
||||||
var mh2 = MultiHash.init(multiCodec("sha2-256"), digest2)
|
var mh2 = ? MultiHash.init(multiCodec("sha2-256"), digest2).orError(HashError)
|
||||||
|
var res = 0;
|
||||||
for i in 0 ..< len(mh1.data.buffer):
|
for i in 0 ..< len(mh1.data.buffer):
|
||||||
result = int(mh1.data.buffer[i]) - int(mh2.data.buffer[i])
|
res = int(mh1.data.buffer[i]) - int(mh2.data.buffer[i])
|
||||||
if result != 0:
|
if res != 0:
|
||||||
if result < 0:
|
if res < 0:
|
||||||
result = -1
|
res = -1
|
||||||
elif result > 0:
|
elif res > 0:
|
||||||
result = 1
|
res = 1
|
||||||
break
|
break
|
||||||
|
ok(res)
|
||||||
|
|
||||||
proc selectBest*(order: int, p1, p2: string): string =
|
proc selectBest*(order: int, p1, p2: string): string =
|
||||||
## Determines which algorithm to use from list `p1` and `p2`.
|
## Determines which algorithm to use from list `p1` and `p2`.
|
||||||
|
@ -741,25 +783,25 @@ proc decodeExchange*(message: seq[byte],
|
||||||
|
|
||||||
## Serialization/Deserialization helpers
|
## Serialization/Deserialization helpers
|
||||||
|
|
||||||
proc write*(vb: var VBuffer, pubkey: PublicKey) {.inline.} =
|
proc write*(vb: var VBuffer, pubkey: PublicKey) {.inline, raises: [Defect, ResultError[CryptoError]].} =
|
||||||
## Write PublicKey value ``pubkey`` to buffer ``vb``.
|
## Write PublicKey value ``pubkey`` to buffer ``vb``.
|
||||||
vb.writeSeq(pubkey.getBytes())
|
vb.writeSeq(pubkey.getBytes().tryGet())
|
||||||
|
|
||||||
proc write*(vb: var VBuffer, seckey: PrivateKey) {.inline.} =
|
proc write*(vb: var VBuffer, seckey: PrivateKey) {.inline, raises: [Defect, ResultError[CryptoError]].} =
|
||||||
## Write PrivateKey value ``seckey`` to buffer ``vb``.
|
## Write PrivateKey value ``seckey`` to buffer ``vb``.
|
||||||
vb.writeSeq(seckey.getBytes())
|
vb.writeSeq(seckey.getBytes().tryGet())
|
||||||
|
|
||||||
proc write*(vb: var VBuffer, sig: PrivateKey) {.inline.} =
|
proc write*(vb: var VBuffer, sig: PrivateKey) {.inline, raises: [Defect, ResultError[CryptoError]].} =
|
||||||
## Write Signature value ``sig`` to buffer ``vb``.
|
## Write Signature value ``sig`` to buffer ``vb``.
|
||||||
vb.writeSeq(sig.getBytes())
|
vb.writeSeq(sig.getBytes().tryGet())
|
||||||
|
|
||||||
proc initProtoField*(index: int, pubkey: PublicKey): ProtoField =
|
proc initProtoField*(index: int, pubkey: PublicKey): ProtoField {.raises: [Defect, ResultError[CryptoError]].} =
|
||||||
## Initialize ProtoField with PublicKey ``pubkey``.
|
## Initialize ProtoField with PublicKey ``pubkey``.
|
||||||
result = initProtoField(index, pubkey.getBytes())
|
result = initProtoField(index, pubkey.getBytes().tryGet())
|
||||||
|
|
||||||
proc initProtoField*(index: int, seckey: PrivateKey): ProtoField =
|
proc initProtoField*(index: int, seckey: PrivateKey): ProtoField {.raises: [Defect, ResultError[CryptoError]].} =
|
||||||
## Initialize ProtoField with PrivateKey ``seckey``.
|
## Initialize ProtoField with PrivateKey ``seckey``.
|
||||||
result = initProtoField(index, seckey.getBytes())
|
result = initProtoField(index, seckey.getBytes().tryGet())
|
||||||
|
|
||||||
proc initProtoField*(index: int, sig: Signature): ProtoField =
|
proc initProtoField*(index: int, sig: Signature): ProtoField =
|
||||||
## Initialize ProtoField with Signature ``sig``.
|
## Initialize ProtoField with Signature ``sig``.
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
## BearSSL library <https://bearssl.org/>
|
## BearSSL library <https://bearssl.org/>
|
||||||
## Copyright(C) 2018 Thomas Pornin <pornin@bolet.org>.
|
## Copyright(C) 2018 Thomas Pornin <pornin@bolet.org>.
|
||||||
|
|
||||||
|
{.push raises: [Defect].}
|
||||||
|
|
||||||
import bearssl
|
import bearssl
|
||||||
import nimcrypto/utils
|
import nimcrypto/utils
|
||||||
import minasn1
|
import minasn1
|
||||||
|
@ -58,11 +60,14 @@ type
|
||||||
|
|
||||||
EcPKI* = EcPrivateKey | EcPublicKey | EcSignature
|
EcPKI* = EcPrivateKey | EcPublicKey | EcSignature
|
||||||
|
|
||||||
EcError* = object of CatchableError
|
EcError* = enum
|
||||||
EcKeyIncorrectError* = object of EcError
|
EcRngError,
|
||||||
EcRngError* = object of EcError
|
EcKeyGenError,
|
||||||
EcPublicKeyError* = object of EcError
|
EcPublicKeyError,
|
||||||
EcSignatureError* = object of EcError
|
EcKeyIncorrectError,
|
||||||
|
EcSignatureError
|
||||||
|
|
||||||
|
EcResult*[T] = Result[T, EcError]
|
||||||
|
|
||||||
const
|
const
|
||||||
EcSupportedCurvesCint* = {cint(Secp256r1), cint(Secp384r1), cint(Secp521r1)}
|
EcSupportedCurvesCint* = {cint(Secp256r1), cint(Secp384r1), cint(Secp521r1)}
|
||||||
|
@ -222,7 +227,7 @@ 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): EcPrivateKey =
|
proc random*(t: typedesc[EcPrivateKey], kind: EcCurveKind): 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.
|
||||||
##
|
##
|
||||||
|
@ -232,37 +237,46 @@ proc random*(t: typedesc[EcPrivateKey], kind: EcCurveKind): EcPrivateKey =
|
||||||
var seeder = brPrngSeederSystem(nil)
|
var seeder = brPrngSeederSystem(nil)
|
||||||
brHmacDrbgInit(addr rng, addr sha256Vtable, nil, 0)
|
brHmacDrbgInit(addr rng, addr sha256Vtable, nil, 0)
|
||||||
if seeder(addr rng.vtable) == 0:
|
if seeder(addr rng.vtable) == 0:
|
||||||
raise newException(ValueError, "Could not seed RNG")
|
return err(EcRngError)
|
||||||
var ecimp = brEcGetDefault()
|
var ecimp = brEcGetDefault()
|
||||||
result = new EcPrivateKey
|
var res = new EcPrivateKey
|
||||||
result.buffer = newSeq[byte](BR_EC_KBUF_PRIV_MAX_SIZE)
|
res.buffer = newSeq[byte](BR_EC_KBUF_PRIV_MAX_SIZE)
|
||||||
if brEcKeygen(addr rng.vtable, ecimp,
|
if brEcKeygen(addr rng.vtable, ecimp,
|
||||||
addr result.key, addr result.buffer[0],
|
addr res.key, addr res.buffer[0],
|
||||||
cast[cint](kind)) == 0:
|
cast[cint](kind)) == 0:
|
||||||
raise newException(ValueError, "Could not generate private key")
|
err(EcKeyGenError)
|
||||||
|
else:
|
||||||
|
ok(res)
|
||||||
|
|
||||||
proc getKey*(seckey: EcPrivateKey): EcPublicKey =
|
proc getKey*(seckey: EcPrivateKey): EcResult[EcPublicKey] =
|
||||||
## Calculate and return EC public key from private key ``seckey``.
|
## Calculate and return EC public key from private key ``seckey``.
|
||||||
doAssert(not isNil(seckey))
|
if isNil(seckey):
|
||||||
|
return err(EcKeyIncorrectError)
|
||||||
|
|
||||||
var ecimp = brEcGetDefault()
|
var ecimp = brEcGetDefault()
|
||||||
if seckey.key.curve in EcSupportedCurvesCint:
|
if seckey.key.curve in EcSupportedCurvesCint:
|
||||||
var length = getPublicKeyLength(cast[EcCurveKind](seckey.key.curve))
|
var length = getPublicKeyLength(cast[EcCurveKind](seckey.key.curve))
|
||||||
result = new EcPublicKey
|
var res = new EcPublicKey
|
||||||
result.buffer = newSeq[byte](length)
|
res.buffer = newSeq[byte](length)
|
||||||
if brEcComputePublicKey(ecimp, addr result.key,
|
if brEcComputePublicKey(ecimp, addr res.key,
|
||||||
addr result.buffer[0], unsafeAddr seckey.key) == 0:
|
addr res.buffer[0], unsafeAddr seckey.key) == 0:
|
||||||
raise newException(EcKeyIncorrectError, "Could not calculate public key")
|
err(EcKeyIncorrectError)
|
||||||
|
else:
|
||||||
|
ok(res)
|
||||||
else:
|
else:
|
||||||
raise newException(EcKeyIncorrectError, "Incorrect private key")
|
err(EcKeyIncorrectError)
|
||||||
|
|
||||||
proc random*(t: typedesc[EcKeyPair], kind: EcCurveKind): EcKeyPair {.inline.} =
|
proc random*(t: typedesc[EcKeyPair], kind: EcCurveKind): EcResult[EcKeyPair] =
|
||||||
## 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).
|
||||||
result.seckey = EcPrivateKey.random(kind)
|
let
|
||||||
result.pubkey = result.seckey.getKey()
|
seckey = ? EcPrivateKey.random(kind)
|
||||||
|
pubkey = ? seckey.getKey()
|
||||||
|
key = EcKeyPair(seckey: seckey, pubkey: pubkey)
|
||||||
|
ok(key)
|
||||||
|
|
||||||
proc `$`*(seckey: EcPrivateKey): string =
|
proc `$`*(seckey: EcPrivateKey): string =
|
||||||
## Return string representation of EC private key.
|
## Return string representation of EC private key.
|
||||||
|
@ -303,29 +317,37 @@ proc `$`*(sig: EcSignature): string =
|
||||||
else:
|
else:
|
||||||
result = toHex(sig.buffer)
|
result = toHex(sig.buffer)
|
||||||
|
|
||||||
proc toRawBytes*(seckey: EcPrivateKey, data: var openarray[byte]): int =
|
proc toRawBytes*(seckey: EcPrivateKey, data: var openarray[byte]): EcResult[int] =
|
||||||
## Serialize EC private key ``seckey`` to raw binary form and store it
|
## Serialize EC private key ``seckey`` to raw binary form and store it
|
||||||
## to ``data``.
|
## to ``data``.
|
||||||
##
|
##
|
||||||
## Returns number of bytes (octets) needed to store EC private key, or `0`
|
## Returns number of bytes (octets) needed to store EC private key, or `0`
|
||||||
## if private key is not in supported curve.
|
## if private key is not in supported curve.
|
||||||
doAssert(not isNil(seckey))
|
if isNil(seckey):
|
||||||
|
return err(EcKeyIncorrectError)
|
||||||
if seckey.key.curve in EcSupportedCurvesCint:
|
if seckey.key.curve in EcSupportedCurvesCint:
|
||||||
result = getPrivateKeyLength(cast[EcCurveKind](seckey.key.curve))
|
let klen = getPrivateKeyLength(cast[EcCurveKind](seckey.key.curve))
|
||||||
if len(data) >= result:
|
if len(data) >= klen:
|
||||||
copyMem(addr data[0], unsafeAddr seckey.buffer[0], result)
|
copyMem(addr data[0], unsafeAddr seckey.buffer[0], klen)
|
||||||
|
ok(klen)
|
||||||
|
else:
|
||||||
|
err(EcKeyIncorrectError)
|
||||||
|
|
||||||
proc toRawBytes*(pubkey: EcPublicKey, data: var openarray[byte]): int =
|
proc toRawBytes*(pubkey: EcPublicKey, data: var openarray[byte]): EcResult[int] =
|
||||||
## Serialize EC public key ``pubkey`` to uncompressed form specified in
|
## Serialize EC public key ``pubkey`` to uncompressed form specified in
|
||||||
## section 4.3.6 of ANSI X9.62.
|
## section 4.3.6 of ANSI X9.62.
|
||||||
##
|
##
|
||||||
## Returns number of bytes (octets) needed to store EC public key, or `0`
|
## Returns number of bytes (octets) needed to store EC public key, or `0`
|
||||||
## if public key is not in supported curve.
|
## if public key is not in supported curve.
|
||||||
doAssert(not isNil(pubkey))
|
if isNil(pubkey):
|
||||||
|
return err(EcKeyIncorrectError)
|
||||||
if pubkey.key.curve in EcSupportedCurvesCint:
|
if pubkey.key.curve in EcSupportedCurvesCint:
|
||||||
result = getPublicKeyLength(cast[EcCurveKind](pubkey.key.curve))
|
let klen = getPublicKeyLength(cast[EcCurveKind](pubkey.key.curve))
|
||||||
if len(data) >= result:
|
if len(data) >= klen:
|
||||||
copyMem(addr data[0], unsafeAddr pubkey.buffer[0], result)
|
copyMem(addr data[0], unsafeAddr pubkey.buffer[0], klen)
|
||||||
|
ok(klen)
|
||||||
|
else:
|
||||||
|
err(EcKeyIncorrectError)
|
||||||
|
|
||||||
proc toRawBytes*(sig: EcSignature, data: var openarray[byte]): int =
|
proc toRawBytes*(sig: EcSignature, data: var openarray[byte]): int =
|
||||||
## Serialize EC signature ``sig`` to raw binary form and store it to ``data``.
|
## Serialize EC signature ``sig`` to raw binary form and store it to ``data``.
|
||||||
|
@ -338,16 +360,17 @@ proc toRawBytes*(sig: EcSignature, data: var openarray[byte]): int =
|
||||||
if len(sig.buffer) > 0:
|
if len(sig.buffer) > 0:
|
||||||
copyMem(addr data[0], unsafeAddr sig.buffer[0], len(sig.buffer))
|
copyMem(addr data[0], unsafeAddr sig.buffer[0], len(sig.buffer))
|
||||||
|
|
||||||
proc toBytes*(seckey: EcPrivateKey, data: var openarray[byte]): int =
|
proc toBytes*(seckey: EcPrivateKey, data: var openarray[byte]): EcResult[int] =
|
||||||
## Serialize EC private key ``seckey`` to ASN.1 DER binary form and store it
|
## Serialize EC private key ``seckey`` to ASN.1 DER binary form and store it
|
||||||
## to ``data``.
|
## to ``data``.
|
||||||
##
|
##
|
||||||
## Procedure returns number of bytes (octets) needed to store EC private key,
|
## Procedure returns number of bytes (octets) needed to store EC private key,
|
||||||
## or `0` if private key is not in supported curve.
|
## or `0` if private key is not in supported curve.
|
||||||
doAssert(not isNil(seckey))
|
if isNil(seckey):
|
||||||
|
return err(EcKeyIncorrectError)
|
||||||
if seckey.key.curve in EcSupportedCurvesCint:
|
if seckey.key.curve in EcSupportedCurvesCint:
|
||||||
var offset, length: int
|
var offset, length: int
|
||||||
var pubkey = seckey.getKey()
|
var pubkey = ? seckey.getKey()
|
||||||
var b = Asn1Buffer.init()
|
var b = Asn1Buffer.init()
|
||||||
var p = Asn1Composite.init(Asn1Tag.Sequence)
|
var p = Asn1Composite.init(Asn1Tag.Sequence)
|
||||||
var c0 = Asn1Composite.init(0)
|
var c0 = Asn1Composite.init(0)
|
||||||
|
@ -374,17 +397,23 @@ proc toBytes*(seckey: EcPrivateKey, data: var openarray[byte]): int =
|
||||||
p.finish()
|
p.finish()
|
||||||
b.write(p)
|
b.write(p)
|
||||||
b.finish()
|
b.finish()
|
||||||
result = len(b)
|
var blen = len(b)
|
||||||
if len(data) >= result:
|
if len(data) >= blen:
|
||||||
copyMem(addr data[0], addr b.buffer[0], result)
|
copyMem(addr data[0], addr b.buffer[0], blen)
|
||||||
|
# ok anyway, since it might have been a query...
|
||||||
|
ok(blen)
|
||||||
|
else:
|
||||||
|
err(EcKeyIncorrectError)
|
||||||
|
|
||||||
proc toBytes*(pubkey: EcPublicKey, data: var openarray[byte]): int =
|
|
||||||
|
proc toBytes*(pubkey: EcPublicKey, data: var openarray[byte]): EcResult[int] =
|
||||||
## Serialize EC public key ``pubkey`` to ASN.1 DER binary form and store it
|
## Serialize EC public key ``pubkey`` to ASN.1 DER binary form and store it
|
||||||
## to ``data``.
|
## to ``data``.
|
||||||
##
|
##
|
||||||
## Procedure returns number of bytes (octets) needed to store EC public key,
|
## Procedure returns number of bytes (octets) needed to store EC public key,
|
||||||
## or `0` if public key is not in supported curve.
|
## or `0` if public key is not in supported curve.
|
||||||
doAssert(not isNil(pubkey))
|
if isNil(pubkey):
|
||||||
|
return err(EcKeyIncorrectError)
|
||||||
if pubkey.key.curve in EcSupportedCurvesCint:
|
if pubkey.key.curve in EcSupportedCurvesCint:
|
||||||
var b = Asn1Buffer.init()
|
var b = Asn1Buffer.init()
|
||||||
var p = Asn1Composite.init(Asn1Tag.Sequence)
|
var p = Asn1Composite.init(Asn1Tag.Sequence)
|
||||||
|
@ -405,80 +434,97 @@ proc toBytes*(pubkey: EcPublicKey, data: var openarray[byte]): int =
|
||||||
p.finish()
|
p.finish()
|
||||||
b.write(p)
|
b.write(p)
|
||||||
b.finish()
|
b.finish()
|
||||||
result = len(b)
|
var blen = len(b)
|
||||||
if len(data) >= result:
|
if len(data) >= blen:
|
||||||
copyMem(addr data[0], addr b.buffer[0], result)
|
copyMem(addr data[0], addr b.buffer[0], blen)
|
||||||
|
ok(blen)
|
||||||
|
else:
|
||||||
|
err(EcKeyIncorrectError)
|
||||||
|
|
||||||
proc toBytes*(sig: EcSignature, data: var openarray[byte]): int =
|
proc toBytes*(sig: EcSignature, data: var openarray[byte]): EcResult[int] =
|
||||||
## Serialize EC signature ``sig`` to ASN.1 DER binary form and store it
|
## Serialize EC signature ``sig`` to ASN.1 DER binary form and store it
|
||||||
## to ``data``.
|
## to ``data``.
|
||||||
##
|
##
|
||||||
## Procedure returns number of bytes (octets) needed to store EC signature,
|
## Procedure returns number of bytes (octets) needed to store EC signature,
|
||||||
## or `0` if signature is not in supported curve.
|
## or `0` if signature is not in supported curve.
|
||||||
doAssert(not isNil(sig))
|
if isNil(sig):
|
||||||
result = len(sig.buffer)
|
return err(EcSignatureError)
|
||||||
if len(data) >= result:
|
let slen = len(sig.buffer)
|
||||||
copyMem(addr data[0], unsafeAddr sig.buffer[0], result)
|
if len(data) >= slen:
|
||||||
|
copyMem(addr data[0], unsafeAddr sig.buffer[0], slen)
|
||||||
|
ok(slen)
|
||||||
|
|
||||||
proc getBytes*(seckey: EcPrivateKey): seq[byte] =
|
proc getBytes*(seckey: EcPrivateKey): EcResult[seq[byte]] =
|
||||||
## Serialize EC private key ``seckey`` to ASN.1 DER binary form and return it.
|
## Serialize EC private key ``seckey`` to ASN.1 DER binary form and return it.
|
||||||
doAssert(not isNil(seckey))
|
if isNil(seckey):
|
||||||
|
return err(EcKeyIncorrectError)
|
||||||
if seckey.key.curve in EcSupportedCurvesCint:
|
if seckey.key.curve in EcSupportedCurvesCint:
|
||||||
result = newSeq[byte]()
|
var res = newSeq[byte]()
|
||||||
let length = seckey.toBytes(result)
|
let length = ? seckey.toBytes(res)
|
||||||
result.setLen(length)
|
res.setLen(length)
|
||||||
discard seckey.toBytes(result)
|
discard ? seckey.toBytes(res)
|
||||||
|
ok(res)
|
||||||
else:
|
else:
|
||||||
raise newException(EcKeyIncorrectError, "Incorrect private key")
|
err(EcKeyIncorrectError)
|
||||||
|
|
||||||
proc getBytes*(pubkey: EcPublicKey): seq[byte] =
|
proc getBytes*(pubkey: EcPublicKey): EcResult[seq[byte]] =
|
||||||
## Serialize EC public key ``pubkey`` to ASN.1 DER binary form and return it.
|
## Serialize EC public key ``pubkey`` to ASN.1 DER binary form and return it.
|
||||||
doAssert(not isNil(pubkey))
|
if isNil(pubkey):
|
||||||
|
return err(EcKeyIncorrectError)
|
||||||
if pubkey.key.curve in EcSupportedCurvesCint:
|
if pubkey.key.curve in EcSupportedCurvesCint:
|
||||||
result = newSeq[byte]()
|
var res = newSeq[byte]()
|
||||||
let length = pubkey.toBytes(result)
|
let length = ? pubkey.toBytes(res)
|
||||||
result.setLen(length)
|
res.setLen(length)
|
||||||
discard pubkey.toBytes(result)
|
discard ? pubkey.toBytes(res)
|
||||||
|
ok(res)
|
||||||
else:
|
else:
|
||||||
raise newException(EcKeyIncorrectError, "Incorrect public key")
|
err(EcKeyIncorrectError)
|
||||||
|
|
||||||
proc getBytes*(sig: EcSignature): seq[byte] =
|
proc getBytes*(sig: EcSignature): EcResult[seq[byte]] =
|
||||||
## Serialize EC signature ``sig`` to ASN.1 DER binary form and return it.
|
## Serialize EC signature ``sig`` to ASN.1 DER binary form and return it.
|
||||||
doAssert(not isNil(sig))
|
if isNil(sig):
|
||||||
result = newSeq[byte]()
|
return err(EcSignatureError)
|
||||||
let length = sig.toBytes(result)
|
var res = newSeq[byte]()
|
||||||
result.setLen(length)
|
let length = ? sig.toBytes(res)
|
||||||
discard sig.toBytes(result)
|
res.setLen(length)
|
||||||
|
discard ? sig.toBytes(res)
|
||||||
|
ok(res)
|
||||||
|
|
||||||
proc getRawBytes*(seckey: EcPrivateKey): seq[byte] =
|
proc getRawBytes*(seckey: EcPrivateKey): EcResult[seq[byte]] =
|
||||||
## Serialize EC private key ``seckey`` to raw binary form and return it.
|
## Serialize EC private key ``seckey`` to raw binary form and return it.
|
||||||
doAssert(not isNil(seckey))
|
if isNil(seckey):
|
||||||
|
return err(EcKeyIncorrectError)
|
||||||
if seckey.key.curve in EcSupportedCurvesCint:
|
if seckey.key.curve in EcSupportedCurvesCint:
|
||||||
result = newSeq[byte]()
|
var res = newSeq[byte]()
|
||||||
let length = seckey.toRawBytes(result)
|
let length = ? seckey.toRawBytes(res)
|
||||||
result.setLen(length)
|
res.setLen(length)
|
||||||
discard seckey.toRawBytes(result)
|
discard ? seckey.toRawBytes(res)
|
||||||
|
ok(res)
|
||||||
else:
|
else:
|
||||||
raise newException(EcKeyIncorrectError, "Incorrect private key")
|
err(EcKeyIncorrectError)
|
||||||
|
|
||||||
proc getRawBytes*(pubkey: EcPublicKey): seq[byte] =
|
proc getRawBytes*(pubkey: EcPublicKey): EcResult[seq[byte]] =
|
||||||
## Serialize EC public key ``pubkey`` to raw binary form and return it.
|
## Serialize EC public key ``pubkey`` to raw binary form and return it.
|
||||||
doAssert(not isNil(pubkey))
|
if isNil(pubkey):
|
||||||
|
return err(EcKeyIncorrectError)
|
||||||
if pubkey.key.curve in EcSupportedCurvesCint:
|
if pubkey.key.curve in EcSupportedCurvesCint:
|
||||||
result = newSeq[byte]()
|
var res = newSeq[byte]()
|
||||||
let length = pubkey.toRawBytes(result)
|
let length = ? pubkey.toRawBytes(res)
|
||||||
result.setLen(length)
|
res.setLen(length)
|
||||||
discard pubkey.toRawBytes(result)
|
discard ? pubkey.toRawBytes(res)
|
||||||
|
ok(res)
|
||||||
else:
|
else:
|
||||||
raise newException(EcKeyIncorrectError, "Incorrect public key")
|
return err(EcKeyIncorrectError)
|
||||||
|
|
||||||
proc getRawBytes*(sig: EcSignature): seq[byte] =
|
proc getRawBytes*(sig: EcSignature): EcResult[seq[byte]] =
|
||||||
## Serialize EC signature ``sig`` to raw binary form and return it.
|
## Serialize EC signature ``sig`` to raw binary form and return it.
|
||||||
doAssert(not isNil(sig))
|
if isNil(sig):
|
||||||
result = newSeq[byte]()
|
return err(EcSignatureError)
|
||||||
let length = sig.toBytes(result)
|
var res = newSeq[byte]()
|
||||||
result.setLen(length)
|
let length = ? sig.toBytes(res)
|
||||||
discard sig.toBytes(result)
|
res.setLen(length)
|
||||||
|
discard ? sig.toBytes(res)
|
||||||
|
ok(res)
|
||||||
|
|
||||||
proc `==`*(pubkey1, pubkey2: EcPublicKey): bool =
|
proc `==`*(pubkey1, pubkey2: EcPublicKey): bool =
|
||||||
## Returns ``true`` if both keys ``pubkey1`` and ``pubkey2`` are equal.
|
## Returns ``true`` if both keys ``pubkey1`` and ``pubkey2`` are equal.
|
||||||
|
@ -663,34 +709,43 @@ proc init*[T: EcPKI](sospk: var T, data: string): Result[void, Asn1Error] {.inli
|
||||||
## Procedure returns ``Asn1Status``.
|
## Procedure returns ``Asn1Status``.
|
||||||
sospk.init(fromHex(data))
|
sospk.init(fromHex(data))
|
||||||
|
|
||||||
proc init*(t: typedesc[EcPrivateKey], data: openarray[byte]): EcPrivateKey =
|
proc init*(t: typedesc[EcPrivateKey], data: openarray[byte]): EcResult[EcPrivateKey] =
|
||||||
## Initialize EC private key from ASN.1 DER binary representation ``data`` and
|
## Initialize EC private key from ASN.1 DER binary representation ``data`` and
|
||||||
## return constructed object.
|
## return constructed object.
|
||||||
let res = result.init(data)
|
var key: EcPrivateKey
|
||||||
|
let res = key.init(data)
|
||||||
if res.isErr:
|
if res.isErr:
|
||||||
raise newException(EcKeyIncorrectError,
|
err(EcKeyIncorrectError)
|
||||||
"Incorrect private key (" & $res.error & ")")
|
else:
|
||||||
|
ok(key)
|
||||||
|
|
||||||
proc init*(t: typedesc[EcPublicKey], data: openarray[byte]): EcPublicKey =
|
proc init*(t: typedesc[EcPublicKey], data: openarray[byte]): EcResult[EcPublicKey] =
|
||||||
## Initialize EC public key from ASN.1 DER binary representation ``data`` and
|
## Initialize EC public key from ASN.1 DER binary representation ``data`` and
|
||||||
## return constructed object.
|
## return constructed object.
|
||||||
let res = result.init(data)
|
var key: EcPublicKey
|
||||||
|
let res = key.init(data)
|
||||||
if res.isErr:
|
if res.isErr:
|
||||||
raise newException(EcKeyIncorrectError,
|
err(EcKeyIncorrectError)
|
||||||
"Incorrect public key (" & $res.error & ")")
|
else:
|
||||||
|
ok(key)
|
||||||
|
|
||||||
proc init*(t: typedesc[EcSignature], data: openarray[byte]): EcSignature =
|
proc init*(t: typedesc[EcSignature], data: openarray[byte]): EcResult[EcSignature] =
|
||||||
## Initialize EC signature from raw binary representation ``data`` and
|
## Initialize EC signature from raw binary representation ``data`` and
|
||||||
## return constructed object.
|
## return constructed object.
|
||||||
let res = result.init(data)
|
var sig: EcSignature
|
||||||
|
let res = sig.init(data)
|
||||||
if res.isErr:
|
if res.isErr:
|
||||||
raise newException(EcKeyIncorrectError,
|
err(EcSignatureError)
|
||||||
"Incorrect signature (" & $res.error & ")")
|
else:
|
||||||
|
ok(sig)
|
||||||
|
|
||||||
proc init*[T: EcPKI](t: typedesc[T], data: string): T {.inline.} =
|
proc init*[T: EcPKI](t: typedesc[T], data: string): EcResult[T] =
|
||||||
## Initialize EC `private key`, `public key` or `signature` from hexadecimal
|
## Initialize EC `private key`, `public key` or `signature` from hexadecimal
|
||||||
## string representation ``data`` and return constructed object.
|
## string representation ``data`` and return constructed object.
|
||||||
result = t.init(fromHex(data))
|
try:
|
||||||
|
t.init(fromHex(data))
|
||||||
|
except ValueError:
|
||||||
|
err(EcKeyIncorrectError)
|
||||||
|
|
||||||
proc initRaw*(key: var EcPrivateKey, data: openarray[byte]): bool =
|
proc initRaw*(key: var EcPrivateKey, data: openarray[byte]): bool =
|
||||||
## Initialize EC `private key` or `scalar` ``key`` from raw binary
|
## Initialize EC `private key` or `scalar` ``key`` from raw binary
|
||||||
|
@ -776,23 +831,32 @@ proc initRaw*[T: EcPKI](sospk: var T, data: string): bool {.inline.} =
|
||||||
## Procedure returns ``true`` on success, ``false`` otherwise.
|
## Procedure returns ``true`` on success, ``false`` otherwise.
|
||||||
result = sospk.initRaw(fromHex(data))
|
result = sospk.initRaw(fromHex(data))
|
||||||
|
|
||||||
proc initRaw*(t: typedesc[EcPrivateKey], data: openarray[byte]): EcPrivateKey =
|
proc initRaw*(t: typedesc[EcPrivateKey], data: openarray[byte]): EcResult[EcPrivateKey] =
|
||||||
## Initialize EC private key from raw binary representation ``data`` and
|
## Initialize EC private key from raw binary representation ``data`` and
|
||||||
## return constructed object.
|
## return constructed object.
|
||||||
if not result.initRaw(data):
|
var res: EcPrivateKey
|
||||||
raise newException(EcKeyIncorrectError, "Incorrect private key")
|
if not res.initRaw(data):
|
||||||
|
err(EcKeyIncorrectError)
|
||||||
|
else:
|
||||||
|
ok(res)
|
||||||
|
|
||||||
proc initRaw*(t: typedesc[EcPublicKey], data: openarray[byte]): EcPublicKey =
|
proc initRaw*(t: typedesc[EcPublicKey], data: openarray[byte]): EcResult[EcPublicKey] =
|
||||||
## Initialize EC public key from raw binary representation ``data`` and
|
## Initialize EC public key from raw binary representation ``data`` and
|
||||||
## return constructed object.
|
## return constructed object.
|
||||||
if not result.initRaw(data):
|
var res: EcPublicKey
|
||||||
raise newException(EcKeyIncorrectError, "Incorrect public key")
|
if not res.initRaw(data):
|
||||||
|
err(EcKeyIncorrectError)
|
||||||
|
else:
|
||||||
|
ok(res)
|
||||||
|
|
||||||
proc initRaw*(t: typedesc[EcSignature], data: openarray[byte]): EcSignature =
|
proc initRaw*(t: typedesc[EcSignature], data: openarray[byte]): EcResult[EcSignature] =
|
||||||
## Initialize EC signature from raw binary representation ``data`` and
|
## Initialize EC signature from raw binary representation ``data`` and
|
||||||
## return constructed object.
|
## return constructed object.
|
||||||
if not result.initRaw(data):
|
var res: EcSignature
|
||||||
raise newException(EcKeyIncorrectError, "Incorrect signature")
|
if not res.initRaw(data):
|
||||||
|
err(EcSignatureError)
|
||||||
|
else:
|
||||||
|
ok(res)
|
||||||
|
|
||||||
proc initRaw*[T: EcPKI](t: typedesc[T], data: string): T {.inline.} =
|
proc initRaw*[T: EcPKI](t: typedesc[T], data: string): T {.inline.} =
|
||||||
## Initialize EC `private key`, `public key` or `signature` from raw
|
## Initialize EC `private key`, `public key` or `signature` from raw
|
||||||
|
@ -858,15 +922,16 @@ proc getSecret*(pubkey: EcPublicKey, seckey: EcPrivateKey): seq[byte] =
|
||||||
copyMem(addr result[0], addr data[0], res)
|
copyMem(addr result[0], addr data[0], res)
|
||||||
|
|
||||||
proc sign*[T: byte|char](seckey: EcPrivateKey,
|
proc sign*[T: byte|char](seckey: EcPrivateKey,
|
||||||
message: openarray[T]): EcSignature {.gcsafe.} =
|
message: openarray[T]): EcResult[EcSignature] {.gcsafe.} =
|
||||||
## Get ECDSA signature of data ``message`` using private key ``seckey``.
|
## Get ECDSA signature of data ``message`` using private key ``seckey``.
|
||||||
doAssert(not isNil(seckey))
|
if isNil(seckey):
|
||||||
|
return err(EcKeyIncorrectError)
|
||||||
var hc: BrHashCompatContext
|
var hc: BrHashCompatContext
|
||||||
var hash: array[32, byte]
|
var hash: array[32, byte]
|
||||||
var impl = brEcGetDefault()
|
var impl = brEcGetDefault()
|
||||||
if seckey.key.curve in EcSupportedCurvesCint:
|
if seckey.key.curve in EcSupportedCurvesCint:
|
||||||
result = new EcSignature
|
var sig = new EcSignature
|
||||||
result.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:
|
||||||
|
@ -875,15 +940,16 @@ proc sign*[T: byte|char](seckey: EcPrivateKey,
|
||||||
kv.update(addr hc.vtable, nil, 0)
|
kv.update(addr hc.vtable, nil, 0)
|
||||||
kv.output(addr hc.vtable, addr hash[0])
|
kv.output(addr hc.vtable, addr hash[0])
|
||||||
let res = brEcdsaSignAsn1(impl, kv, addr hash[0], addr seckey.key,
|
let res = brEcdsaSignAsn1(impl, kv, addr hash[0], addr seckey.key,
|
||||||
addr result.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)
|
||||||
if res != 0:
|
if res != 0:
|
||||||
result.buffer.setLen(res)
|
sig.buffer.setLen(res)
|
||||||
|
ok(sig)
|
||||||
else:
|
else:
|
||||||
raise newException(EcSignatureError, "Could not make signature")
|
err(EcSignatureError)
|
||||||
else:
|
else:
|
||||||
raise newException(EcKeyIncorrectError, "Incorrect private key")
|
err(EcKeyIncorrectError)
|
||||||
|
|
||||||
proc verify*[T: byte|char](sig: EcSignature, message: openarray[T],
|
proc verify*[T: byte|char](sig: EcSignature, message: openarray[T],
|
||||||
pubkey: EcPublicKey): bool {.inline.} =
|
pubkey: EcPublicKey): bool {.inline.} =
|
||||||
|
|
|
@ -10,8 +10,13 @@
|
||||||
## This module implements ED25519.
|
## This module implements ED25519.
|
||||||
## This code is a port of the public domain, "ref10" implementation of ed25519
|
## This code is a port of the public domain, "ref10" implementation of ed25519
|
||||||
## from SUPERCOP.
|
## from SUPERCOP.
|
||||||
|
|
||||||
|
{.push raises: Defect.}
|
||||||
|
|
||||||
import constants
|
import constants
|
||||||
import nimcrypto/[hash, sha2, sysrand, utils]
|
import nimcrypto/[hash, sha2, sysrand, utils]
|
||||||
|
import stew/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
|
||||||
|
@ -38,9 +43,9 @@ type
|
||||||
seckey*: EdPrivateKey
|
seckey*: EdPrivateKey
|
||||||
pubkey*: EdPublicKey
|
pubkey*: EdPublicKey
|
||||||
|
|
||||||
EdError* = object of CatchableError
|
EdError* = enum
|
||||||
EdRngError* = object of EdError
|
EdRngError,
|
||||||
EdIncorrectError* = object of EdError
|
EdIncorrectError
|
||||||
|
|
||||||
proc `-`(x: uint32): uint32 {.inline.} =
|
proc `-`(x: uint32): uint32 {.inline.} =
|
||||||
result = (0xFFFF_FFFF'u32 - x) + 1'u32
|
result = (0xFFFF_FFFF'u32 - x) + 1'u32
|
||||||
|
@ -1632,40 +1637,47 @@ proc checkScalar*(scalar: openarray[byte]): uint32 =
|
||||||
for u in scalar:
|
for u in scalar:
|
||||||
z = z or u
|
z = z or u
|
||||||
if len(scalar) == len(CurveOrder):
|
if len(scalar) == len(CurveOrder):
|
||||||
for i in countdown(len(scalar) - 1, 0):
|
for i in countdown(scalar.high, 0):
|
||||||
c = c or (-(cast[int32](EQ0(c))) and CMP(scalar[i], CurveOrder[i]))
|
c = c or (-(cast[int32](EQ0(c))) and CMP(scalar[i], CurveOrder[i]))
|
||||||
else:
|
else:
|
||||||
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]): EdPrivateKey =
|
proc random*(t: typedesc[EdPrivateKey]): Result[EdPrivateKey, EdError] =
|
||||||
## Generate new random ED25519 private key using OS specific CSPRNG.
|
## Generate new random ED25519 private key using OS specific CSPRNG.
|
||||||
var
|
var
|
||||||
point: GeP3
|
point: GeP3
|
||||||
pk: array[EdPublicKeySize, byte]
|
pk: array[EdPublicKeySize, byte]
|
||||||
if randomBytes(result.data.toOpenArray(0, 31)) != 32:
|
res: EdPrivateKey
|
||||||
raise newException(EdRngError, "Could not generate random data")
|
if randomBytes(res.data.toOpenArray(0, 31)) != 32:
|
||||||
var hh = sha512.digest(result.data.toOpenArray(0, 31))
|
err(EdRngError)
|
||||||
hh.data[0] = hh.data[0] and 0xF8'u8
|
else:
|
||||||
hh.data[31] = hh.data[31] and 0x3F'u8
|
var hh = sha512.digest(res.data.toOpenArray(0, 31))
|
||||||
hh.data[31] = hh.data[31] or 0x40'u8
|
hh.data[0] = hh.data[0] and 0xF8'u8
|
||||||
geScalarMultBase(point, hh.data)
|
hh.data[31] = hh.data[31] and 0x3F'u8
|
||||||
geP3ToBytes(pk, point)
|
hh.data[31] = hh.data[31] or 0x40'u8
|
||||||
copyMem(addr result.data[32], addr pk[0], 32)
|
geScalarMultBase(point, hh.data)
|
||||||
|
geP3ToBytes(pk, point)
|
||||||
|
copyMem(addr res.data[32], addr pk[0], 32)
|
||||||
|
ok(res)
|
||||||
|
|
||||||
proc random*(t: typedesc[EdKeyPair]): EdKeyPair =
|
proc random*(t: typedesc[EdKeyPair]): Result[EdKeyPair, EdError] =
|
||||||
## 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 point: GeP3
|
var
|
||||||
if randomBytes(result.seckey.data.toOpenArray(0, 31)) != 32:
|
point: GeP3
|
||||||
raise newException(EdRngError, "Could not generate random data")
|
res: EdKeyPair
|
||||||
var hh = sha512.digest(result.seckey.data.toOpenArray(0, 31))
|
if randomBytes(res.seckey.data.toOpenArray(0, 31)) != 32:
|
||||||
hh.data[0] = hh.data[0] and 0xF8'u8
|
err(EdRngError)
|
||||||
hh.data[31] = hh.data[31] and 0x3F'u8
|
else:
|
||||||
hh.data[31] = hh.data[31] or 0x40'u8
|
var hh = sha512.digest(res.seckey.data.toOpenArray(0, 31))
|
||||||
geScalarMultBase(point, hh.data)
|
hh.data[0] = hh.data[0] and 0xF8'u8
|
||||||
geP3ToBytes(result.pubkey.data, point)
|
hh.data[31] = hh.data[31] and 0x3F'u8
|
||||||
copyMem(addr result.seckey.data[32], addr result.pubkey.data[0], 32)
|
hh.data[31] = hh.data[31] or 0x40'u8
|
||||||
|
geScalarMultBase(point, hh.data)
|
||||||
|
geP3ToBytes(res.pubkey.data, point)
|
||||||
|
copyMem(addr res.seckey.data[32], addr res.pubkey.data[0], 32)
|
||||||
|
ok(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``.
|
||||||
|
@ -1766,57 +1778,84 @@ proc init*(key: var EdPrivateKey, data: string): bool =
|
||||||
## representation ``data``.
|
## representation ``data``.
|
||||||
##
|
##
|
||||||
## Procedure returns ``true`` on success.
|
## Procedure returns ``true`` on success.
|
||||||
result = init(key, fromHex(data))
|
try:
|
||||||
|
init(key, fromHex(data))
|
||||||
|
except ValueError:
|
||||||
|
false
|
||||||
|
|
||||||
proc init*(key: var EdPublicKey, data: string): bool =
|
proc init*(key: var EdPublicKey, data: string): bool =
|
||||||
## Initialize ED25519 `public key` ``key`` from hexadecimal string
|
## Initialize ED25519 `public key` ``key`` from hexadecimal string
|
||||||
## representation ``data``.
|
## representation ``data``.
|
||||||
##
|
##
|
||||||
## Procedure returns ``true`` on success.
|
## Procedure returns ``true`` on success.
|
||||||
result = init(key, fromHex(data))
|
try:
|
||||||
|
init(key, fromHex(data))
|
||||||
|
except ValueError:
|
||||||
|
false
|
||||||
|
|
||||||
proc init*(sig: var EdSignature, data: string): bool =
|
proc init*(sig: var EdSignature, data: string): bool =
|
||||||
## Initialize ED25519 `signature` ``sig`` from hexadecimal string
|
## Initialize ED25519 `signature` ``sig`` from hexadecimal string
|
||||||
## representation ``data``.
|
## representation ``data``.
|
||||||
##
|
##
|
||||||
## Procedure returns ``true`` on success.
|
## Procedure returns ``true`` on success.
|
||||||
result = init(sig, fromHex(data))
|
try:
|
||||||
|
init(sig, fromHex(data))
|
||||||
|
except ValueError:
|
||||||
|
false
|
||||||
|
|
||||||
proc init*(t: typedesc[EdPrivateKey], data: openarray[byte]): EdPrivateKey =
|
proc init*(t: typedesc[EdPrivateKey], data: openarray[byte]): Result[EdPrivateKey, EdError] =
|
||||||
## Initialize ED25519 `private key` from raw binary representation ``data``
|
## Initialize ED25519 `private key` from raw binary representation ``data``
|
||||||
## and return constructed object.
|
## and return constructed object.
|
||||||
if not init(result, data):
|
var res: t
|
||||||
raise newException(EdIncorrectError, "Incorrect binary form")
|
if not init(res, data):
|
||||||
|
err(EdIncorrectError)
|
||||||
|
else:
|
||||||
|
ok(res)
|
||||||
|
|
||||||
proc init*(t: typedesc[EdPublicKey], data: openarray[byte]): EdPublicKey =
|
proc init*(t: typedesc[EdPublicKey], data: openarray[byte]): Result[EdPublicKey, EdError] =
|
||||||
## Initialize ED25519 `public key` from raw binary representation ``data``
|
## Initialize ED25519 `public key` from raw binary representation ``data``
|
||||||
## and return constructed object.
|
## and return constructed object.
|
||||||
if not init(result, data):
|
var res: t
|
||||||
raise newException(EdIncorrectError, "Incorrect binary form")
|
if not init(res, data):
|
||||||
|
err(EdIncorrectError)
|
||||||
|
else:
|
||||||
|
ok(res)
|
||||||
|
|
||||||
proc init*(t: typedesc[EdSignature], data: openarray[byte]): EdSignature =
|
proc init*(t: typedesc[EdSignature], data: openarray[byte]): Result[EdSignature, EdError] =
|
||||||
## Initialize ED25519 `signature` from raw binary representation ``data``
|
## Initialize ED25519 `signature` from raw binary representation ``data``
|
||||||
## and return constructed object.
|
## and return constructed object.
|
||||||
if not init(result, data):
|
var res: t
|
||||||
raise newException(EdIncorrectError, "Incorrect binary form")
|
if not init(res, data):
|
||||||
|
err(EdIncorrectError)
|
||||||
|
else:
|
||||||
|
ok(res)
|
||||||
|
|
||||||
proc init*(t: typedesc[EdPrivateKey], data: string): EdPrivateKey =
|
proc init*(t: typedesc[EdPrivateKey], data: string): Result[EdPrivateKey, EdError] =
|
||||||
## Initialize ED25519 `private key` from hexadecimal string representation
|
## Initialize ED25519 `private key` from hexadecimal string representation
|
||||||
## ``data`` and return constructed object.
|
## ``data`` and return constructed object.
|
||||||
if not init(result, data):
|
var res: t
|
||||||
raise newException(EdIncorrectError, "Incorrect binary form")
|
if not init(res, data):
|
||||||
|
err(EdIncorrectError)
|
||||||
|
else:
|
||||||
|
ok(res)
|
||||||
|
|
||||||
proc init*(t: typedesc[EdPublicKey], data: string): EdPublicKey =
|
proc init*(t: typedesc[EdPublicKey], data: string): Result[EdPublicKey, EdError] =
|
||||||
## Initialize ED25519 `public key` from hexadecimal string representation
|
## Initialize ED25519 `public key` from hexadecimal string representation
|
||||||
## ``data`` and return constructed object.
|
## ``data`` and return constructed object.
|
||||||
if not init(result, data):
|
var res: t
|
||||||
raise newException(EdIncorrectError, "Incorrect binary form")
|
if not init(res, data):
|
||||||
|
err(EdIncorrectError)
|
||||||
|
else:
|
||||||
|
ok(res)
|
||||||
|
|
||||||
proc init*(t: typedesc[EdSignature], data: string): EdSignature =
|
proc init*(t: typedesc[EdSignature], data: string): Result[EdSignature, EdError] =
|
||||||
## Initialize ED25519 `signature` from hexadecimal string representation
|
## Initialize ED25519 `signature` from hexadecimal string representation
|
||||||
## ``data`` and return constructed object.
|
## ``data`` and return constructed object.
|
||||||
if not init(result, data):
|
var res: t
|
||||||
raise newException(EdIncorrectError, "Incorrect binary form")
|
if not init(res, data):
|
||||||
|
err(EdIncorrectError)
|
||||||
|
else:
|
||||||
|
ok(res)
|
||||||
|
|
||||||
proc clear*(key: var EdPrivateKey) =
|
proc clear*(key: var EdPrivateKey) =
|
||||||
## Wipe and clear memory of ED25519 `private key`.
|
## Wipe and clear memory of ED25519 `private key`.
|
||||||
|
|
|
@ -106,10 +106,10 @@ const
|
||||||
## Encoded ``NULL`` value.
|
## Encoded ``NULL`` value.
|
||||||
|
|
||||||
template toOpenArray*(ab: Asn1Buffer): untyped =
|
template toOpenArray*(ab: Asn1Buffer): untyped =
|
||||||
toOpenArray(ab.buffer, ab.offset, len(ab.buffer) - 1)
|
toOpenArray(ab.buffer, ab.offset, ab.buffer.high)
|
||||||
|
|
||||||
template toOpenArray*(ac: Asn1Composite): untyped =
|
template toOpenArray*(ac: Asn1Composite): untyped =
|
||||||
toOpenArray(ac.buffer, ac.offset, len(ac.buffer) - 1)
|
toOpenArray(ac.buffer, ac.offset, ac.buffer.high)
|
||||||
|
|
||||||
template toOpenArray*(af: Asn1Field): untyped =
|
template toOpenArray*(af: Asn1Field): untyped =
|
||||||
toOpenArray(af.buffer, af.offset, af.offset + af.length - 1)
|
toOpenArray(af.buffer, af.offset, af.offset + af.length - 1)
|
||||||
|
@ -336,7 +336,7 @@ proc asn1EncodeOid*(dest: var openarray[byte], value: openarray[int]): int =
|
||||||
result += asn1EncodeLength(buffer, oidlen)
|
result += asn1EncodeLength(buffer, oidlen)
|
||||||
result += oidlen
|
result += oidlen
|
||||||
if len(dest) >= result:
|
if len(dest) >= result:
|
||||||
let last = len(dest) - 1
|
let last = dest.high
|
||||||
var offset = 1
|
var offset = 1
|
||||||
dest[0] = Asn1Tag.Oid.code()
|
dest[0] = Asn1Tag.Oid.code()
|
||||||
offset += asn1EncodeLength(dest.toOpenArray(offset, last), oidlen)
|
offset += asn1EncodeLength(dest.toOpenArray(offset, last), oidlen)
|
||||||
|
|
|
@ -12,6 +12,9 @@
|
||||||
## This module uses unmodified parts of code from
|
## This module uses unmodified parts of code from
|
||||||
## BearSSL library <https://bearssl.org/>
|
## BearSSL library <https://bearssl.org/>
|
||||||
## Copyright(C) 2018 Thomas Pornin <pornin@bolet.org>.
|
## Copyright(C) 2018 Thomas Pornin <pornin@bolet.org>.
|
||||||
|
|
||||||
|
{.push raises: Defect.}
|
||||||
|
|
||||||
import nimcrypto/utils
|
import nimcrypto/utils
|
||||||
import bearssl
|
import bearssl
|
||||||
import minasn1
|
import minasn1
|
||||||
|
@ -72,11 +75,13 @@ type
|
||||||
RsaPKI* = RsaPrivateKey | RsaPublicKey | RsaSignature
|
RsaPKI* = RsaPrivateKey | RsaPublicKey | RsaSignature
|
||||||
RsaKP* = RsaPrivateKey | RsaKeyPair
|
RsaKP* = RsaPrivateKey | RsaKeyPair
|
||||||
|
|
||||||
RsaError* = object of CatchableError
|
RsaError* = enum
|
||||||
RsaRngError* = object of RsaError
|
RsaRngError,
|
||||||
RsaGenError* = object of RsaError
|
RsaGenError,
|
||||||
RsaKeyIncorrectError* = object of RsaError
|
RsaKeyIncorrectError,
|
||||||
RsaSignatureError* = object of RsaError
|
RsaSignatureError
|
||||||
|
|
||||||
|
RsaResult*[T] = Result[T, RsaError]
|
||||||
|
|
||||||
template getStart(bs, os, ls: untyped): untyped =
|
template getStart(bs, os, ls: untyped): untyped =
|
||||||
let p = cast[uint](os)
|
let p = cast[uint](os)
|
||||||
|
@ -108,7 +113,7 @@ template trimZeroes(b: seq[byte], pt, ptlen: untyped) =
|
||||||
ptlen -= 1
|
ptlen -= 1
|
||||||
|
|
||||||
proc random*[T: RsaKP](t: typedesc[T], bits = DefaultKeySize,
|
proc random*[T: RsaKP](t: typedesc[T], bits = DefaultKeySize,
|
||||||
pubexp = DefaultPublicExponent): 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,7 +126,8 @@ proc random*[T: RsaKP](t: typedesc[T], bits = DefaultKeySize,
|
||||||
var seeder = brPrngSeederSystem(nil)
|
var seeder = brPrngSeederSystem(nil)
|
||||||
brHmacDrbgInit(addr rng, addr sha256Vtable, nil, 0)
|
brHmacDrbgInit(addr rng, addr sha256Vtable, nil, 0)
|
||||||
if seeder(addr rng.vtable) == 0:
|
if seeder(addr rng.vtable) == 0:
|
||||||
raise newException(RsaRngError, "Could not seed RNG")
|
return err(RsaRngError)
|
||||||
|
|
||||||
keygen = brRsaKeygenGetDefault()
|
keygen = brRsaKeygenGetDefault()
|
||||||
|
|
||||||
let length = brRsaPrivateKeyBufferSize(bits) +
|
let length = brRsaPrivateKeyBufferSize(bits) +
|
||||||
|
@ -131,34 +137,38 @@ proc random*[T: RsaKP](t: typedesc[T], bits = DefaultKeySize,
|
||||||
let pko = brRsaPrivateKeyBufferSize(bits)
|
let pko = brRsaPrivateKeyBufferSize(bits)
|
||||||
let eko = pko + brRsaPublicKeyBufferSize(bits)
|
let eko = pko + brRsaPublicKeyBufferSize(bits)
|
||||||
|
|
||||||
when T is RsaKeyPair:
|
var res: T
|
||||||
result = new RsaKeyPair
|
|
||||||
else:
|
|
||||||
result = new RsaPrivateKey
|
|
||||||
|
|
||||||
result.buffer = newSeq[byte](length)
|
when T is RsaKeyPair:
|
||||||
|
res = new T
|
||||||
|
else:
|
||||||
|
res = new RsaPrivateKey
|
||||||
|
|
||||||
|
res.buffer = newSeq[byte](length)
|
||||||
if keygen(addr rng.vtable,
|
if keygen(addr rng.vtable,
|
||||||
addr result.seck, addr result.buffer[sko],
|
addr res.seck, addr res.buffer[sko],
|
||||||
addr result.pubk, addr result.buffer[pko],
|
addr res.pubk, addr res.buffer[pko],
|
||||||
cuint(bits), pubexp) == 0:
|
cuint(bits), pubexp) == 0:
|
||||||
raise newException(RsaGenError, "Could not create private key")
|
return err(RsaGenError)
|
||||||
|
|
||||||
let compute = brRsaComputePrivexpGetDefault()
|
let compute = brRsaComputePrivexpGetDefault()
|
||||||
let res = compute(addr result.buffer[eko], addr result.seck, pubexp)
|
let computed = compute(addr res.buffer[eko], addr res.seck, pubexp)
|
||||||
if res == 0:
|
if computed == 0:
|
||||||
raise newException(RsaGenError, "Could not create private key")
|
return err(RsaGenError)
|
||||||
|
|
||||||
result.pexp = cast[ptr cuchar](addr result.buffer[eko])
|
res.pexp = cast[ptr cuchar](addr res.buffer[eko])
|
||||||
result.pexplen = res
|
res.pexplen = computed
|
||||||
|
|
||||||
trimZeroes(result.buffer, result.seck.p, result.seck.plen)
|
trimZeroes(res.buffer, res.seck.p, res.seck.plen)
|
||||||
trimZeroes(result.buffer, result.seck.q, result.seck.qlen)
|
trimZeroes(res.buffer, res.seck.q, res.seck.qlen)
|
||||||
trimZeroes(result.buffer, result.seck.dp, result.seck.dplen)
|
trimZeroes(res.buffer, res.seck.dp, res.seck.dplen)
|
||||||
trimZeroes(result.buffer, result.seck.dq, result.seck.dqlen)
|
trimZeroes(res.buffer, res.seck.dq, res.seck.dqlen)
|
||||||
trimZeroes(result.buffer, result.seck.iq, result.seck.iqlen)
|
trimZeroes(res.buffer, res.seck.iq, res.seck.iqlen)
|
||||||
trimZeroes(result.buffer, result.pubk.n, result.pubk.nlen)
|
trimZeroes(res.buffer, res.pubk.n, res.pubk.nlen)
|
||||||
trimZeroes(result.buffer, result.pubk.e, result.pubk.elen)
|
trimZeroes(res.buffer, res.pubk.e, res.pubk.elen)
|
||||||
trimZeroes(result.buffer, result.pexp, result.pexplen)
|
trimZeroes(res.buffer, res.pexp, res.pexplen)
|
||||||
|
|
||||||
|
ok(res)
|
||||||
|
|
||||||
proc copy*[T: RsaPKI](key: T): T =
|
proc copy*[T: RsaPKI](key: T): T =
|
||||||
## Create copy of RSA private key, public key or signature.
|
## Create copy of RSA private key, public key or signature.
|
||||||
|
@ -275,14 +285,15 @@ proc clear*[T: RsaPKI|RsaKeyPair](pki: var T) =
|
||||||
burnMem(pki.buffer)
|
burnMem(pki.buffer)
|
||||||
pki.buffer.setLen(0)
|
pki.buffer.setLen(0)
|
||||||
|
|
||||||
proc toBytes*(key: RsaPrivateKey, data: var openarray[byte]): int =
|
proc toBytes*(key: RsaPrivateKey, data: var openarray[byte]): RsaResult[int] =
|
||||||
## Serialize RSA private key ``key`` to ASN.1 DER binary form and store it
|
## Serialize RSA private key ``key`` to ASN.1 DER binary form and store it
|
||||||
## to ``data``.
|
## to ``data``.
|
||||||
##
|
##
|
||||||
## Procedure returns number of bytes (octets) needed to store RSA private key,
|
## Procedure returns number of bytes (octets) needed to store RSA private key,
|
||||||
## or `0` if private key is is incorrect.
|
## or `0` if private key is is incorrect.
|
||||||
doAssert(not isNil(key))
|
if isNil(key):
|
||||||
if len(key.buffer) > 0:
|
err(RsaKeyIncorrectError)
|
||||||
|
elif len(key.buffer) > 0:
|
||||||
var b = Asn1Buffer.init()
|
var b = Asn1Buffer.init()
|
||||||
var p = Asn1Composite.init(Asn1Tag.Sequence)
|
var p = Asn1Composite.init(Asn1Tag.Sequence)
|
||||||
p.write(0'u64)
|
p.write(0'u64)
|
||||||
|
@ -304,18 +315,22 @@ proc toBytes*(key: RsaPrivateKey, data: var openarray[byte]): int =
|
||||||
p.finish()
|
p.finish()
|
||||||
b.write(p)
|
b.write(p)
|
||||||
b.finish()
|
b.finish()
|
||||||
result = len(b)
|
var blen = len(b)
|
||||||
if len(data) >= result:
|
if len(data) >= blen:
|
||||||
copyMem(addr data[0], addr b.buffer[0], result)
|
copyMem(addr data[0], addr b.buffer[0], blen)
|
||||||
|
ok(blen)
|
||||||
|
else:
|
||||||
|
err(RsaKeyIncorrectError)
|
||||||
|
|
||||||
proc toBytes*(key: RsaPublicKey, data: var openarray[byte]): int =
|
proc toBytes*(key: RsaPublicKey, data: var openarray[byte]): RsaResult[int] =
|
||||||
## Serialize RSA public key ``key`` to ASN.1 DER binary form and store it
|
## Serialize RSA public key ``key`` to ASN.1 DER binary form and store it
|
||||||
## to ``data``.
|
## to ``data``.
|
||||||
##
|
##
|
||||||
## Procedure returns number of bytes (octets) needed to store RSA public key,
|
## Procedure returns number of bytes (octets) needed to store RSA public key,
|
||||||
## or `0` if public key is incorrect.
|
## or `0` if public key is incorrect.
|
||||||
doAssert(not isNil(key))
|
if isNil(key):
|
||||||
if len(key.buffer) > 0:
|
err(RsaKeyIncorrectError)
|
||||||
|
elif len(key.buffer) > 0:
|
||||||
var b = Asn1Buffer.init()
|
var b = Asn1Buffer.init()
|
||||||
var p = Asn1Composite.init(Asn1Tag.Sequence)
|
var p = Asn1Composite.init(Asn1Tag.Sequence)
|
||||||
var c0 = Asn1Composite.init(Asn1Tag.Sequence)
|
var c0 = Asn1Composite.init(Asn1Tag.Sequence)
|
||||||
|
@ -334,52 +349,64 @@ proc toBytes*(key: RsaPublicKey, data: var openarray[byte]): int =
|
||||||
p.finish()
|
p.finish()
|
||||||
b.write(p)
|
b.write(p)
|
||||||
b.finish()
|
b.finish()
|
||||||
result = len(b)
|
var blen = len(b)
|
||||||
if len(data) >= result:
|
if len(data) >= blen:
|
||||||
copyMem(addr data[0], addr b.buffer[0], result)
|
copyMem(addr data[0], addr b.buffer[0], blen)
|
||||||
|
ok(blen)
|
||||||
|
else:
|
||||||
|
err(RsaKeyIncorrectError)
|
||||||
|
|
||||||
proc toBytes*(sig: RsaSignature, data: var openarray[byte]): int =
|
proc toBytes*(sig: RsaSignature, data: var openarray[byte]): RSaResult[int] =
|
||||||
## Serialize RSA signature ``sig`` to raw binary form and store it
|
## Serialize RSA signature ``sig`` to raw binary form and store it
|
||||||
## to ``data``.
|
## to ``data``.
|
||||||
##
|
##
|
||||||
## Procedure returns number of bytes (octets) needed to store RSA public key,
|
## Procedure returns number of bytes (octets) needed to store RSA public key,
|
||||||
## or `0` if public key is incorrect.
|
## or `0` if public key is incorrect.
|
||||||
doAssert(not isNil(sig))
|
if isNil(sig):
|
||||||
result = len(sig.buffer)
|
err(RsaSignatureError)
|
||||||
if len(data) >= result:
|
else:
|
||||||
copyMem(addr data[0], addr sig.buffer[0], result)
|
var slen = len(sig.buffer)
|
||||||
|
if len(data) >= slen:
|
||||||
|
copyMem(addr data[0], addr sig.buffer[0], slen)
|
||||||
|
ok(slen)
|
||||||
|
|
||||||
proc getBytes*(key: RsaPrivateKey): seq[byte] =
|
proc getBytes*(key: RsaPrivateKey): RsaResult[seq[byte]] =
|
||||||
## Serialize RSA private key ``key`` to ASN.1 DER binary form and
|
## Serialize RSA private key ``key`` to ASN.1 DER binary form and
|
||||||
## return it.
|
## return it.
|
||||||
doAssert(not isNil(key))
|
if isNil(key):
|
||||||
result = newSeq[byte](4096)
|
return err(RsaKeyIncorrectError)
|
||||||
let length = key.toBytes(result)
|
var res = newSeq[byte](4096)
|
||||||
|
let length = ? key.toBytes(res)
|
||||||
if length > 0:
|
if length > 0:
|
||||||
result.setLen(length)
|
res.setLen(length)
|
||||||
|
ok(res)
|
||||||
else:
|
else:
|
||||||
raise newException(RsaKeyIncorrectError, "Incorrect private key")
|
err(RsaKeyIncorrectError)
|
||||||
|
|
||||||
proc getBytes*(key: RsaPublicKey): seq[byte] =
|
proc getBytes*(key: RsaPublicKey): RsaResult[seq[byte]] =
|
||||||
## Serialize RSA public key ``key`` to ASN.1 DER binary form and
|
## Serialize RSA public key ``key`` to ASN.1 DER binary form and
|
||||||
## return it.
|
## return it.
|
||||||
doAssert(not isNil(key))
|
if isNil(key):
|
||||||
result = newSeq[byte](4096)
|
return err(RsaKeyIncorrectError)
|
||||||
let length = key.toBytes(result)
|
var res = newSeq[byte](4096)
|
||||||
|
let length = ? key.toBytes(res)
|
||||||
if length > 0:
|
if length > 0:
|
||||||
result.setLen(length)
|
res.setLen(length)
|
||||||
|
ok(res)
|
||||||
else:
|
else:
|
||||||
raise newException(RsaKeyIncorrectError, "Incorrect private key")
|
err(RsaKeyIncorrectError)
|
||||||
|
|
||||||
proc getBytes*(sig: RsaSignature): seq[byte] =
|
proc getBytes*(sig: RsaSignature): RsaResult[seq[byte]] =
|
||||||
## Serialize RSA signature ``sig`` to raw binary form and return it.
|
## Serialize RSA signature ``sig`` to raw binary form and return it.
|
||||||
doAssert(not isNil(sig))
|
if isNil(sig):
|
||||||
result = newSeq[byte](4096)
|
return err(RsaSignatureError)
|
||||||
let length = sig.toBytes(result)
|
var res = newSeq[byte](4096)
|
||||||
|
let length = ? sig.toBytes(res)
|
||||||
if length > 0:
|
if length > 0:
|
||||||
result.setLen(length)
|
res.setLen(length)
|
||||||
|
ok(res)
|
||||||
else:
|
else:
|
||||||
raise newException(RsaSignatureError, "Incorrect signature")
|
err(RsaSignatureError)
|
||||||
|
|
||||||
proc init*(key: var RsaPrivateKey, data: openarray[byte]): Result[void, Asn1Error] =
|
proc init*(key: var RsaPrivateKey, data: openarray[byte]): Result[void, Asn1Error] =
|
||||||
## Initialize RSA private key ``key`` from ASN.1 DER binary representation
|
## Initialize RSA private key ``key`` from ASN.1 DER binary representation
|
||||||
|
@ -560,29 +587,32 @@ proc init*[T: RsaPKI](sospk: var T, data: string): Result[void, Asn1Error] {.inl
|
||||||
## Procedure returns ``Result[void, Asn1Status]``.
|
## Procedure returns ``Result[void, Asn1Status]``.
|
||||||
sospk.init(fromHex(data))
|
sospk.init(fromHex(data))
|
||||||
|
|
||||||
proc init*(t: typedesc[RsaPrivateKey], data: openarray[byte]): RsaPrivateKey =
|
proc init*(t: typedesc[RsaPrivateKey], data: openarray[byte]): RsaResult[RsaPrivateKey] =
|
||||||
## Initialize RSA private key from ASN.1 DER binary representation ``data``
|
## Initialize RSA private key from ASN.1 DER binary representation ``data``
|
||||||
## and return constructed object.
|
## and return constructed object.
|
||||||
let res = result.init(data)
|
var res: RsaPrivateKey
|
||||||
if res.isErr:
|
if res.init(data).isErr:
|
||||||
raise newException(RsaKeyIncorrectError,
|
err(RsaKeyIncorrectError)
|
||||||
"Incorrect private key (" & $res.error & ")")
|
else:
|
||||||
|
ok(res)
|
||||||
|
|
||||||
proc init*(t: typedesc[RsaPublicKey], data: openarray[byte]): RsaPublicKey =
|
proc init*(t: typedesc[RsaPublicKey], data: openarray[byte]): RsaResult[RsaPublicKey] =
|
||||||
## Initialize RSA public key from ASN.1 DER binary representation ``data``
|
## Initialize RSA public key from ASN.1 DER binary representation ``data``
|
||||||
## and return constructed object.
|
## and return constructed object.
|
||||||
let res = result.init(data)
|
var res: RsaPublicKey
|
||||||
if res.isErr:
|
if res.init(data).isErr:
|
||||||
raise newException(RsaKeyIncorrectError,
|
err(RsaKeyIncorrectError)
|
||||||
"Incorrect public key (" & $res.error & ")")
|
else:
|
||||||
|
ok(res)
|
||||||
|
|
||||||
proc init*(t: typedesc[RsaSignature], data: openarray[byte]): RsaSignature =
|
proc init*(t: typedesc[RsaSignature], data: openarray[byte]): RsaResult[RsaSignature] =
|
||||||
## Initialize RSA signature from raw binary representation ``data`` and
|
## Initialize RSA signature from raw binary representation ``data`` and
|
||||||
## return constructed object.
|
## return constructed object.
|
||||||
let res = result.init(data)
|
var res: RsaSignature
|
||||||
if res.isErr:
|
if res.init(data).isErr:
|
||||||
raise newException(RsaKeyIncorrectError,
|
err(RsaSignatureError)
|
||||||
"Incorrect signature (" & $res.error & ")")
|
else:
|
||||||
|
ok(res)
|
||||||
|
|
||||||
proc init*[T: RsaPKI](t: typedesc[T], data: string): T {.inline.} =
|
proc init*[T: RsaPKI](t: typedesc[T], data: string): T {.inline.} =
|
||||||
## Initialize RSA `private key`, `public key` or `signature` from hexadecimal
|
## Initialize RSA `private key`, `public key` or `signature` from hexadecimal
|
||||||
|
@ -714,15 +744,17 @@ proc `==`*(a, b: RsaPublicKey): bool =
|
||||||
result = r1 and r2
|
result = r1 and r2
|
||||||
|
|
||||||
proc sign*[T: byte|char](key: RsaPrivateKey,
|
proc sign*[T: byte|char](key: RsaPrivateKey,
|
||||||
message: openarray[T]): RsaSignature {.gcsafe.} =
|
message: openarray[T]): RsaResult[RsaSignature] {.gcsafe.} =
|
||||||
## Get RSA PKCS1.5 signature of data ``message`` using SHA256 and private
|
## Get RSA PKCS1.5 signature of data ``message`` using SHA256 and private
|
||||||
## key ``key``.
|
## key ``key``.
|
||||||
doAssert(not isNil(key))
|
if isNil(key):
|
||||||
|
return err(RsaKeyIncorrectError)
|
||||||
|
|
||||||
var hc: BrHashCompatContext
|
var hc: BrHashCompatContext
|
||||||
var hash: array[32, byte]
|
var hash: array[32, byte]
|
||||||
let impl = BrRsaPkcs1SignGetDefault()
|
let impl = BrRsaPkcs1SignGetDefault()
|
||||||
result = new RsaSignature
|
var res = new RsaSignature
|
||||||
result.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:
|
||||||
|
@ -731,11 +763,13 @@ proc sign*[T: byte|char](key: RsaPrivateKey,
|
||||||
kv.update(addr hc.vtable, nil, 0)
|
kv.update(addr hc.vtable, nil, 0)
|
||||||
kv.output(addr hc.vtable, addr hash[0])
|
kv.output(addr hc.vtable, addr hash[0])
|
||||||
var oid = RsaOidSha256
|
var oid = RsaOidSha256
|
||||||
let res = impl(cast[ptr cuchar](addr oid[0]),
|
let implRes = impl(cast[ptr cuchar](addr oid[0]),
|
||||||
cast[ptr cuchar](addr hash[0]), len(hash),
|
cast[ptr cuchar](addr hash[0]), len(hash),
|
||||||
addr key.seck, cast[ptr cuchar](addr result.buffer[0]))
|
addr key.seck, cast[ptr cuchar](addr res.buffer[0]))
|
||||||
if res == 0:
|
if implRes == 0:
|
||||||
raise newException(RsaSignatureError, "Signature generation error")
|
err(RsaSignatureError)
|
||||||
|
else:
|
||||||
|
ok(res)
|
||||||
|
|
||||||
proc verify*[T: byte|char](sig: RsaSignature, message: openarray[T],
|
proc verify*[T: byte|char](sig: RsaSignature, message: openarray[T],
|
||||||
pubkey: RsaPublicKey): bool {.inline.} =
|
pubkey: RsaPublicKey): bool {.inline.} =
|
||||||
|
|
|
@ -6,8 +6,15 @@
|
||||||
## 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 secp256k1 as s, stew/byteutils, nimcrypto/hash, nimcrypto/sha2
|
|
||||||
|
{.push raises: [Defect].}
|
||||||
|
|
||||||
|
import secp256k1, stew/byteutils, nimcrypto/hash, nimcrypto/sha2
|
||||||
export sha2
|
export sha2
|
||||||
|
import stew/results
|
||||||
|
|
||||||
|
export results
|
||||||
|
export secp256k1
|
||||||
|
|
||||||
const
|
const
|
||||||
SkRawPrivateKeySize* = 256 div 8
|
SkRawPrivateKeySize* = 256 div 8
|
||||||
|
@ -18,169 +25,125 @@ const
|
||||||
## Size of public key in octets (bytes)
|
## Size of public key in octets (bytes)
|
||||||
|
|
||||||
type
|
type
|
||||||
SkPublicKey* = distinct s.SkPublicKey
|
SkPrivateKey* = SkSecretKey
|
||||||
SkPrivateKey* = distinct s.SkSecretKey
|
|
||||||
SkKeyPair* = distinct s.SkKeyPair
|
|
||||||
SkSignature* = distinct s.SkSignature
|
|
||||||
|
|
||||||
Secp256k1Error* = object of CatchableError
|
template pubkey*(v: SkKeyPair): SkPublicKey = SkPublicKey(SkKeyPair(v).pubkey)
|
||||||
## Exceptions generated by `libsecp256k1`
|
template seckey*(v: SkKeyPair): SkPrivateKey = SkPrivateKey(SkKeyPair(v).seckey)
|
||||||
|
|
||||||
template toException(v: cstring): (ref Secp256k1Error) =
|
proc init*(key: var SkPrivateKey, data: openarray[byte]): SkResult[void] =
|
||||||
(ref Secp256k1Error)(msg: $v)
|
|
||||||
|
|
||||||
template pubkey*(v: SkKeyPair): SkPublicKey = SkPublicKey(s.SkKeyPair(v).pubkey)
|
|
||||||
template seckey*(v: SkKeyPair): SkPrivateKey = SkPrivateKey(s.SkKeyPair(v).seckey)
|
|
||||||
|
|
||||||
proc init*(key: var SkPrivateKey, data: openarray[byte]): bool {.raises: [Defect].} =
|
|
||||||
## Initialize Secp256k1 `private key` ``key`` from raw binary
|
## Initialize Secp256k1 `private key` ``key`` from raw binary
|
||||||
## representation ``data``.
|
## representation ``data``.
|
||||||
##
|
key = ? SkSecretKey.fromRaw(data)
|
||||||
## Procedure returns ``true`` on success.
|
ok()
|
||||||
if (let v = SkSecretKey.fromRaw(data); v.isOk):
|
|
||||||
key = SkPrivateKey(v[])
|
|
||||||
return true
|
|
||||||
|
|
||||||
proc init*(key: var SkPrivateKey, data: string): bool {.raises: [Defect].} =
|
proc init*(key: var SkPrivateKey, data: string): SkResult[void] =
|
||||||
## Initialize Secp256k1 `private key` ``key`` from hexadecimal string
|
## Initialize Secp256k1 `private key` ``key`` from hexadecimal string
|
||||||
## representation ``data``.
|
## representation ``data``.
|
||||||
##
|
key = ? SkSecretKey.fromHex(data)
|
||||||
## Procedure returns ``true`` on success.
|
ok()
|
||||||
try:
|
|
||||||
key = SkPrivateKey(SkSecretKey.fromHex(data).tryGet())
|
|
||||||
return true
|
|
||||||
except Secp256k1Error:
|
|
||||||
discard
|
|
||||||
|
|
||||||
proc init*(key: var SkPublicKey, data: openarray[byte]): bool {.raises: [Defect].} =
|
proc init*(key: var SkPublicKey, data: openarray[byte]): SkResult[void] =
|
||||||
## Initialize Secp256k1 `public key` ``key`` from raw binary
|
## Initialize Secp256k1 `public key` ``key`` from raw binary
|
||||||
## representation ``data``.
|
## representation ``data``.
|
||||||
##
|
key = ? SkPublicKey.fromRaw(data)
|
||||||
## Procedure returns ``true`` on success.
|
ok()
|
||||||
try:
|
|
||||||
key = SkPublicKey(s.SkPublicKey.fromRaw(data).tryGet())
|
|
||||||
return true
|
|
||||||
except Secp256k1Error:
|
|
||||||
discard
|
|
||||||
|
|
||||||
proc init*(key: var SkPublicKey, data: string): bool {.raises: [Defect].} =
|
proc init*(key: var SkPublicKey, data: string): SkResult[void] =
|
||||||
## Initialize Secp256k1 `public key` ``key`` from hexadecimal string
|
## Initialize Secp256k1 `public key` ``key`` from hexadecimal string
|
||||||
## representation ``data``.
|
## representation ``data``.
|
||||||
##
|
key = ? SkPublicKey.fromHex(data)
|
||||||
## Procedure returns ``true`` on success.
|
ok()
|
||||||
try:
|
|
||||||
key = SkPublicKey(s.SkPublicKey.fromHex(data).tryGet())
|
|
||||||
return true
|
|
||||||
except Secp256k1Error:
|
|
||||||
discard
|
|
||||||
|
|
||||||
proc init*(sig: var SkSignature, data: openarray[byte]): bool {.raises: [Defect].} =
|
proc init*(sig: var SkSignature, data: openarray[byte]): SkResult[void] =
|
||||||
## Initialize Secp256k1 `signature` ``sig`` from raw binary
|
## Initialize Secp256k1 `signature` ``sig`` from raw binary
|
||||||
## representation ``data``.
|
## representation ``data``.
|
||||||
##
|
sig = ? SkSignature.fromDer(data)
|
||||||
## Procedure returns ``true`` on success.
|
ok()
|
||||||
try:
|
|
||||||
sig = SkSignature(s.SkSignature.fromDer(data).tryGet())
|
|
||||||
return true
|
|
||||||
except Secp256k1Error:
|
|
||||||
discard
|
|
||||||
|
|
||||||
proc init*(sig: var SkSignature, data: string): bool {.raises: [Defect].} =
|
proc init*(sig: var SkSignature, data: string): SkResult[void] =
|
||||||
## Initialize Secp256k1 `signature` ``sig`` from hexadecimal string
|
## Initialize Secp256k1 `signature` ``sig`` from hexadecimal string
|
||||||
## representation ``data``.
|
## representation ``data``.
|
||||||
##
|
|
||||||
## Procedure returns ``true`` on success.
|
|
||||||
# TODO DER vs raw here is fishy
|
# TODO DER vs raw here is fishy
|
||||||
var buffer: seq[byte]
|
var buffer: seq[byte]
|
||||||
try:
|
try:
|
||||||
buffer = hexToSeqByte(data)
|
buffer = hexToSeqByte(data)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
return false
|
return err("Hex to bytes failed")
|
||||||
result = init(sig, buffer)
|
init(sig, buffer)
|
||||||
|
|
||||||
proc init*(t: typedesc[SkPrivateKey],
|
proc init*(t: typedesc[SkPrivateKey], data: openarray[byte]): SkResult[SkPrivateKey] =
|
||||||
data: openarray[byte]): SkPrivateKey {.raises: [Defect, Secp256k1Error].} =
|
|
||||||
## Initialize Secp256k1 `private key` from raw binary
|
## Initialize Secp256k1 `private key` from raw binary
|
||||||
## representation ``data``.
|
## representation ``data``.
|
||||||
##
|
##
|
||||||
## Procedure returns `private key` on success.
|
## Procedure returns `private key` on success.
|
||||||
SkPrivateKey(s.SkSecretKey.fromRaw(data).tryGet())
|
SkSecretKey.fromRaw(data)
|
||||||
|
|
||||||
proc init*(t: typedesc[SkPrivateKey],
|
proc init*(t: typedesc[SkPrivateKey], data: string): SkResult[SkPrivateKey] =
|
||||||
data: string): SkPrivateKey {.raises: [Defect, Secp256k1Error].} =
|
|
||||||
## 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.
|
||||||
s.SkSecretKey.fromHex(data).tryGet()
|
SkSecretKey.fromHex(data)
|
||||||
|
|
||||||
proc init*(t: typedesc[SkPublicKey],
|
proc init*(t: typedesc[SkPublicKey], data: openarray[byte]): SkResult[SkPublicKey] =
|
||||||
data: openarray[byte]): SkPublicKey {.raises: [Defect, Secp256k1Error].} =
|
|
||||||
## Initialize Secp256k1 `public key` from raw binary
|
## Initialize Secp256k1 `public key` from raw binary
|
||||||
## representation ``data``.
|
## representation ``data``.
|
||||||
##
|
##
|
||||||
## Procedure returns `public key` on success.
|
## Procedure returns `public key` on success.
|
||||||
if not init(result, data):
|
var key: SkPublicKey
|
||||||
raise newException(Secp256k1Error, "Incorrect binary form")
|
key.init(data) and ok(key)
|
||||||
|
|
||||||
proc init*(t: typedesc[SkPublicKey],
|
proc init*(t: typedesc[SkPublicKey], data: string): SkResult[SkPublicKey] =
|
||||||
data: string): SkPublicKey {.raises: [Defect, Secp256k1Error].} =
|
|
||||||
## Initialize Secp256k1 `public key` from hexadecimal string
|
## Initialize Secp256k1 `public key` from hexadecimal string
|
||||||
## representation ``data``.
|
## representation ``data``.
|
||||||
##
|
##
|
||||||
## Procedure returns `public key` on success.
|
## Procedure returns `public key` on success.
|
||||||
if not init(result, data):
|
var key: SkPublicKey
|
||||||
raise newException(Secp256k1Error, "Incorrect binary form")
|
key.init(data) and ok(key)
|
||||||
|
|
||||||
proc init*(t: typedesc[SkSignature],
|
proc init*(t: typedesc[SkSignature], data: openarray[byte]): SkResult[SkSignature] =
|
||||||
data: openarray[byte]): SkSignature {.raises: [Defect, Secp256k1Error].} =
|
|
||||||
## Initialize Secp256k1 `signature` from raw binary
|
## Initialize Secp256k1 `signature` from raw binary
|
||||||
## representation ``data``.
|
## representation ``data``.
|
||||||
##
|
##
|
||||||
## Procedure returns `signature` on success.
|
## Procedure returns `signature` on success.
|
||||||
if not init(result, data):
|
var sig: SkSignature
|
||||||
raise newException(Secp256k1Error, "Incorrect binary form")
|
sig.init(data) and ok(sig)
|
||||||
|
|
||||||
proc init*(t: typedesc[SkSignature],
|
proc init*(t: typedesc[SkSignature], data: string): SkResult[SkSignature] =
|
||||||
data: string): SkSignature {.raises: [Defect, Secp256k1Error].} =
|
|
||||||
## Initialize Secp256k1 `signature` from hexadecimal string
|
## Initialize Secp256k1 `signature` from hexadecimal string
|
||||||
## representation ``data``.
|
## representation ``data``.
|
||||||
##
|
##
|
||||||
## Procedure returns `signature` on success.
|
## Procedure returns `signature` on success.
|
||||||
if not init(result, data):
|
var sig: SkSignature
|
||||||
raise newException(Secp256k1Error, "Incorrect binary form")
|
sig.init(data) and ok(sig)
|
||||||
|
|
||||||
proc getKey*(key: SkPrivateKey): SkPublicKey {.raises: [Defect, Secp256k1Error].} =
|
proc getKey*(key: SkPrivateKey): SkResult[SkPublicKey] =
|
||||||
## Calculate and return Secp256k1 `public key` from `private key` ``key``.
|
## Calculate and return Secp256k1 `public key` from `private key` ``key``.
|
||||||
SkPublicKey(s.SkSecretKey(key).toPublicKey().tryGet())
|
key.toPublicKey()
|
||||||
|
|
||||||
proc random*(t: typedesc[SkPrivateKey]): SkPrivateKey =
|
proc toBytes*(key: SkPrivateKey, data: var openarray[byte]): SkResult[int] =
|
||||||
## Generates new random private key.
|
|
||||||
SkPrivateKey(s.SkSecretKey.random().tryGet())
|
|
||||||
|
|
||||||
proc random*(t: typedesc[SkKeyPair]): SkKeyPair {.inline.} =
|
|
||||||
## Generates new random key pair.
|
|
||||||
SkKeyPair(s.SkKeyPair.random().tryGet())
|
|
||||||
|
|
||||||
proc toBytes*(key: SkPrivateKey, data: var openarray[byte]): int =
|
|
||||||
## Serialize Secp256k1 `private key` ``key`` to raw binary form and store it
|
## Serialize Secp256k1 `private key` ``key`` to raw binary form and store it
|
||||||
## to ``data``.
|
## to ``data``.
|
||||||
##
|
##
|
||||||
## Procedure returns number of bytes (octets) needed to store
|
## Procedure returns number of bytes (octets) needed to store
|
||||||
## Secp256k1 private key.
|
## Secp256k1 private key.
|
||||||
result = SkRawPrivateKeySize
|
|
||||||
if len(data) >= SkRawPrivateKeySize:
|
if len(data) >= SkRawPrivateKeySize:
|
||||||
data[0..<SkRawPrivateKeySize] = s.SkSecretKey(key).toRaw()
|
data[0..<SkRawPrivateKeySize] = SkSecretKey(key).toRaw()
|
||||||
|
ok(SkRawPrivateKeySize)
|
||||||
|
else:
|
||||||
|
err("Not enough bytes")
|
||||||
|
|
||||||
proc toBytes*(key: SkPublicKey, data: var openarray[byte]): int =
|
proc toBytes*(key: SkPublicKey, data: var openarray[byte]): SkResult[int] =
|
||||||
## Serialize Secp256k1 `public key` ``key`` to raw binary form and store it
|
## Serialize Secp256k1 `public key` ``key`` to raw binary form and store it
|
||||||
## to ``data``.
|
## to ``data``.
|
||||||
##
|
##
|
||||||
## Procedure returns number of bytes (octets) needed to store
|
## Procedure returns number of bytes (octets) needed to store
|
||||||
## Secp256k1 public key.
|
## Secp256k1 public key.
|
||||||
result = SkRawPublicKeySize
|
|
||||||
if len(data) >= SkRawPublicKeySize:
|
if len(data) >= SkRawPublicKeySize:
|
||||||
data[0..<SkRawPublicKeySize] = s.SkPublicKey(key).toRawCompressed()
|
data[0..<SkRawPublicKeySize] = key.toRawCompressed()
|
||||||
|
ok(SkRawPublicKeySize)
|
||||||
|
else:
|
||||||
|
err("Not enough bytes")
|
||||||
|
|
||||||
proc toBytes*(sig: SkSignature, data: var openarray[byte]): int =
|
proc toBytes*(sig: SkSignature, data: var openarray[byte]): int =
|
||||||
## Serialize Secp256k1 `signature` ``sig`` to raw binary form and store it
|
## Serialize Secp256k1 `signature` ``sig`` to raw binary form and store it
|
||||||
|
@ -188,15 +151,15 @@ proc toBytes*(sig: SkSignature, data: var openarray[byte]): int =
|
||||||
##
|
##
|
||||||
## Procedure returns number of bytes (octets) needed to store
|
## Procedure returns number of bytes (octets) needed to store
|
||||||
## Secp256k1 signature.
|
## Secp256k1 signature.
|
||||||
s.SkSignature(sig).toDer(data)
|
sig.toDer(data)
|
||||||
|
|
||||||
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 = @(s.SkSecretKey(key).toRaw())
|
result = @(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 = @(s.SkPublicKey(key).toRawCompressed())
|
result = @(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.
|
||||||
|
@ -204,49 +167,12 @@ proc getBytes*(sig: SkSignature): seq[byte] {.inline.} =
|
||||||
let length = toBytes(sig, result)
|
let length = toBytes(sig, result)
|
||||||
result.setLen(length)
|
result.setLen(length)
|
||||||
|
|
||||||
proc `==`*(ska, skb: SkPrivateKey): bool =
|
proc sign*[T: byte|char](key: SkPrivateKey, msg: openarray[T]): SkResult[SkSignature] =
|
||||||
## Compare Secp256k1 `private key` objects for equality.
|
|
||||||
result = (s.SkSecretKey(ska).toRaw == s.SkSecretKey(skb).toRaw)
|
|
||||||
|
|
||||||
proc `==`*(pka, pkb: SkPublicKey): bool =
|
|
||||||
## Compare Secp256k1 `public key` objects for equality.
|
|
||||||
result = (s.SkPublicKey(pka).toRaw == s.SkPublicKey(pkb).toRaw)
|
|
||||||
|
|
||||||
proc `==`*(sia, sib: SkSignature): bool =
|
|
||||||
## Compare Secp256k1 `signature` objects for equality.
|
|
||||||
result = (s.SkSignature(sia).toRaw == s.SkSignature(sib).toRaw)
|
|
||||||
|
|
||||||
proc `$`*(key: SkPrivateKey): string = s.SkSecretKey(key).toHex()
|
|
||||||
## Return string representation of Secp256k1 `private key`.
|
|
||||||
|
|
||||||
proc `$`*(key: SkPublicKey): string =
|
|
||||||
## Return string representation of Secp256k1 `private key`.s
|
|
||||||
result = toHex(s.SkPublicKey(key).toRawCompressed())
|
|
||||||
|
|
||||||
proc `$`*(sig: SkSignature): string =
|
|
||||||
## Return string representation of Secp256k1 `signature`.s
|
|
||||||
result = toHex(s.SkSignature(sig).toDer())
|
|
||||||
|
|
||||||
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(s.SkSecretKey(key), h).tryGet())
|
sign(key, h)
|
||||||
|
|
||||||
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(s.SkSignature(sig), h, s.SkPublicKey(key))
|
verify(SkSignature(sig), h, SkPublicKey(key))
|
||||||
|
|
||||||
proc clear*(key: var SkPrivateKey) {.borrow.}
|
|
||||||
## Wipe and clear memory of Secp256k1 `private key`.
|
|
||||||
|
|
||||||
proc clear*(key: var SkPublicKey) {.borrow.}
|
|
||||||
## Wipe and clear memory of Secp256k1 `public key`.
|
|
||||||
|
|
||||||
proc clear*(sig: var SkSignature) {.borrow.}
|
|
||||||
## Wipe and clear memory of Secp256k1 `signature`.
|
|
||||||
# Internal memory representation size of signature object is 64 bytes.
|
|
||||||
|
|
||||||
proc clear*(pair: var SkKeyPair) {.borrow.}
|
|
||||||
|
|
||||||
proc verify*(seckey: SkPrivateKey): bool {.borrow.}
|
|
||||||
|
|
|
@ -140,7 +140,7 @@ proc p2pStB(s: string, vb: var VBuffer): bool =
|
||||||
try:
|
try:
|
||||||
var data = Base58.decode(s)
|
var data = Base58.decode(s)
|
||||||
var mh: MultiHash
|
var mh: MultiHash
|
||||||
if MultiHash.decode(data, mh) >= 0:
|
if MultiHash.decode(data, mh).isOk:
|
||||||
vb.writeSeq(data)
|
vb.writeSeq(data)
|
||||||
result = true
|
result = true
|
||||||
except:
|
except:
|
||||||
|
@ -151,7 +151,7 @@ proc p2pBtS(vb: var VBuffer, s: var string): bool =
|
||||||
var address = newSeq[byte]()
|
var address = newSeq[byte]()
|
||||||
if vb.readSeq(address) > 0:
|
if vb.readSeq(address) > 0:
|
||||||
var mh: MultiHash
|
var mh: MultiHash
|
||||||
if MultiHash.decode(address, mh) >= 0:
|
if MultiHash.decode(address, mh).isOk:
|
||||||
s = Base58.encode(address)
|
s = Base58.encode(address)
|
||||||
result = true
|
result = true
|
||||||
|
|
||||||
|
@ -160,7 +160,7 @@ proc p2pVB(vb: var VBuffer): bool =
|
||||||
var address = newSeq[byte]()
|
var address = newSeq[byte]()
|
||||||
if vb.readSeq(address) > 0:
|
if vb.readSeq(address) > 0:
|
||||||
var mh: MultiHash
|
var mh: MultiHash
|
||||||
if MultiHash.decode(address, mh) >= 0:
|
if MultiHash.decode(address, mh).isOk:
|
||||||
result = true
|
result = true
|
||||||
|
|
||||||
proc onionStB(s: string, vb: var VBuffer): bool =
|
proc onionStB(s: string, vb: var VBuffer): bool =
|
||||||
|
@ -426,12 +426,12 @@ const
|
||||||
proc trimRight(s: string, ch: char): string =
|
proc trimRight(s: string, ch: char): string =
|
||||||
## Consume trailing characters ``ch`` from string ``s`` and return result.
|
## Consume trailing characters ``ch`` from string ``s`` and return result.
|
||||||
var m = 0
|
var m = 0
|
||||||
for i in countdown(len(s) - 1, 0):
|
for i in countdown(s.high, 0):
|
||||||
if s[i] == ch:
|
if s[i] == ch:
|
||||||
inc(m)
|
inc(m)
|
||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
result = s[0..(len(s) - 1 - m)]
|
result = s[0..(s.high - m)]
|
||||||
|
|
||||||
proc shcopy*(m1: var MultiAddress, m2: MultiAddress) =
|
proc shcopy*(m1: var MultiAddress, m2: MultiAddress) =
|
||||||
shallowCopy(m1.data.buffer, m2.data.buffer)
|
shallowCopy(m1.data.buffer, m2.data.buffer)
|
||||||
|
|
|
@ -392,7 +392,7 @@ proc encode*(mbtype: typedesc[MultiBase], encoding: string,
|
||||||
if isNil(mb.encr) or isNil(mb.encl):
|
if isNil(mb.encr) or isNil(mb.encl):
|
||||||
return MultibaseStatus.NotSupported
|
return MultibaseStatus.NotSupported
|
||||||
if len(outbytes) > 1:
|
if len(outbytes) > 1:
|
||||||
result = mb.encr(inbytes, outbytes.toOpenArray(1, len(outbytes) - 1),
|
result = mb.encr(inbytes, outbytes.toOpenArray(1, outbytes.high),
|
||||||
outlen)
|
outlen)
|
||||||
if result == MultiBaseStatus.Overrun:
|
if result == MultiBaseStatus.Overrun:
|
||||||
outlen += 1
|
outlen += 1
|
||||||
|
@ -452,7 +452,7 @@ proc encode*(mbtype: typedesc[MultiBase], encoding: string,
|
||||||
if length > 0:
|
if length > 0:
|
||||||
buffer = newString(mb.encl(length) + 1)
|
buffer = newString(mb.encl(length) + 1)
|
||||||
var outlen = 0
|
var outlen = 0
|
||||||
let res = mb.encr(inbytes, buffer.toOpenArray(1, len(buffer) - 1), outlen)
|
let res = mb.encr(inbytes, buffer.toOpenArray(1, buffer.high), outlen)
|
||||||
if res != MultiBaseStatus.Success:
|
if res != MultiBaseStatus.Success:
|
||||||
raise newException(MultiBaseError, "Encoding error [" & $res & "]")
|
raise newException(MultiBaseError, "Encoding error [" & $res & "]")
|
||||||
buffer.setLen(outlen + 1)
|
buffer.setLen(outlen + 1)
|
||||||
|
|
|
@ -8,8 +8,13 @@
|
||||||
## those terms.
|
## those terms.
|
||||||
|
|
||||||
## This module implements MultiCodec.
|
## This module implements MultiCodec.
|
||||||
|
|
||||||
|
{.push raises: [Defect].}
|
||||||
|
|
||||||
import tables, hashes
|
import tables, hashes
|
||||||
import varint, vbuffer
|
import varint, vbuffer
|
||||||
|
import stew/results
|
||||||
|
export results
|
||||||
|
|
||||||
{.deadCodeElim: on.}
|
{.deadCodeElim: on.}
|
||||||
|
|
||||||
|
@ -230,7 +235,8 @@ const MultiCodecList = [
|
||||||
|
|
||||||
type
|
type
|
||||||
MultiCodec* = distinct int
|
MultiCodec* = distinct int
|
||||||
MultiCodecError* = object of CatchableError
|
MultiCodecError* = enum
|
||||||
|
MultiCodecNotSupported
|
||||||
|
|
||||||
const
|
const
|
||||||
InvalidMultiCodec* = MultiCodec(-1)
|
InvalidMultiCodec* = MultiCodec(-1)
|
||||||
|
@ -251,37 +257,32 @@ const
|
||||||
|
|
||||||
proc multiCodec*(name: string): MultiCodec {.compileTime.} =
|
proc multiCodec*(name: string): MultiCodec {.compileTime.} =
|
||||||
## Generate MultiCodec from string ``name`` at compile time.
|
## Generate MultiCodec from string ``name`` at compile time.
|
||||||
var code = NameCodecs.getOrDefault(name, -1)
|
let code = NameCodecs.getOrDefault(name, -1)
|
||||||
if code == -1:
|
doAssert(code != -1)
|
||||||
raise newException(MultiCodecError,
|
MultiCodec(code)
|
||||||
"MultiCodec `" & name & "` not supported!")
|
|
||||||
result = MultiCodec(code)
|
|
||||||
|
|
||||||
proc multiCodec*(code: int): MultiCodec {.compileTime.} =
|
proc multiCodec*(code: int): MultiCodec {.compileTime.} =
|
||||||
## Generate MultiCodec from integer ``code`` at compile time.
|
## Generate MultiCodec from integer ``code`` at compile time.
|
||||||
var name = CodeCodecs.getOrDefault(code, "")
|
let name = CodeCodecs.getOrDefault(code, "")
|
||||||
if name == "":
|
doAssert(name != "")
|
||||||
raise newException(MultiCodecError,
|
MultiCodec(code)
|
||||||
"MultiCodec with code " & $code & " not supported!")
|
|
||||||
result = MultiCodec(code)
|
|
||||||
|
|
||||||
proc `$`*(mc: MultiCodec): string =
|
proc `$`*(mc: MultiCodec): string =
|
||||||
## Returns string representation of MultiCodec ``mc``.
|
## Returns string representation of MultiCodec ``mc``.
|
||||||
result = CodeCodecs.getOrDefault(int(mc), "")
|
let name = CodeCodecs.getOrDefault(int(mc), "")
|
||||||
if result == "":
|
doAssert(name != "")
|
||||||
raise newException(MultiCodecError,
|
name
|
||||||
"MultiCodec with code " & $int(mc) & " not supported!")
|
|
||||||
|
|
||||||
proc `==`*(mc: MultiCodec, name: string): bool {.inline.} =
|
proc `==`*(mc: MultiCodec, name: string): bool {.inline.} =
|
||||||
## Compares MultiCodec ``mc`` with string ``name``.
|
## Compares MultiCodec ``mc`` with string ``name``.
|
||||||
var mcname = CodeCodecs.getOrDefault(int(mc), "")
|
let mcname = CodeCodecs.getOrDefault(int(mc), "")
|
||||||
if mcname == "":
|
if mcname == "":
|
||||||
return false
|
return false
|
||||||
result = (mcname == name)
|
result = (mcname == name)
|
||||||
|
|
||||||
proc `==`*(mc: MultiCodec, code: int): bool {.inline.} =
|
proc `==`*(mc: MultiCodec, code: int): bool {.inline.} =
|
||||||
## Compares MultiCodec ``mc`` with integer ``code``.
|
## Compares MultiCodec ``mc`` with integer ``code``.
|
||||||
result = (int(mc) == code)
|
(int(mc) == code)
|
||||||
|
|
||||||
proc `==`*(a, b: MultiCodec): bool =
|
proc `==`*(a, b: MultiCodec): bool =
|
||||||
## Returns ``true`` if MultiCodecs ``a`` and ``b`` are equal.
|
## Returns ``true`` if MultiCodecs ``a`` and ``b`` are equal.
|
||||||
|
@ -293,13 +294,13 @@ proc `!=`*(a, b: MultiCodec): bool =
|
||||||
|
|
||||||
proc hash*(m: MultiCodec): Hash {.inline.} =
|
proc hash*(m: MultiCodec): Hash {.inline.} =
|
||||||
## Hash procedure for tables.
|
## Hash procedure for tables.
|
||||||
result = hash(int(m))
|
hash(int(m))
|
||||||
|
|
||||||
proc codec*(mt: typedesc[MultiCodec], name: string): MultiCodec {.inline.} =
|
proc codec*(mt: typedesc[MultiCodec], name: string): MultiCodec {.inline.} =
|
||||||
## Return MultiCodec from string representation ``name``.
|
## Return MultiCodec from string representation ``name``.
|
||||||
## If ``name`` is not valid multicodec name, then ``InvalidMultiCodec`` will
|
## If ``name`` is not valid multicodec name, then ``InvalidMultiCodec`` will
|
||||||
## be returned.
|
## be returned.
|
||||||
result = MultiCodec(NameCodecs.getOrDefault(name, -1))
|
MultiCodec(NameCodecs.getOrDefault(name, -1))
|
||||||
|
|
||||||
proc codec*(mt: typedesc[MultiCodec], code: int): MultiCodec {.inline.} =
|
proc codec*(mt: typedesc[MultiCodec], code: int): MultiCodec {.inline.} =
|
||||||
## Return MultiCodec from integer representation ``code``.
|
## Return MultiCodec from integer representation ``code``.
|
||||||
|
@ -307,9 +308,9 @@ proc codec*(mt: typedesc[MultiCodec], code: int): MultiCodec {.inline.} =
|
||||||
## be returned.
|
## be returned.
|
||||||
let res = CodeCodecs.getOrDefault(code, "")
|
let res = CodeCodecs.getOrDefault(code, "")
|
||||||
if res == "":
|
if res == "":
|
||||||
result = InvalidMultiCodec
|
InvalidMultiCodec
|
||||||
else:
|
else:
|
||||||
result = MultiCodec(code)
|
MultiCodec(code)
|
||||||
|
|
||||||
proc write*(vb: var VBuffer, mc: MultiCodec) {.inline.} =
|
proc write*(vb: var VBuffer, mc: MultiCodec) {.inline.} =
|
||||||
## Write MultiCodec to buffer ``vb``.
|
## Write MultiCodec to buffer ``vb``.
|
||||||
|
|
|
@ -20,19 +20,29 @@
|
||||||
## Hashes which are not yet supported
|
## Hashes which are not yet supported
|
||||||
## 1. SKEIN
|
## 1. SKEIN
|
||||||
## 2. MURMUR
|
## 2. MURMUR
|
||||||
|
|
||||||
|
{.push raises: [Defect].}
|
||||||
|
|
||||||
import tables
|
import tables
|
||||||
import nimcrypto/[sha, sha2, keccak, blake2, hash, utils]
|
import nimcrypto/[sha, sha2, keccak, blake2, hash, utils]
|
||||||
import varint, vbuffer, multicodec, multibase
|
import varint, vbuffer, multicodec, multibase
|
||||||
import stew/base58
|
import stew/base58
|
||||||
|
import stew/results
|
||||||
|
export results
|
||||||
# This is workaround for Nim `import` bug.
|
# This is workaround for Nim `import` bug.
|
||||||
export sha, sha2, keccak, blake2, hash, utils
|
export sha, sha2, keccak, blake2, hash, utils
|
||||||
|
|
||||||
const
|
const
|
||||||
MaxHashSize* = 128
|
MaxHashSize* = 128
|
||||||
|
ErrIncorrectName = "Incorrect hash name"
|
||||||
|
ErrNotSupported = "Hash not supported"
|
||||||
|
ErrWrongDigestSize = "Incorrect digest size"
|
||||||
|
ErrDecodeError = "Decoding error from bytes"
|
||||||
|
ErrParseError = "Parse error fromHex"
|
||||||
|
|
||||||
type
|
type
|
||||||
MHashCoderProc* = proc(data: openarray[byte],
|
MHashCoderProc* = proc(data: openarray[byte],
|
||||||
output: var openarray[byte]) {.nimcall, gcsafe.}
|
output: var openarray[byte]) {.nimcall, gcsafe, raises: [Defect].}
|
||||||
MHash* = object
|
MHash* = object
|
||||||
mcodec*: MultiCodec
|
mcodec*: MultiCodec
|
||||||
size*: int
|
size*: int
|
||||||
|
@ -44,7 +54,7 @@ type
|
||||||
size*: int
|
size*: int
|
||||||
dpos*: int
|
dpos*: int
|
||||||
|
|
||||||
MultiHashError* = object of CatchableError
|
MhResult*[T] = Result[T, cstring]
|
||||||
|
|
||||||
proc identhash(data: openarray[byte], output: var openarray[byte]) =
|
proc identhash(data: openarray[byte], output: var openarray[byte]) =
|
||||||
if len(output) > 0:
|
if len(output) > 0:
|
||||||
|
@ -345,78 +355,87 @@ proc digestImplWithoutHash(hash: MHash, data: openarray[byte]): MultiHash =
|
||||||
result.data.finish()
|
result.data.finish()
|
||||||
|
|
||||||
proc digest*(mhtype: typedesc[MultiHash], hashname: string,
|
proc digest*(mhtype: typedesc[MultiHash], hashname: string,
|
||||||
data: openarray[byte]): MultiHash {.inline.} =
|
data: openarray[byte]): MhResult[MultiHash] {.inline.} =
|
||||||
## Perform digest calculation using hash algorithm with name ``hashname`` on
|
## Perform digest calculation using hash algorithm with name ``hashname`` on
|
||||||
## data array ``data``.
|
## data array ``data``.
|
||||||
let mc = MultiCodec.codec(hashname)
|
let mc = MultiCodec.codec(hashname)
|
||||||
if mc == InvalidMultiCodec:
|
if mc == InvalidMultiCodec:
|
||||||
raise newException(MultihashError, "Incorrect hash name")
|
err(ErrIncorrectName)
|
||||||
let hash = CodeHashes.getOrDefault(mc)
|
else:
|
||||||
if isNil(hash.coder):
|
let hash = CodeHashes.getOrDefault(mc)
|
||||||
raise newException(MultihashError, "Hash not supported")
|
if isNil(hash.coder):
|
||||||
result = digestImplWithHash(hash, data)
|
err(ErrNotSupported)
|
||||||
|
else:
|
||||||
|
ok(digestImplWithHash(hash, data))
|
||||||
|
|
||||||
proc digest*(mhtype: typedesc[MultiHash], hashcode: int,
|
proc digest*(mhtype: typedesc[MultiHash], hashcode: int,
|
||||||
data: openarray[byte]): MultiHash {.inline.} =
|
data: openarray[byte]): MhResult[MultiHash] {.inline.} =
|
||||||
## Perform digest calculation using hash algorithm with code ``hashcode`` on
|
## Perform digest calculation using hash algorithm with code ``hashcode`` on
|
||||||
## data array ``data``.
|
## data array ``data``.
|
||||||
let hash = CodeHashes.getOrDefault(hashcode)
|
let hash = CodeHashes.getOrDefault(hashcode)
|
||||||
if isNil(hash.coder):
|
if isNil(hash.coder):
|
||||||
raise newException(MultihashError, "Hash not supported")
|
err(ErrNotSupported)
|
||||||
result = digestImplWithHash(hash, data)
|
else:
|
||||||
|
ok(digestImplWithHash(hash, data))
|
||||||
|
|
||||||
proc init*[T](mhtype: typedesc[MultiHash], hashname: string,
|
proc init*[T](mhtype: typedesc[MultiHash], hashname: string,
|
||||||
mdigest: MDigest[T]): MultiHash {.inline.} =
|
mdigest: MDigest[T]): MhResult[MultiHash] {.inline.} =
|
||||||
## Create MultiHash from nimcrypto's `MDigest` object and hash algorithm name
|
## Create MultiHash from nimcrypto's `MDigest` object and hash algorithm name
|
||||||
## ``hashname``.
|
## ``hashname``.
|
||||||
let mc = MultiCodec.codec(hashname)
|
let mc = MultiCodec.codec(hashname)
|
||||||
if mc == InvalidMultiCodec:
|
if mc == InvalidMultiCodec:
|
||||||
raise newException(MultihashError, "Incorrect hash name")
|
err(ErrIncorrectName)
|
||||||
let hash = CodeHashes.getOrDefault(mc)
|
else:
|
||||||
if isNil(hash.coder):
|
let hash = CodeHashes.getOrDefault(mc)
|
||||||
raise newException(MultihashError, "Hash not supported")
|
if isNil(hash.coder):
|
||||||
if hash.size != len(mdigest.data):
|
err(ErrNotSupported)
|
||||||
raise newException(MultiHashError, "Incorrect MDigest[T] size")
|
elif hash.size != len(mdigest.data):
|
||||||
result = digestImplWithoutHash(hash, mdigest.data)
|
err(ErrWrongDigestSize)
|
||||||
|
else:
|
||||||
|
ok(digestImplWithoutHash(hash, mdigest.data))
|
||||||
|
|
||||||
proc init*[T](mhtype: typedesc[MultiHash], hashcode: MultiCodec,
|
proc init*[T](mhtype: typedesc[MultiHash], hashcode: MultiCodec,
|
||||||
mdigest: MDigest[T]): MultiHash {.inline.} =
|
mdigest: MDigest[T]): MhResult[MultiHash] {.inline.} =
|
||||||
## Create MultiHash from nimcrypto's `MDigest` and hash algorithm code
|
## Create MultiHash from nimcrypto's `MDigest` and hash algorithm code
|
||||||
## ``hashcode``.
|
## ``hashcode``.
|
||||||
let hash = CodeHashes.getOrDefault(hashcode)
|
let hash = CodeHashes.getOrDefault(hashcode)
|
||||||
if isNil(hash.coder):
|
if isNil(hash.coder):
|
||||||
raise newException(MultihashError, "Hash not supported")
|
err(ErrNotSupported)
|
||||||
if (hash.size != 0) and (hash.size != len(mdigest.data)):
|
elif (hash.size != 0) and (hash.size != len(mdigest.data)):
|
||||||
raise newException(MultiHashError, "Incorrect MDigest[T] size")
|
err(ErrWrongDigestSize)
|
||||||
result = digestImplWithoutHash(hash, mdigest.data)
|
else:
|
||||||
|
ok(digestImplWithoutHash(hash, mdigest.data))
|
||||||
|
|
||||||
proc init*(mhtype: typedesc[MultiHash], hashname: string,
|
proc init*(mhtype: typedesc[MultiHash], hashname: string,
|
||||||
bdigest: openarray[byte]): MultiHash {.inline.} =
|
bdigest: openarray[byte]): MhResult[MultiHash] {.inline.} =
|
||||||
## Create MultiHash from array of bytes ``bdigest`` and hash algorithm code
|
## Create MultiHash from array of bytes ``bdigest`` and hash algorithm code
|
||||||
## ``hashcode``.
|
## ``hashcode``.
|
||||||
let mc = MultiCodec.codec(hashname)
|
let mc = MultiCodec.codec(hashname)
|
||||||
if mc == InvalidMultiCodec:
|
if mc == InvalidMultiCodec:
|
||||||
raise newException(MultihashError, "Incorrect hash name")
|
err(ErrIncorrectName)
|
||||||
let hash = CodeHashes.getOrDefault(mc)
|
else:
|
||||||
if isNil(hash.coder):
|
let hash = CodeHashes.getOrDefault(mc)
|
||||||
raise newException(MultihashError, "Hash not supported")
|
if isNil(hash.coder):
|
||||||
if (hash.size != 0) and (hash.size != len(bdigest)):
|
err(ErrNotSupported)
|
||||||
raise newException(MultiHashError, "Incorrect bdigest size")
|
elif (hash.size != 0) and (hash.size != len(bdigest)):
|
||||||
result = digestImplWithoutHash(hash, bdigest)
|
err(ErrWrongDigestSize)
|
||||||
|
else:
|
||||||
|
ok(digestImplWithoutHash(hash, bdigest))
|
||||||
|
|
||||||
proc init*(mhtype: typedesc[MultiHash], hashcode: MultiCodec,
|
proc init*(mhtype: typedesc[MultiHash], hashcode: MultiCodec,
|
||||||
bdigest: openarray[byte]): MultiHash {.inline.} =
|
bdigest: openarray[byte]): MhResult[MultiHash] {.inline.} =
|
||||||
## Create MultiHash from array of bytes ``bdigest`` and hash algorithm code
|
## Create MultiHash from array of bytes ``bdigest`` and hash algorithm code
|
||||||
## ``hashcode``.
|
## ``hashcode``.
|
||||||
let hash = CodeHashes.getOrDefault(hashcode)
|
let hash = CodeHashes.getOrDefault(hashcode)
|
||||||
if isNil(hash.coder):
|
if isNil(hash.coder):
|
||||||
raise newException(MultihashError, "Hash not supported")
|
err(ErrNotSupported)
|
||||||
if (hash.size != 0) and (hash.size != len(bdigest)):
|
elif (hash.size != 0) and (hash.size != len(bdigest)):
|
||||||
raise newException(MultiHashError, "Incorrect bdigest size")
|
err(ErrWrongDigestSize)
|
||||||
result = digestImplWithoutHash(hash, bdigest)
|
else:
|
||||||
|
ok(digestImplWithoutHash(hash, bdigest))
|
||||||
|
|
||||||
proc decode*(mhtype: typedesc[MultiHash], data: openarray[byte],
|
proc decode*(mhtype: typedesc[MultiHash], data: openarray[byte],
|
||||||
mhash: var MultiHash): int =
|
mhash: var MultiHash): MhResult[int] =
|
||||||
## Decode MultiHash value from array of bytes ``data``.
|
## Decode MultiHash value from array of bytes ``data``.
|
||||||
##
|
##
|
||||||
## On success decoded MultiHash will be stored into ``mhash`` and number of
|
## On success decoded MultiHash will be stored into ``mhash`` and number of
|
||||||
|
@ -426,31 +445,39 @@ proc decode*(mhtype: typedesc[MultiHash], data: openarray[byte],
|
||||||
var code, size: uint64
|
var code, size: uint64
|
||||||
var res, dpos: int
|
var res, dpos: int
|
||||||
if len(data) < 2:
|
if len(data) < 2:
|
||||||
return -1
|
return err(ErrDecodeError)
|
||||||
|
|
||||||
var vb = initVBuffer(data)
|
var vb = initVBuffer(data)
|
||||||
if vb.isEmpty():
|
if vb.isEmpty():
|
||||||
return -1
|
return err(ErrDecodeError)
|
||||||
|
|
||||||
res = vb.readVarint(code)
|
res = vb.readVarint(code)
|
||||||
if res == -1:
|
if res == -1:
|
||||||
return -1
|
return err(ErrDecodeError)
|
||||||
|
|
||||||
dpos += res
|
dpos += res
|
||||||
res = vb.readVarint(size)
|
res = vb.readVarint(size)
|
||||||
if res == -1:
|
if res == -1:
|
||||||
return -1
|
return err(ErrDecodeError)
|
||||||
|
|
||||||
dpos += res
|
dpos += res
|
||||||
if size > 0x7FFF_FFFF'u64:
|
if size > 0x7FFF_FFFF'u64:
|
||||||
return -1
|
return err(ErrDecodeError)
|
||||||
|
|
||||||
let hash = CodeHashes.getOrDefault(MultiCodec(code))
|
let hash = CodeHashes.getOrDefault(MultiCodec(code))
|
||||||
if isNil(hash.coder):
|
if isNil(hash.coder):
|
||||||
return -1
|
return err(ErrDecodeError)
|
||||||
|
|
||||||
if (hash.size != 0) and (hash.size != int(size)):
|
if (hash.size != 0) and (hash.size != int(size)):
|
||||||
return -1
|
return err(ErrDecodeError)
|
||||||
|
|
||||||
if not vb.isEnough(int(size)):
|
if not vb.isEnough(int(size)):
|
||||||
return -1
|
return err(ErrDecodeError)
|
||||||
mhash = MultiHash.init(MultiCodec(code),
|
|
||||||
|
mhash = ? MultiHash.init(MultiCodec(code),
|
||||||
vb.buffer.toOpenArray(vb.offset,
|
vb.buffer.toOpenArray(vb.offset,
|
||||||
vb.offset + int(size) - 1))
|
vb.offset + int(size) - 1))
|
||||||
result = vb.offset + int(size)
|
ok(vb.offset + int(size))
|
||||||
|
|
||||||
proc validate*(mhtype: typedesc[MultiHash], data: openarray[byte]): bool =
|
proc validate*(mhtype: typedesc[MultiHash], data: openarray[byte]): bool =
|
||||||
## Returns ``true`` if array of bytes ``data`` has correct MultiHash inside.
|
## Returns ``true`` if array of bytes ``data`` has correct MultiHash inside.
|
||||||
|
@ -458,7 +485,7 @@ proc validate*(mhtype: typedesc[MultiHash], data: openarray[byte]): bool =
|
||||||
var res: VarintStatus
|
var res: VarintStatus
|
||||||
if len(data) < 2:
|
if len(data) < 2:
|
||||||
return false
|
return false
|
||||||
let last = len(data) - 1
|
let last = data.high
|
||||||
var offset = 0
|
var offset = 0
|
||||||
var length = 0
|
var length = 0
|
||||||
res = LP.getUVarint(data.toOpenArray(offset, last), length, code)
|
res = LP.getUVarint(data.toOpenArray(offset, last), length, code)
|
||||||
|
@ -483,15 +510,20 @@ proc validate*(mhtype: typedesc[MultiHash], data: openarray[byte]): bool =
|
||||||
result = true
|
result = true
|
||||||
|
|
||||||
proc init*(mhtype: typedesc[MultiHash],
|
proc init*(mhtype: typedesc[MultiHash],
|
||||||
data: openarray[byte]): MultiHash {.inline.} =
|
data: openarray[byte]): MhResult[MultiHash] {.inline.} =
|
||||||
## Create MultiHash from bytes array ``data``.
|
## Create MultiHash from bytes array ``data``.
|
||||||
if MultiHash.decode(data, result) == -1:
|
var hash: MultiHash
|
||||||
raise newException(MultihashError, "Incorrect MultiHash binary format")
|
discard ? MultiHash.decode(data, hash)
|
||||||
|
ok(hash)
|
||||||
|
|
||||||
proc init*(mhtype: typedesc[MultiHash], data: string): MultiHash {.inline.} =
|
proc init*(mhtype: typedesc[MultiHash], data: string): MhResult[MultiHash] {.inline.} =
|
||||||
## Create MultiHash from hexadecimal string representation ``data``.
|
## Create MultiHash from hexadecimal string representation ``data``.
|
||||||
if MultiHash.decode(fromHex(data), result) == -1:
|
var hash: MultiHash
|
||||||
raise newException(MultihashError, "Incorrect MultiHash binary format")
|
try:
|
||||||
|
discard ? MultiHash.decode(fromHex(data), hash)
|
||||||
|
ok(hash)
|
||||||
|
except ValueError:
|
||||||
|
err(ErrParseError)
|
||||||
|
|
||||||
proc init58*(mhtype: typedesc[MultiHash],
|
proc init58*(mhtype: typedesc[MultiHash],
|
||||||
data: string): MultiHash {.inline.} =
|
data: string): MultiHash {.inline.} =
|
||||||
|
@ -518,7 +550,7 @@ proc `==`*[T](mh: MultiHash, mdigest: MDigest[T]): bool =
|
||||||
if len(mdigest.data) != mh.size:
|
if len(mdigest.data) != mh.size:
|
||||||
return false
|
return false
|
||||||
result = cmp(mh.data.buffer.toOpenArray(mh.dpos, mh.dpos + mh.size - 1),
|
result = cmp(mh.data.buffer.toOpenArray(mh.dpos, mh.dpos + mh.size - 1),
|
||||||
mdigest.data.toOpenArray(0, len(mdigest.data) - 1))
|
mdigest.data.toOpenArray(0, mdigest.data.high))
|
||||||
|
|
||||||
proc `==`*[T](mdigest: MDigest[T], mh: MultiHash): bool {.inline.} =
|
proc `==`*[T](mdigest: MDigest[T], mh: MultiHash): bool {.inline.} =
|
||||||
## Compares MultiHash with nimcrypto's MDigest[T], returns ``true`` if
|
## Compares MultiHash with nimcrypto's MDigest[T], returns ``true`` if
|
||||||
|
|
|
@ -91,7 +91,7 @@ proc hasPublicKey*(pid: PeerID): bool =
|
||||||
## Returns ``true`` if ``pid`` is small enough to hold public key inside.
|
## Returns ``true`` if ``pid`` is small enough to hold public key inside.
|
||||||
if len(pid.data) > 0:
|
if len(pid.data) > 0:
|
||||||
var mh: MultiHash
|
var mh: MultiHash
|
||||||
if MultiHash.decode(pid.data, mh) > 0:
|
if MultiHash.decode(pid.data, mh).isOk:
|
||||||
if mh.mcodec == multiCodec("identity"):
|
if mh.mcodec == multiCodec("identity"):
|
||||||
result = true
|
result = true
|
||||||
|
|
||||||
|
@ -102,7 +102,7 @@ proc extractPublicKey*(pid: PeerID, pubkey: var PublicKey): bool =
|
||||||
## Returns ``false`` otherwise.
|
## Returns ``false`` otherwise.
|
||||||
var mh: MultiHash
|
var mh: MultiHash
|
||||||
if len(pid.data) > 0:
|
if len(pid.data) > 0:
|
||||||
if MultiHash.decode(pid.data, mh) > 0:
|
if MultiHash.decode(pid.data, mh).isOk:
|
||||||
if mh.mcodec == multiCodec("identity"):
|
if mh.mcodec == multiCodec("identity"):
|
||||||
let length = len(mh.data.buffer)
|
let length = len(mh.data.buffer)
|
||||||
result = pubkey.init(mh.data.buffer.toOpenArray(mh.dpos, length - 1))
|
result = pubkey.init(mh.data.buffer.toOpenArray(mh.dpos, length - 1))
|
||||||
|
@ -117,7 +117,7 @@ proc `$`*(pid: PeerID): string =
|
||||||
for i in 0..<2:
|
for i in 0..<2:
|
||||||
result.add(spid[i])
|
result.add(spid[i])
|
||||||
result.add("*")
|
result.add("*")
|
||||||
for i in (len(spid) - 6)..(len(spid) - 1):
|
for i in (len(spid) - 6)..spid.high:
|
||||||
result.add(spid[i])
|
result.add(spid[i])
|
||||||
|
|
||||||
proc init*(pid: var PeerID, data: openarray[byte]): bool =
|
proc init*(pid: var PeerID, data: openarray[byte]): bool =
|
||||||
|
@ -155,17 +155,17 @@ proc init*(t: typedesc[PeerID], data: string): PeerID {.inline.} =
|
||||||
|
|
||||||
proc init*(t: typedesc[PeerID], pubkey: PublicKey): PeerID =
|
proc init*(t: typedesc[PeerID], pubkey: PublicKey): PeerID =
|
||||||
## Create new peer id from public key ``pubkey``.
|
## Create new peer id from public key ``pubkey``.
|
||||||
var pubraw = pubkey.getBytes()
|
var pubraw = pubkey.getBytes().tryGet()
|
||||||
var mh: MultiHash
|
var mh: MultiHash
|
||||||
if len(pubraw) <= maxInlineKeyLength:
|
if len(pubraw) <= maxInlineKeyLength:
|
||||||
mh = MultiHash.digest("identity", pubraw)
|
mh = MultiHash.digest("identity", pubraw).tryGet()
|
||||||
else:
|
else:
|
||||||
mh = MultiHash.digest("sha2-256", pubraw)
|
mh = MultiHash.digest("sha2-256", pubraw).tryGet()
|
||||||
result.data = mh.data.buffer
|
result.data = mh.data.buffer
|
||||||
|
|
||||||
proc init*(t: typedesc[PeerID], seckey: PrivateKey): PeerID {.inline.} =
|
proc init*(t: typedesc[PeerID], seckey: PrivateKey): PeerID {.inline.} =
|
||||||
## Create new peer id from private key ``seckey``.
|
## Create new peer id from private key ``seckey``.
|
||||||
result = PeerID.init(seckey.getKey())
|
result = PeerID.init(seckey.getKey().tryGet())
|
||||||
|
|
||||||
proc match*(pid: PeerID, pubkey: PublicKey): bool {.inline.} =
|
proc match*(pid: PeerID, pubkey: PublicKey): bool {.inline.} =
|
||||||
## Returns ``true`` if ``pid`` matches public key ``pubkey``.
|
## Returns ``true`` if ``pid`` matches public key ``pubkey``.
|
||||||
|
|
|
@ -118,4 +118,4 @@ proc publicKey*(p: PeerInfo): Option[PublicKey] {.inline.} =
|
||||||
elif p.key.isSome:
|
elif p.key.isSome:
|
||||||
result = p.key
|
result = p.key
|
||||||
else:
|
else:
|
||||||
result = some(p.privateKey.getKey())
|
result = some(p.privateKey.getKey().tryGet())
|
||||||
|
|
|
@ -47,7 +47,7 @@ type
|
||||||
proc encodeMsg*(peerInfo: PeerInfo, observedAddrs: Multiaddress): ProtoBuffer =
|
proc encodeMsg*(peerInfo: PeerInfo, observedAddrs: Multiaddress): ProtoBuffer =
|
||||||
result = initProtoBuffer()
|
result = initProtoBuffer()
|
||||||
|
|
||||||
result.write(initProtoField(1, peerInfo.publicKey.get().getBytes()))
|
result.write(initProtoField(1, peerInfo.publicKey.get().getBytes().tryGet()))
|
||||||
|
|
||||||
for ma in peerInfo.addrs:
|
for ma in peerInfo.addrs:
|
||||||
result.write(initProtoField(2, ma.data.buffer))
|
result.write(initProtoField(2, ma.data.buffer))
|
||||||
|
|
|
@ -33,7 +33,7 @@ proc sign*(msg: Message, p: PeerInfo): Message {.gcsafe.} =
|
||||||
if buff.buffer.len > 0:
|
if buff.buffer.len > 0:
|
||||||
result = msg
|
result = msg
|
||||||
result.signature = p.privateKey.
|
result.signature = p.privateKey.
|
||||||
sign(cast[seq[byte]](PubSubPrefix) & buff.buffer).
|
sign(cast[seq[byte]](PubSubPrefix) & buff.buffer).tryGet().
|
||||||
getBytes()
|
getBytes()
|
||||||
|
|
||||||
proc verify*(m: Message, p: PeerInfo): bool =
|
proc verify*(m: Message, p: PeerInfo): bool =
|
||||||
|
@ -57,7 +57,7 @@ proc newMessage*(p: PeerInfo,
|
||||||
sign: bool = true): Message {.gcsafe.} =
|
sign: bool = true): Message {.gcsafe.} =
|
||||||
var seqno: seq[byte] = newSeq[byte](20)
|
var seqno: seq[byte] = newSeq[byte](20)
|
||||||
if p.publicKey.isSome and randomBytes(addr seqno[0], 20) > 0:
|
if p.publicKey.isSome and randomBytes(addr seqno[0], 20) > 0:
|
||||||
var key: seq[byte] = p.publicKey.get().getBytes()
|
var key: seq[byte] = p.publicKey.get().getBytes().tryGet()
|
||||||
|
|
||||||
result = Message(fromPeer: p.peerId.getBytes(),
|
result = Message(fromPeer: p.peerId.getBytes(),
|
||||||
data: data,
|
data: data,
|
||||||
|
|
|
@ -470,7 +470,8 @@ method handshake*(p: Noise, conn: Connection, initiator: bool = false): Future[S
|
||||||
|
|
||||||
# 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(PayloadString.toBytes & p.noisePublicKey.getBytes)
|
signedPayload = p.localPrivateKey.sign(
|
||||||
|
PayloadString.toBytes & p.noisePublicKey.getBytes).tryGet()
|
||||||
|
|
||||||
var
|
var
|
||||||
libp2pProof = initProtoBuffer()
|
libp2pProof = initProtoBuffer()
|
||||||
|
@ -532,7 +533,7 @@ proc newNoise*(privateKey: PrivateKey; outgoing: bool = true; commonPrologue: se
|
||||||
new result
|
new result
|
||||||
result.outgoing = outgoing
|
result.outgoing = outgoing
|
||||||
result.localPrivateKey = privateKey
|
result.localPrivateKey = privateKey
|
||||||
result.localPublicKey = privateKey.getKey()
|
result.localPublicKey = privateKey.getKey().tryGet()
|
||||||
discard randomBytes(result.noisePrivateKey)
|
discard randomBytes(result.noisePrivateKey)
|
||||||
result.noisePublicKey = result.noisePrivateKey.public()
|
result.noisePublicKey = result.noisePrivateKey.public()
|
||||||
result.commonPrologue = commonPrologue
|
result.commonPrologue = commonPrologue
|
||||||
|
|
|
@ -166,7 +166,7 @@ proc macCheckAndDecode(sconn: SecioConn, data: var seq[byte]): bool =
|
||||||
if not equalMem(addr data[mark], addr macData[0], macsize):
|
if not equalMem(addr data[mark], addr macData[0], macsize):
|
||||||
trace "Invalid MAC",
|
trace "Invalid MAC",
|
||||||
calculated = toHex(macData.toOpenArray(0, macsize - 1)),
|
calculated = toHex(macData.toOpenArray(0, macsize - 1)),
|
||||||
stored = toHex(data.toOpenArray(mark, len(data) - 1))
|
stored = toHex(data.toOpenArray(mark, data.high))
|
||||||
return false
|
return false
|
||||||
|
|
||||||
sconn.readerCoder.decrypt(data.toOpenArray(0, mark - 1),
|
sconn.readerCoder.decrypt(data.toOpenArray(0, mark - 1),
|
||||||
|
@ -303,7 +303,7 @@ method handshake*(s: Secio, conn: Connection, initiator: bool = false): Future[S
|
||||||
remoteHashes: string
|
remoteHashes: string
|
||||||
remotePeerId: PeerID
|
remotePeerId: PeerID
|
||||||
localPeerId: PeerID
|
localPeerId: PeerID
|
||||||
localBytesPubkey = s.localPublicKey.getBytes()
|
localBytesPubkey = s.localPublicKey.getBytes().tryGet()
|
||||||
|
|
||||||
if randomBytes(localNonce) != SecioNonceSize:
|
if randomBytes(localNonce) != SecioNonceSize:
|
||||||
raise (ref SecioError)(msg: "Could not generate random data")
|
raise (ref SecioError)(msg: "Could not generate random data")
|
||||||
|
@ -341,7 +341,7 @@ method handshake*(s: Secio, conn: Connection, initiator: bool = false): Future[S
|
||||||
|
|
||||||
# TODO: PeerID check against supplied PeerID
|
# TODO: PeerID check against supplied PeerID
|
||||||
let order = getOrder(remoteBytesPubkey, localNonce, localBytesPubkey,
|
let order = getOrder(remoteBytesPubkey, localNonce, localBytesPubkey,
|
||||||
remoteNonce)
|
remoteNonce).tryGet()
|
||||||
trace "Remote proposal", schemes = remoteExchanges, ciphers = remoteCiphers,
|
trace "Remote proposal", schemes = remoteExchanges, ciphers = remoteCiphers,
|
||||||
hashes = remoteHashes,
|
hashes = remoteHashes,
|
||||||
pubkey = remoteBytesPubkey.shortLog, order = order,
|
pubkey = remoteBytesPubkey.shortLog, order = order,
|
||||||
|
@ -357,11 +357,11 @@ 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)
|
var ekeypair = ephemeral(scheme).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()
|
var epubkey = ekeypair.pubkey.eckey.getRawBytes().tryGet()
|
||||||
var localCorpus = request[4..^1] & answer & epubkey
|
var localCorpus = request[4..^1] & answer & epubkey
|
||||||
var signature = s.localPrivateKey.sign(localCorpus)
|
var signature = s.localPrivateKey.sign(localCorpus).tryGet()
|
||||||
|
|
||||||
var localExchange = createExchange(epubkey, signature.getBytes())
|
var localExchange = createExchange(epubkey, signature.getBytes())
|
||||||
var remoteExchange = await transactMessage(conn, localExchange)
|
var remoteExchange = await transactMessage(conn, localExchange)
|
||||||
|
@ -430,5 +430,5 @@ method init(s: Secio) {.gcsafe.} =
|
||||||
proc newSecio*(localPrivateKey: PrivateKey): Secio =
|
proc newSecio*(localPrivateKey: PrivateKey): Secio =
|
||||||
new result
|
new result
|
||||||
result.localPrivateKey = localPrivateKey
|
result.localPrivateKey = localPrivateKey
|
||||||
result.localPublicKey = localPrivateKey.getKey()
|
result.localPublicKey = localPrivateKey.getKey().tryGet()
|
||||||
result.init()
|
result.init()
|
||||||
|
|
|
@ -31,7 +31,7 @@ proc newStandardSwitch*(privKey = none(PrivateKey),
|
||||||
result = newMplex(conn)
|
result = newMplex(conn)
|
||||||
|
|
||||||
let
|
let
|
||||||
seckey = privKey.get(otherwise = PrivateKey.random(ECDSA))
|
seckey = privKey.get(otherwise = PrivateKey.random(ECDSA).tryGet())
|
||||||
peerInfo = PeerInfo.init(seckey, [address])
|
peerInfo = PeerInfo.init(seckey, [address])
|
||||||
mplexProvider = newMuxerProvider(createMplex, MplexCodec)
|
mplexProvider = newMuxerProvider(createMplex, MplexCodec)
|
||||||
transports = @[Transport(newTransport(TcpTransport, transportFlags))]
|
transports = @[Transport(newTransport(TcpTransport, transportFlags))]
|
||||||
|
|
|
@ -24,9 +24,15 @@ template isEnough*(vb: VBuffer, length: int): bool =
|
||||||
## Returns ``true`` if buffer ``vb`` holds at least ``length`` bytes.
|
## Returns ``true`` if buffer ``vb`` holds at least ``length`` bytes.
|
||||||
len(vb.buffer) - vb.offset - length >= 0
|
len(vb.buffer) - vb.offset - length >= 0
|
||||||
|
|
||||||
|
proc high*(vb: VBuffer): int =
|
||||||
|
## Returns number of bytes left in buffer ``vb``.
|
||||||
|
result = vb.buffer.high - vb.offset
|
||||||
|
doAssert(result >= 0)
|
||||||
|
|
||||||
proc len*(vb: VBuffer): int =
|
proc len*(vb: VBuffer): int =
|
||||||
## Returns number of bytes left in buffer ``vb``.
|
## Returns number of bytes left in buffer ``vb``.
|
||||||
result = len(vb.buffer) - vb.offset
|
result = len(vb.buffer) - vb.offset
|
||||||
|
doAssert(result >= 0)
|
||||||
|
|
||||||
proc isLiteral[T](s: seq[T]): bool {.inline.} =
|
proc isLiteral[T](s: seq[T]): bool {.inline.} =
|
||||||
type
|
type
|
||||||
|
@ -58,7 +64,7 @@ proc writePBVarint*(vb: var VBuffer, value: PBSomeUVarint) =
|
||||||
var length = 0
|
var length = 0
|
||||||
var v = value and cast[type(value)](0xFFFF_FFFF_FFFF_FFFF)
|
var v = value and cast[type(value)](0xFFFF_FFFF_FFFF_FFFF)
|
||||||
vb.buffer.setLen(len(vb.buffer) + vsizeof(v))
|
vb.buffer.setLen(len(vb.buffer) + vsizeof(v))
|
||||||
let res = PB.putUVarint(toOpenArray(vb.buffer, vb.offset, len(vb.buffer) - 1),
|
let res = PB.putUVarint(toOpenArray(vb.buffer, vb.offset, vb.buffer.high),
|
||||||
length, v)
|
length, v)
|
||||||
doAssert(res == VarintStatus.Success)
|
doAssert(res == VarintStatus.Success)
|
||||||
vb.offset += length
|
vb.offset += length
|
||||||
|
@ -69,7 +75,7 @@ proc writeLPVarint*(vb: var VBuffer, value: LPSomeUVarint) =
|
||||||
# LibP2P varint supports only 63 bits.
|
# LibP2P varint supports only 63 bits.
|
||||||
var v = value and cast[type(value)](0x7FFF_FFFF_FFFF_FFFF)
|
var v = value and cast[type(value)](0x7FFF_FFFF_FFFF_FFFF)
|
||||||
vb.buffer.setLen(len(vb.buffer) + vsizeof(v))
|
vb.buffer.setLen(len(vb.buffer) + vsizeof(v))
|
||||||
let res = LP.putUVarint(toOpenArray(vb.buffer, vb.offset, len(vb.buffer) - 1),
|
let res = LP.putUVarint(toOpenArray(vb.buffer, vb.offset, vb.buffer.high),
|
||||||
length, v)
|
length, v)
|
||||||
doAssert(res == VarintStatus.Success)
|
doAssert(res == VarintStatus.Success)
|
||||||
vb.offset += length
|
vb.offset += length
|
||||||
|
@ -82,7 +88,7 @@ proc writeSeq*[T: byte|char](vb: var VBuffer, value: openarray[T]) =
|
||||||
## varint length of the array.
|
## varint length of the array.
|
||||||
var length = 0
|
var length = 0
|
||||||
vb.buffer.setLen(len(vb.buffer) + vsizeof(uint(len(value))) + len(value))
|
vb.buffer.setLen(len(vb.buffer) + vsizeof(uint(len(value))) + len(value))
|
||||||
let res = LP.putUVarint(toOpenArray(vb.buffer, vb.offset, len(vb.buffer) - 1),
|
let res = LP.putUVarint(toOpenArray(vb.buffer, vb.offset, vb.buffer.high),
|
||||||
length, uint(len(value)))
|
length, uint(len(value)))
|
||||||
doAssert(res == VarintStatus.Success)
|
doAssert(res == VarintStatus.Success)
|
||||||
vb.offset += length
|
vb.offset += length
|
||||||
|
@ -113,7 +119,7 @@ proc peekVarint*(vb: var VBuffer, value: var LPSomeUVarint): int =
|
||||||
var length = 0
|
var length = 0
|
||||||
if not vb.isEmpty():
|
if not vb.isEmpty():
|
||||||
let res = LP.getUVarint(
|
let res = LP.getUVarint(
|
||||||
toOpenArray(vb.buffer, vb.offset, len(vb.buffer) - 1), length, value)
|
toOpenArray(vb.buffer, vb.offset, vb.buffer.high), length, value)
|
||||||
if res == VarintStatus.Success:
|
if res == VarintStatus.Success:
|
||||||
result = length
|
result = length
|
||||||
|
|
||||||
|
@ -129,7 +135,7 @@ proc peekSeq*[T: string|seq[byte]](vb: var VBuffer, value: var T): int =
|
||||||
var length = 0
|
var length = 0
|
||||||
var size = 0'u64
|
var size = 0'u64
|
||||||
if not vb.isEmpty() and
|
if not vb.isEmpty() and
|
||||||
LP.getUVarint(toOpenArray(vb.buffer, vb.offset, len(vb.buffer) - 1),
|
LP.getUVarint(toOpenArray(vb.buffer, vb.offset, vb.buffer.high),
|
||||||
length, size) == VarintStatus.Success:
|
length, size) == VarintStatus.Success:
|
||||||
vb.offset += length
|
vb.offset += length
|
||||||
result = length
|
result = length
|
||||||
|
|
|
@ -19,7 +19,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,
|
||||||
PeerInfo.init(PrivateKey.random(RSA)))
|
PeerInfo.init(PrivateKey.random(RSA).get()))
|
||||||
|
|
||||||
let topic = "foobar"
|
let topic = "foobar"
|
||||||
gossipSub.mesh[topic] = initHashSet[string]()
|
gossipSub.mesh[topic] = initHashSet[string]()
|
||||||
|
@ -28,7 +28,7 @@ suite "GossipSub internal":
|
||||||
for i in 0..<15:
|
for i in 0..<15:
|
||||||
let conn = newConnection(newBufferStream())
|
let conn = newConnection(newBufferStream())
|
||||||
conns &= conn
|
conns &= conn
|
||||||
let peerInfo = PeerInfo.init(PrivateKey.random(RSA))
|
let peerInfo = PeerInfo.init(PrivateKey.random(RSA).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
|
||||||
|
@ -48,7 +48,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,
|
||||||
PeerInfo.init(PrivateKey.random(RSA)))
|
PeerInfo.init(PrivateKey.random(RSA).get()))
|
||||||
|
|
||||||
let topic = "foobar"
|
let topic = "foobar"
|
||||||
gossipSub.gossipsub[topic] = initHashSet[string]()
|
gossipSub.gossipsub[topic] = initHashSet[string]()
|
||||||
|
@ -57,7 +57,7 @@ suite "GossipSub internal":
|
||||||
for i in 0..<15:
|
for i in 0..<15:
|
||||||
let conn = newConnection(newBufferStream())
|
let conn = newConnection(newBufferStream())
|
||||||
conns &= conn
|
conns &= conn
|
||||||
let peerInfo = PeerInfo.init(PrivateKey.random(RSA))
|
let peerInfo = PeerInfo.init(PrivateKey.random(RSA).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
|
||||||
|
@ -77,7 +77,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,
|
||||||
PeerInfo.init(PrivateKey.random(RSA)))
|
PeerInfo.init(PrivateKey.random(RSA).get()))
|
||||||
|
|
||||||
proc handler(peer: PubSubPeer, msg: seq[RPCMsg]) {.async.} =
|
proc handler(peer: PubSubPeer, msg: seq[RPCMsg]) {.async.} =
|
||||||
discard
|
discard
|
||||||
|
@ -89,7 +89,7 @@ suite "GossipSub internal":
|
||||||
for i in 0..<15:
|
for i in 0..<15:
|
||||||
let conn = newConnection(newBufferStream())
|
let conn = newConnection(newBufferStream())
|
||||||
conns &= conn
|
conns &= conn
|
||||||
var peerInfo = PeerInfo.init(PrivateKey.random(RSA))
|
var peerInfo = PeerInfo.init(PrivateKey.random(RSA).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
|
||||||
|
@ -109,7 +109,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,
|
||||||
PeerInfo.init(PrivateKey.random(RSA)))
|
PeerInfo.init(PrivateKey.random(RSA).get()))
|
||||||
|
|
||||||
proc handler(peer: PubSubPeer, msg: seq[RPCMsg]) {.async.} =
|
proc handler(peer: PubSubPeer, msg: seq[RPCMsg]) {.async.} =
|
||||||
discard
|
discard
|
||||||
|
@ -122,7 +122,7 @@ suite "GossipSub internal":
|
||||||
for i in 0..<6:
|
for i in 0..<6:
|
||||||
let conn = newConnection(newBufferStream())
|
let conn = newConnection(newBufferStream())
|
||||||
conns &= conn
|
conns &= conn
|
||||||
let peerInfo = PeerInfo.init(PrivateKey.random(RSA))
|
let peerInfo = PeerInfo.init(PrivateKey.random(RSA).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
|
||||||
|
@ -143,7 +143,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,
|
||||||
PeerInfo.init(PrivateKey.random(RSA)))
|
PeerInfo.init(PrivateKey.random(RSA).get()))
|
||||||
|
|
||||||
proc handler(peer: PubSubPeer, msg: seq[RPCMsg]) {.async.} =
|
proc handler(peer: PubSubPeer, msg: seq[RPCMsg]) {.async.} =
|
||||||
discard
|
discard
|
||||||
|
@ -159,7 +159,7 @@ suite "GossipSub internal":
|
||||||
for i in 0..<6:
|
for i in 0..<6:
|
||||||
let conn = newConnection(newBufferStream())
|
let conn = newConnection(newBufferStream())
|
||||||
conns &= conn
|
conns &= conn
|
||||||
let peerInfo = PeerInfo.init(PrivateKey.random(RSA))
|
let peerInfo = PeerInfo.init(PrivateKey.random(RSA).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
|
||||||
|
@ -183,7 +183,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,
|
||||||
PeerInfo.init(PrivateKey.random(RSA)))
|
PeerInfo.init(PrivateKey.random(RSA).get()))
|
||||||
|
|
||||||
proc handler(peer: PubSubPeer, msg: seq[RPCMsg]) {.async.} =
|
proc handler(peer: PubSubPeer, msg: seq[RPCMsg]) {.async.} =
|
||||||
discard
|
discard
|
||||||
|
@ -196,7 +196,7 @@ suite "GossipSub internal":
|
||||||
for i in 0..<30:
|
for i in 0..<30:
|
||||||
let conn = newConnection(newBufferStream())
|
let conn = newConnection(newBufferStream())
|
||||||
conns &= conn
|
conns &= conn
|
||||||
let peerInfo = PeerInfo.init(PrivateKey.random(RSA))
|
let peerInfo = PeerInfo.init(PrivateKey.random(RSA).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
|
||||||
|
@ -208,7 +208,7 @@ suite "GossipSub internal":
|
||||||
for i in 0..<15:
|
for i in 0..<15:
|
||||||
let conn = newConnection(newBufferStream())
|
let conn = newConnection(newBufferStream())
|
||||||
conns &= conn
|
conns &= conn
|
||||||
let peerInfo = PeerInfo.init(PrivateKey.random(RSA))
|
let peerInfo = PeerInfo.init(PrivateKey.random(RSA).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
|
||||||
|
@ -234,7 +234,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,
|
||||||
PeerInfo.init(PrivateKey.random(RSA)))
|
PeerInfo.init(PrivateKey.random(RSA).get()))
|
||||||
|
|
||||||
proc handler(peer: PubSubPeer, msg: seq[RPCMsg]) {.async.} =
|
proc handler(peer: PubSubPeer, msg: seq[RPCMsg]) {.async.} =
|
||||||
discard
|
discard
|
||||||
|
@ -246,7 +246,7 @@ suite "GossipSub internal":
|
||||||
for i in 0..<30:
|
for i in 0..<30:
|
||||||
let conn = newConnection(newBufferStream())
|
let conn = newConnection(newBufferStream())
|
||||||
conns &= conn
|
conns &= conn
|
||||||
let peerInfo = PeerInfo.init(PrivateKey.random(RSA))
|
let peerInfo = PeerInfo.init(PrivateKey.random(RSA).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
|
||||||
|
@ -268,7 +268,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,
|
||||||
PeerInfo.init(PrivateKey.random(RSA)))
|
PeerInfo.init(PrivateKey.random(RSA).get()))
|
||||||
|
|
||||||
proc handler(peer: PubSubPeer, msg: seq[RPCMsg]) {.async.} =
|
proc handler(peer: PubSubPeer, msg: seq[RPCMsg]) {.async.} =
|
||||||
discard
|
discard
|
||||||
|
@ -280,7 +280,7 @@ suite "GossipSub internal":
|
||||||
for i in 0..<30:
|
for i in 0..<30:
|
||||||
let conn = newConnection(newBufferStream())
|
let conn = newConnection(newBufferStream())
|
||||||
conns &= conn
|
conns &= conn
|
||||||
let peerInfo = PeerInfo.init(PrivateKey.random(RSA))
|
let peerInfo = PeerInfo.init(PrivateKey.random(RSA).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
|
||||||
|
@ -302,7 +302,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,
|
||||||
PeerInfo.init(PrivateKey.random(RSA)))
|
PeerInfo.init(PrivateKey.random(RSA).get()))
|
||||||
|
|
||||||
proc handler(peer: PubSubPeer, msg: seq[RPCMsg]) {.async.} =
|
proc handler(peer: PubSubPeer, msg: seq[RPCMsg]) {.async.} =
|
||||||
discard
|
discard
|
||||||
|
@ -314,7 +314,7 @@ suite "GossipSub internal":
|
||||||
for i in 0..<30:
|
for i in 0..<30:
|
||||||
let conn = newConnection(newBufferStream())
|
let conn = newConnection(newBufferStream())
|
||||||
conns &= conn
|
conns &= conn
|
||||||
let peerInfo = PeerInfo.init(PrivateKey.random(RSA))
|
let peerInfo = PeerInfo.init(PrivateKey.random(RSA).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
|
||||||
|
|
|
@ -25,7 +25,7 @@ import utils, ../../libp2p/[errors,
|
||||||
import ../helpers
|
import ../helpers
|
||||||
|
|
||||||
proc createGossipSub(): GossipSub =
|
proc createGossipSub(): GossipSub =
|
||||||
var peerInfo = PeerInfo.init(PrivateKey.random(RSA))
|
var peerInfo = PeerInfo.init(PrivateKey.random(RSA).get())
|
||||||
result = newPubSub(GossipSub, peerInfo)
|
result = newPubSub(GossipSub, peerInfo)
|
||||||
|
|
||||||
proc waitSub(sender, receiver: auto; key: string) {.async, gcsafe.} =
|
proc waitSub(sender, receiver: auto; key: string) {.async, gcsafe.} =
|
||||||
|
|
|
@ -11,7 +11,7 @@ import ../../libp2p/[peer,
|
||||||
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(RSA)).data,
|
var msg = Message(fromPeer: PeerID.init(PrivateKey.random(RSA).get()).data,
|
||||||
seqno: cast[seq[byte]]("12345"))
|
seqno: cast[seq[byte]]("12345"))
|
||||||
mCache.put(msg)
|
mCache.put(msg)
|
||||||
check mCache.get(msg.msgId).isSome and mCache.get(msg.msgId).get() == msg
|
check mCache.get(msg.msgId).isSome and mCache.get(msg.msgId).get() == msg
|
||||||
|
@ -20,13 +20,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(RSA)).data,
|
var msg = Message(fromPeer: PeerID.init(PrivateKey.random(RSA).get()).data,
|
||||||
seqno: cast[seq[byte]]("12345"),
|
seqno: cast[seq[byte]]("12345"),
|
||||||
topicIDs: @["foo"])
|
topicIDs: @["foo"])
|
||||||
mCache.put(msg)
|
mCache.put(msg)
|
||||||
|
|
||||||
for i in 0..<5:
|
for i in 0..<5:
|
||||||
var msg = Message(fromPeer: PeerID.init(PrivateKey.random(RSA)).data,
|
var msg = Message(fromPeer: PeerID.init(PrivateKey.random(RSA).get()).data,
|
||||||
seqno: cast[seq[byte]]("12345"),
|
seqno: cast[seq[byte]]("12345"),
|
||||||
topicIDs: @["bar"])
|
topicIDs: @["bar"])
|
||||||
mCache.put(msg)
|
mCache.put(msg)
|
||||||
|
@ -41,7 +41,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(RSA)).data,
|
var msg = Message(fromPeer: PeerID.init(PrivateKey.random(RSA).get()).data,
|
||||||
seqno: cast[seq[byte]]("12345"),
|
seqno: cast[seq[byte]]("12345"),
|
||||||
topicIDs: @["foo"])
|
topicIDs: @["foo"])
|
||||||
mCache.put(msg)
|
mCache.put(msg)
|
||||||
|
@ -50,7 +50,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(RSA)).data,
|
var msg = Message(fromPeer: PeerID.init(PrivateKey.random(RSA).get()).data,
|
||||||
seqno: cast[seq[byte]]("12345"),
|
seqno: cast[seq[byte]]("12345"),
|
||||||
topicIDs: @["bar"])
|
topicIDs: @["bar"])
|
||||||
mCache.put(msg)
|
mCache.put(msg)
|
||||||
|
@ -59,7 +59,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(RSA)).data,
|
var msg = Message(fromPeer: PeerID.init(PrivateKey.random(RSA).get()).data,
|
||||||
seqno: cast[seq[byte]]("12345"),
|
seqno: cast[seq[byte]]("12345"),
|
||||||
topicIDs: @["baz"])
|
topicIDs: @["baz"])
|
||||||
mCache.put(msg)
|
mCache.put(msg)
|
||||||
|
@ -71,19 +71,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(RSA)).data,
|
var msg = Message(fromPeer: PeerID.init(PrivateKey.random(RSA).get()).data,
|
||||||
seqno: cast[seq[byte]]("12345"),
|
seqno: cast[seq[byte]]("12345"),
|
||||||
topicIDs: @["foo"])
|
topicIDs: @["foo"])
|
||||||
mCache.put(msg)
|
mCache.put(msg)
|
||||||
|
|
||||||
for i in 0..<3:
|
for i in 0..<3:
|
||||||
var msg = Message(fromPeer: PeerID.init(PrivateKey.random(RSA)).data,
|
var msg = Message(fromPeer: PeerID.init(PrivateKey.random(RSA).get()).data,
|
||||||
seqno: cast[seq[byte]]("12345"),
|
seqno: cast[seq[byte]]("12345"),
|
||||||
topicIDs: @["bar"])
|
topicIDs: @["bar"])
|
||||||
mCache.put(msg)
|
mCache.put(msg)
|
||||||
|
|
||||||
for i in 0..<3:
|
for i in 0..<3:
|
||||||
var msg = Message(fromPeer: PeerID.init(PrivateKey.random(RSA)).data,
|
var msg = Message(fromPeer: PeerID.init(PrivateKey.random(RSA).get()).data,
|
||||||
seqno: cast[seq[byte]]("12345"),
|
seqno: cast[seq[byte]]("12345"),
|
||||||
topicIDs: @["baz"])
|
topicIDs: @["baz"])
|
||||||
mCache.put(msg)
|
mCache.put(msg)
|
||||||
|
|
|
@ -38,17 +38,17 @@ suite "Content identifier CID test suite":
|
||||||
var bmsg = cast[seq[byte]](msg)
|
var bmsg = cast[seq[byte]](msg)
|
||||||
var bmmsg = cast[seq[byte]](mmsg)
|
var bmmsg = cast[seq[byte]](mmsg)
|
||||||
var cid0 = Cid.init(CIDv0, multiCodec("dag-pb"),
|
var cid0 = Cid.init(CIDv0, multiCodec("dag-pb"),
|
||||||
MultiHash.digest("sha2-256", bmsg))
|
MultiHash.digest("sha2-256", bmsg).get())
|
||||||
var cid1 = Cid.init(CIDv1, multiCodec("dag-pb"),
|
var cid1 = Cid.init(CIDv1, multiCodec("dag-pb"),
|
||||||
MultiHash.digest("sha2-256", bmsg))
|
MultiHash.digest("sha2-256", bmsg).get())
|
||||||
var cid2 = cid1
|
var cid2 = cid1
|
||||||
var cid3 = cid0
|
var cid3 = cid0
|
||||||
var cid4 = Cid.init(CIDv1, multiCodec("dag-cbor"),
|
var cid4 = Cid.init(CIDv1, multiCodec("dag-cbor"),
|
||||||
MultiHash.digest("sha2-256", bmsg))
|
MultiHash.digest("sha2-256", bmsg).get())
|
||||||
var cid5 = Cid.init(CIDv1, multiCodec("dag-pb"),
|
var cid5 = Cid.init(CIDv1, multiCodec("dag-pb"),
|
||||||
MultiHash.digest("sha2-256", bmmsg))
|
MultiHash.digest("sha2-256", bmmsg).get())
|
||||||
var cid6 = Cid.init(CIDv1, multiCodec("dag-pb"),
|
var cid6 = Cid.init(CIDv1, multiCodec("dag-pb"),
|
||||||
MultiHash.digest("keccak-256", bmsg))
|
MultiHash.digest("keccak-256", bmsg).get())
|
||||||
check:
|
check:
|
||||||
cid0 == cid1
|
cid0 == cid1
|
||||||
cid1 == cid2
|
cid1 == cid2
|
||||||
|
|
|
@ -378,13 +378,13 @@ suite "Key interface test suite":
|
||||||
|
|
||||||
test "Go test vectors":
|
test "Go test vectors":
|
||||||
for i in 0..<len(PrivateKeys):
|
for i in 0..<len(PrivateKeys):
|
||||||
var seckey = PrivateKey.init(fromHex(stripSpaces(PrivateKeys[i])))
|
var seckey = PrivateKey.init(fromHex(stripSpaces(PrivateKeys[i]))).expect("private key")
|
||||||
var pubkey = PublicKey.init(fromHex(stripSpaces(PublicKeys[i])))
|
var pubkey = PublicKey.init(fromHex(stripSpaces(PublicKeys[i]))).expect("public key")
|
||||||
var calckey = seckey.getKey()
|
var calckey = seckey.getKey().expect("public key")
|
||||||
check:
|
check:
|
||||||
pubkey == calckey
|
pubkey == calckey
|
||||||
var checkseckey = seckey.getBytes()
|
var checkseckey = seckey.getBytes().expect("private key")
|
||||||
var checkpubkey = pubkey.getBytes()
|
var checkpubkey = pubkey.getBytes().expect("public key")
|
||||||
check:
|
check:
|
||||||
toHex(checkseckey) == stripSpaces(PrivateKeys[i])
|
toHex(checkseckey) == stripSpaces(PrivateKeys[i])
|
||||||
toHex(checkpubkey) == stripSpaces(PublicKeys[i])
|
toHex(checkpubkey) == stripSpaces(PublicKeys[i])
|
||||||
|
@ -394,19 +394,19 @@ 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)
|
var seckey = PrivateKey.random(ECDSA).get()
|
||||||
var pubkey = seckey.getKey()
|
var pubkey = seckey.getKey().get()
|
||||||
var pair = KeyPair.random(ECDSA)
|
var pair = KeyPair.random(ECDSA).get()
|
||||||
var sig1 = pair.seckey.sign(bmsg)
|
var sig1 = pair.seckey.sign(bmsg).get()
|
||||||
var sig2 = seckey.sign(bmsg)
|
var sig2 = seckey.sign(bmsg).get()
|
||||||
var sersig1 = sig1.getBytes()
|
var sersig1 = sig1.getBytes()
|
||||||
var sersig2 = sig2.getBytes()
|
var sersig2 = sig2.getBytes()
|
||||||
var serpub1 = pair.pubkey.getBytes()
|
var serpub1 = pair.pubkey.getBytes().get()
|
||||||
var serpub2 = pubkey.getBytes()
|
var serpub2 = pubkey.getBytes().get()
|
||||||
var recsig1 = Signature.init(sersig1)
|
var recsig1 = Signature.init(sersig1).get()
|
||||||
var recsig2 = Signature.init(sersig2)
|
var recsig2 = Signature.init(sersig2).get()
|
||||||
var recpub1 = PublicKey.init(serpub1)
|
var recpub1 = PublicKey.init(serpub1).get()
|
||||||
var recpub2 = PublicKey.init(serpub2)
|
var recpub2 = PublicKey.init(serpub2).get()
|
||||||
check:
|
check:
|
||||||
sig1.verify(bmsg, pair.pubkey) == true
|
sig1.verify(bmsg, pair.pubkey) == true
|
||||||
recsig1.verify(bmsg, recpub1) == true
|
recsig1.verify(bmsg, recpub1) == true
|
||||||
|
@ -414,19 +414,19 @@ 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)
|
var seckey = PrivateKey.random(Ed25519).get()
|
||||||
var pubkey = seckey.getKey()
|
var pubkey = seckey.getKey().get()
|
||||||
var pair = KeyPair.random(Ed25519)
|
var pair = KeyPair.random(Ed25519).get()
|
||||||
var sig1 = pair.seckey.sign(bmsg)
|
var sig1 = pair.seckey.sign(bmsg).get()
|
||||||
var sig2 = seckey.sign(bmsg)
|
var sig2 = seckey.sign(bmsg).get()
|
||||||
var sersig1 = sig1.getBytes()
|
var sersig1 = sig1.getBytes()
|
||||||
var sersig2 = sig2.getBytes()
|
var sersig2 = sig2.getBytes()
|
||||||
var serpub1 = pair.pubkey.getBytes()
|
var serpub1 = pair.pubkey.getBytes().get()
|
||||||
var serpub2 = pubkey.getBytes()
|
var serpub2 = pubkey.getBytes().get()
|
||||||
var recsig1 = Signature.init(sersig1)
|
var recsig1 = Signature.init(sersig1).get()
|
||||||
var recsig2 = Signature.init(sersig2)
|
var recsig2 = Signature.init(sersig2).get()
|
||||||
var recpub1 = PublicKey.init(serpub1)
|
var recpub1 = PublicKey.init(serpub1).get()
|
||||||
var recpub2 = PublicKey.init(serpub2)
|
var recpub2 = PublicKey.init(serpub2).get()
|
||||||
check:
|
check:
|
||||||
sig1.verify(bmsg, pair.pubkey) == true
|
sig1.verify(bmsg, pair.pubkey) == true
|
||||||
recsig1.verify(bmsg, recpub1) == true
|
recsig1.verify(bmsg, recpub1) == true
|
||||||
|
@ -434,19 +434,19 @@ 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)
|
var seckey = PrivateKey.random(RSA, 512).get()
|
||||||
var pubkey = seckey.getKey()
|
var pubkey = seckey.getKey().get()
|
||||||
var pair = KeyPair.random(RSA, 512)
|
var pair = KeyPair.random(RSA, 512).get()
|
||||||
var sig1 = pair.seckey.sign(bmsg)
|
var sig1 = pair.seckey.sign(bmsg).get()
|
||||||
var sig2 = seckey.sign(bmsg)
|
var sig2 = seckey.sign(bmsg).get()
|
||||||
var sersig1 = sig1.getBytes()
|
var sersig1 = sig1.getBytes()
|
||||||
var sersig2 = sig2.getBytes()
|
var sersig2 = sig2.getBytes()
|
||||||
var serpub1 = pair.pubkey.getBytes()
|
var serpub1 = pair.pubkey.getBytes().get()
|
||||||
var serpub2 = pubkey.getBytes()
|
var serpub2 = pubkey.getBytes().get()
|
||||||
var recsig1 = Signature.init(sersig1)
|
var recsig1 = Signature.init(sersig1).get()
|
||||||
var recsig2 = Signature.init(sersig2)
|
var recsig2 = Signature.init(sersig2).get()
|
||||||
var recpub1 = PublicKey.init(serpub1)
|
var recpub1 = PublicKey.init(serpub1).get()
|
||||||
var recpub2 = PublicKey.init(serpub2)
|
var recpub2 = PublicKey.init(serpub2).get()
|
||||||
check:
|
check:
|
||||||
sig1.verify(bmsg, pair.pubkey) == true
|
sig1.verify(bmsg, pair.pubkey) == true
|
||||||
recsig1.verify(bmsg, recpub1) == true
|
recsig1.verify(bmsg, recpub1) == true
|
||||||
|
|
|
@ -300,15 +300,15 @@ 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(Secp256r1)
|
var key = EcPrivateKey.random(Secp256r1).expect("random key")
|
||||||
var skey1 = key.getBytes()
|
var skey1 = key.getBytes().expect("bytes")
|
||||||
check:
|
check:
|
||||||
key.toBytes(skey2) > 0
|
key.toBytes(skey2).expect("bytes") > 0
|
||||||
check:
|
check:
|
||||||
rkey1.init(skey1).isOk
|
rkey1.init(skey1).isOk
|
||||||
rkey2.init(skey2).isOk
|
rkey2.init(skey2).isOk
|
||||||
var rkey3 = EcPrivateKey.init(skey1)
|
var rkey3 = EcPrivateKey.init(skey1).expect("private key")
|
||||||
var rkey4 = EcPrivateKey.init(skey2)
|
var rkey4 = EcPrivateKey.init(skey2).expect("private key")
|
||||||
check:
|
check:
|
||||||
rkey1 == key
|
rkey1 == key
|
||||||
rkey2 == key
|
rkey2 == key
|
||||||
|
@ -319,14 +319,14 @@ 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)
|
var pair = EcKeyPair.random(Secp256r1).expect("random key")
|
||||||
var skey1 = pair.pubkey.getBytes()
|
var skey1 = pair.pubkey.getBytes().expect("bytes")
|
||||||
check:
|
check:
|
||||||
pair.pubkey.toBytes(skey2) > 0
|
pair.pubkey.toBytes(skey2).expect("bytes") > 0
|
||||||
rkey1.init(skey1).isOk
|
rkey1.init(skey1).isOk
|
||||||
rkey2.init(skey2).isOk
|
rkey2.init(skey2).isOk
|
||||||
var rkey3 = EcPublicKey.init(skey1)
|
var rkey3 = EcPublicKey.init(skey1).expect("public key")
|
||||||
var rkey4 = EcPublicKey.init(skey2)
|
var rkey4 = EcPublicKey.init(skey2).expect("public key")
|
||||||
check:
|
check:
|
||||||
rkey1 == pair.pubkey
|
rkey1 == pair.pubkey
|
||||||
rkey2 == pair.pubkey
|
rkey2 == pair.pubkey
|
||||||
|
@ -335,8 +335,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)
|
var kp1 = EcKeyPair.random(Secp256r1).expect("random key")
|
||||||
var kp2 = EcKeyPair.random(Secp256r1)
|
var kp2 = EcKeyPair.random(Secp256r1).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:
|
||||||
|
@ -348,10 +348,10 @@ suite "EC NIST-P256/384/521 test suite":
|
||||||
for i in 0..<3:
|
for i in 0..<3:
|
||||||
var key1 = fromHex(stripSpaces(ECDHEPrivateKeys[i * 2]))
|
var key1 = fromHex(stripSpaces(ECDHEPrivateKeys[i * 2]))
|
||||||
var key2 = fromHex(stripSpaces(ECDHEPrivateKeys[i * 2 + 1]))
|
var key2 = fromHex(stripSpaces(ECDHEPrivateKeys[i * 2 + 1]))
|
||||||
var seckey1 = EcPrivateKey.initRaw(key1)
|
var seckey1 = EcPrivateKey.initRaw(key1).expect("initRaw key")
|
||||||
var seckey2 = EcPrivateKey.initRaw(key2)
|
var seckey2 = EcPrivateKey.initRaw(key2).expect("initRaw key")
|
||||||
var pubkey1 = seckey1.getKey()
|
var pubkey1 = seckey1.getKey().expect("public key")
|
||||||
var pubkey2 = seckey2.getKey()
|
var pubkey2 = seckey2.getKey().expect("public key")
|
||||||
var secret1 = getSecret(pubkey2, seckey1)
|
var secret1 = getSecret(pubkey2, seckey1)
|
||||||
var secret2 = getSecret(pubkey1, seckey2)
|
var secret2 = getSecret(pubkey1, seckey2)
|
||||||
var expsecret = fromHex(stripSpaces(ECDHESecrets[i]))
|
var expsecret = fromHex(stripSpaces(ECDHESecrets[i]))
|
||||||
|
@ -361,45 +361,45 @@ suite "EC NIST-P256/384/521 test suite":
|
||||||
|
|
||||||
test "[secp256r1] ECDSA test vectors":
|
test "[secp256r1] ECDSA test vectors":
|
||||||
for i in 0..<2:
|
for i in 0..<2:
|
||||||
var sk = EcPrivateKey.init(stripSpaces(SignatureSecKeys[i]))
|
var sk = EcPrivateKey.init(stripSpaces(SignatureSecKeys[i])).expect("private key")
|
||||||
var expectpk = EcPublicKey.init(stripSpaces(SignaturePubKeys[i]))
|
var expectpk = EcPublicKey.init(stripSpaces(SignaturePubKeys[i])).expect("private key")
|
||||||
var checkpk = sk.getKey()
|
var checkpk = sk.getKey().expect("public key")
|
||||||
check expectpk == checkpk
|
check expectpk == checkpk
|
||||||
var checksig = sk.sign(SignatureMessages[i])
|
var checksig = sk.sign(SignatureMessages[i]).expect("signature")
|
||||||
var expectsig = EcSignature.init(stripSpaces(SignatureVectors[i]))
|
var expectsig = EcSignature.init(stripSpaces(SignatureVectors[i])).expect("signature")
|
||||||
check:
|
check:
|
||||||
checksig == expectsig
|
checksig == expectsig
|
||||||
checksig.verify(SignatureMessages[i], checkpk) == true
|
checksig.verify(SignatureMessages[i], checkpk) == true
|
||||||
let error = len(checksig.buffer) - 1
|
let error = checksig.buffer.high
|
||||||
checksig.buffer[error] = not(checksig.buffer[error])
|
checksig.buffer[error] = not(checksig.buffer[error])
|
||||||
check checksig.verify(SignatureMessages[i], checkpk) == false
|
check checksig.verify(SignatureMessages[i], checkpk) == false
|
||||||
|
|
||||||
test "[secp256r1] ECDSA non-deterministic test vectors":
|
test "[secp256r1] ECDSA non-deterministic test vectors":
|
||||||
var sk = EcPrivateKey.init(stripSpaces(NDPrivateKeys[0]))
|
var sk = EcPrivateKey.init(stripSpaces(NDPrivateKeys[0])).expect("private key")
|
||||||
var pk = EcPublicKey.init(stripSpaces(NDPublicKeys[0]))
|
var pk = EcPublicKey.init(stripSpaces(NDPublicKeys[0])).expect("public key")
|
||||||
var checkpk = sk.getKey()
|
var checkpk = sk.getKey().expect("public key")
|
||||||
check pk == checkpk
|
check pk == checkpk
|
||||||
for i in 0..<6:
|
for i in 0..<6:
|
||||||
var message = NDMessages[i]
|
var message = NDMessages[i]
|
||||||
var checksig = EcSignature.init(stripSpaces(NDSignatures[i]))
|
var checksig = EcSignature.init(stripSpaces(NDSignatures[i])).expect("signature")
|
||||||
check checksig.verify(message, pk) == true
|
check checksig.verify(message, pk) == true
|
||||||
let error = len(checksig.buffer) - 1
|
let error = checksig.buffer.high
|
||||||
checksig.buffer[error] = not(checksig.buffer[error])
|
checksig.buffer[error] = not(checksig.buffer[error])
|
||||||
check checksig.verify(message, pk) == false
|
check checksig.verify(message, pk) == false
|
||||||
|
|
||||||
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)
|
var kp = EcKeyPair.random(Secp256r1).expect("random key")
|
||||||
var sig = kp.seckey.sign(message)
|
var sig = kp.seckey.sign(message).expect("signature")
|
||||||
var sersk = kp.seckey.getBytes()
|
var sersk = kp.seckey.getBytes().expect("bytes")
|
||||||
var serpk = kp.pubkey.getBytes()
|
var serpk = kp.pubkey.getBytes().expect("bytes")
|
||||||
var sersig = sig.getBytes()
|
var sersig = sig.getBytes().expect("bytes")
|
||||||
discard EcPrivateKey.init(sersk)
|
discard EcPrivateKey.init(sersk)
|
||||||
var pubkey = EcPublicKey.init(serpk)
|
var pubkey = EcPublicKey.init(serpk).expect("public key")
|
||||||
var csig = EcSignature.init(sersig)
|
var csig = EcSignature.init(sersig).expect("signature")
|
||||||
check csig.verify(message, pubkey) == true
|
check csig.verify(message, pubkey) == true
|
||||||
let error = len(csig.buffer) - 1
|
let error = csig.buffer.high
|
||||||
csig.buffer[error] = not(csig.buffer[error])
|
csig.buffer[error] = not(csig.buffer[error])
|
||||||
check csig.verify(message, pubkey) == false
|
check csig.verify(message, pubkey) == false
|
||||||
|
|
||||||
|
@ -407,15 +407,15 @@ 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)
|
var key = EcPrivateKey.random(Secp384r1).expect("random key")
|
||||||
var skey1 = key.getBytes()
|
var skey1 = key.getBytes().expect("bytes")
|
||||||
check:
|
check:
|
||||||
key.toBytes(skey2) > 0
|
key.toBytes(skey2).expect("bytes") > 0
|
||||||
check:
|
check:
|
||||||
rkey1.init(skey1).isOk
|
rkey1.init(skey1).isOk
|
||||||
rkey2.init(skey2).isOk
|
rkey2.init(skey2).isOk
|
||||||
var rkey3 = EcPrivateKey.init(skey1)
|
var rkey3 = EcPrivateKey.init(skey1).expect("private key")
|
||||||
var rkey4 = EcPrivateKey.init(skey2)
|
var rkey4 = EcPrivateKey.init(skey2).expect("private key")
|
||||||
check:
|
check:
|
||||||
rkey1 == key
|
rkey1 == key
|
||||||
rkey2 == key
|
rkey2 == key
|
||||||
|
@ -426,14 +426,14 @@ 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)
|
var pair = EcKeyPair.random(Secp384r1).expect("random key")
|
||||||
var skey1 = pair.pubkey.getBytes()
|
var skey1 = pair.pubkey.getBytes().expect("bytes")
|
||||||
check:
|
check:
|
||||||
pair.pubkey.toBytes(skey2) > 0
|
pair.pubkey.toBytes(skey2).expect("bytes") > 0
|
||||||
rkey1.init(skey1).isOk
|
rkey1.init(skey1).isOk
|
||||||
rkey2.init(skey2).isOk
|
rkey2.init(skey2).isOk
|
||||||
var rkey3 = EcPublicKey.init(skey1)
|
var rkey3 = EcPublicKey.init(skey1).expect("public key")
|
||||||
var rkey4 = EcPublicKey.init(skey2)
|
var rkey4 = EcPublicKey.init(skey2).expect("public key")
|
||||||
check:
|
check:
|
||||||
rkey1 == pair.pubkey
|
rkey1 == pair.pubkey
|
||||||
rkey2 == pair.pubkey
|
rkey2 == pair.pubkey
|
||||||
|
@ -442,8 +442,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)
|
var kp1 = EcKeyPair.random(Secp384r1).expect("random key")
|
||||||
var kp2 = EcKeyPair.random(Secp384r1)
|
var kp2 = EcKeyPair.random(Secp384r1).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:
|
||||||
|
@ -455,10 +455,10 @@ suite "EC NIST-P256/384/521 test suite":
|
||||||
for i in 3..<6:
|
for i in 3..<6:
|
||||||
var key1 = fromHex(stripSpaces(ECDHEPrivateKeys[i * 2]))
|
var key1 = fromHex(stripSpaces(ECDHEPrivateKeys[i * 2]))
|
||||||
var key2 = fromHex(stripSpaces(ECDHEPrivateKeys[i * 2 + 1]))
|
var key2 = fromHex(stripSpaces(ECDHEPrivateKeys[i * 2 + 1]))
|
||||||
var seckey1 = EcPrivateKey.initRaw(key1)
|
var seckey1 = EcPrivateKey.initRaw(key1).expect("private key")
|
||||||
var seckey2 = EcPrivateKey.initRaw(key2)
|
var seckey2 = EcPrivateKey.initRaw(key2).expect("private key")
|
||||||
var pubkey1 = seckey1.getKey()
|
var pubkey1 = seckey1.getKey().expect("public key")
|
||||||
var pubkey2 = seckey2.getKey()
|
var pubkey2 = seckey2.getKey().expect("public key")
|
||||||
var secret1 = getSecret(pubkey2, seckey1)
|
var secret1 = getSecret(pubkey2, seckey1)
|
||||||
var secret2 = getSecret(pubkey1, seckey2)
|
var secret2 = getSecret(pubkey1, seckey2)
|
||||||
var expsecret = fromHex(stripSpaces(ECDHESecrets[i]))
|
var expsecret = fromHex(stripSpaces(ECDHESecrets[i]))
|
||||||
|
@ -468,45 +468,45 @@ suite "EC NIST-P256/384/521 test suite":
|
||||||
|
|
||||||
test "[secp384r1] ECDSA test vectors":
|
test "[secp384r1] ECDSA test vectors":
|
||||||
for i in 2..<4:
|
for i in 2..<4:
|
||||||
var sk = EcPrivateKey.init(stripSpaces(SignatureSecKeys[i]))
|
var sk = EcPrivateKey.init(stripSpaces(SignatureSecKeys[i])).expect("private key")
|
||||||
var expectpk = EcPublicKey.init(stripSpaces(SignaturePubKeys[i]))
|
var expectpk = EcPublicKey.init(stripSpaces(SignaturePubKeys[i])).expect("public key")
|
||||||
var checkpk = sk.getKey()
|
var checkpk = sk.getKey().expect("public key")
|
||||||
check expectpk == checkpk
|
check expectpk == checkpk
|
||||||
var checksig = sk.sign(SignatureMessages[i])
|
var checksig = sk.sign(SignatureMessages[i]).expect("signature")
|
||||||
var expectsig = EcSignature.init(stripSpaces(SignatureVectors[i]))
|
var expectsig = EcSignature.init(stripSpaces(SignatureVectors[i])).expect("signature")
|
||||||
check:
|
check:
|
||||||
checksig == expectsig
|
checksig == expectsig
|
||||||
checksig.verify(SignatureMessages[i], checkpk) == true
|
checksig.verify(SignatureMessages[i], checkpk) == true
|
||||||
let error = len(checksig.buffer) - 1
|
let error = checksig.buffer.high
|
||||||
checksig.buffer[error] = not(checksig.buffer[error])
|
checksig.buffer[error] = not(checksig.buffer[error])
|
||||||
check checksig.verify(SignatureMessages[i], checkpk) == false
|
check checksig.verify(SignatureMessages[i], checkpk) == false
|
||||||
|
|
||||||
test "[secp384r1] ECDSA non-deterministic test vectors":
|
test "[secp384r1] ECDSA non-deterministic test vectors":
|
||||||
var sk = EcPrivateKey.init(stripSpaces(NDPrivateKeys[1]))
|
var sk = EcPrivateKey.init(stripSpaces(NDPrivateKeys[1])).expect("private key")
|
||||||
var pk = EcPublicKey.init(stripSpaces(NDPublicKeys[1]))
|
var pk = EcPublicKey.init(stripSpaces(NDPublicKeys[1])).expect("public key")
|
||||||
var checkpk = sk.getKey()
|
var checkpk = sk.getKey().expect("public key")
|
||||||
check pk == checkpk
|
check pk == checkpk
|
||||||
for i in 6..<12:
|
for i in 6..<12:
|
||||||
var message = NDMessages[i]
|
var message = NDMessages[i]
|
||||||
var checksig = EcSignature.init(stripSpaces(NDSignatures[i]))
|
var checksig = EcSignature.init(stripSpaces(NDSignatures[i])).expect("signature")
|
||||||
check checksig.verify(message, pk) == true
|
check checksig.verify(message, pk) == true
|
||||||
let error = len(checksig.buffer) - 1
|
let error = checksig.buffer.high
|
||||||
checksig.buffer[error] = not(checksig.buffer[error])
|
checksig.buffer[error] = not(checksig.buffer[error])
|
||||||
check checksig.verify(message, pk) == false
|
check checksig.verify(message, pk) == false
|
||||||
|
|
||||||
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)
|
var kp = EcKeyPair.random(Secp384r1).expect("random key")
|
||||||
var sig = kp.seckey.sign(message)
|
var sig = kp.seckey.sign(message).expect("signature")
|
||||||
var sersk = kp.seckey.getBytes()
|
var sersk = kp.seckey.getBytes().expect("bytes")
|
||||||
var serpk = kp.pubkey.getBytes()
|
var serpk = kp.pubkey.getBytes().expect("bytes")
|
||||||
var sersig = sig.getBytes()
|
var sersig = sig.getBytes().expect("bytes")
|
||||||
discard EcPrivateKey.init(sersk)
|
discard EcPrivateKey.init(sersk).expect("private key")
|
||||||
var pubkey = EcPublicKey.init(serpk)
|
var pubkey = EcPublicKey.init(serpk).expect("public key")
|
||||||
var csig = EcSignature.init(sersig)
|
var csig = EcSignature.init(sersig).expect("signature")
|
||||||
check csig.verify(message, pubkey) == true
|
check csig.verify(message, pubkey) == true
|
||||||
let error = len(csig.buffer) - 1
|
let error = csig.buffer.high
|
||||||
csig.buffer[error] = not(csig.buffer[error])
|
csig.buffer[error] = not(csig.buffer[error])
|
||||||
check csig.verify(message, pubkey) == false
|
check csig.verify(message, pubkey) == false
|
||||||
|
|
||||||
|
@ -514,15 +514,15 @@ 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)
|
var key = EcPrivateKey.random(Secp521r1).expect("random key")
|
||||||
var skey1 = key.getBytes()
|
var skey1 = key.getBytes().expect("bytes")
|
||||||
check:
|
check:
|
||||||
key.toBytes(skey2) > 0
|
key.toBytes(skey2).expect("bytes") > 0
|
||||||
check:
|
check:
|
||||||
rkey1.init(skey1).isOk
|
rkey1.init(skey1).isOk
|
||||||
rkey2.init(skey2).isOk
|
rkey2.init(skey2).isOk
|
||||||
var rkey3 = EcPrivateKey.init(skey1)
|
var rkey3 = EcPrivateKey.init(skey1).expect("private key")
|
||||||
var rkey4 = EcPrivateKey.init(skey2)
|
var rkey4 = EcPrivateKey.init(skey2).expect("private key")
|
||||||
check:
|
check:
|
||||||
rkey1 == key
|
rkey1 == key
|
||||||
rkey2 == key
|
rkey2 == key
|
||||||
|
@ -533,14 +533,14 @@ 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)
|
var pair = EcKeyPair.random(Secp521r1).expect("random key")
|
||||||
var skey1 = pair.pubkey.getBytes()
|
var skey1 = pair.pubkey.getBytes().expect("bytes")
|
||||||
check:
|
check:
|
||||||
pair.pubkey.toBytes(skey2) > 0
|
pair.pubkey.toBytes(skey2).expect("bytes") > 0
|
||||||
rkey1.init(skey1).isOk
|
rkey1.init(skey1).isOk
|
||||||
rkey2.init(skey2).isOk
|
rkey2.init(skey2).isOk
|
||||||
var rkey3 = EcPublicKey.init(skey1)
|
var rkey3 = EcPublicKey.init(skey1).expect("public key")
|
||||||
var rkey4 = EcPublicKey.init(skey2)
|
var rkey4 = EcPublicKey.init(skey2).expect("public key")
|
||||||
check:
|
check:
|
||||||
rkey1 == pair.pubkey
|
rkey1 == pair.pubkey
|
||||||
rkey2 == pair.pubkey
|
rkey2 == pair.pubkey
|
||||||
|
@ -549,8 +549,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)
|
var kp1 = EcKeyPair.random(Secp521r1).expect("random key")
|
||||||
var kp2 = EcKeyPair.random(Secp521r1)
|
var kp2 = EcKeyPair.random(Secp521r1).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:
|
||||||
|
@ -562,10 +562,10 @@ suite "EC NIST-P256/384/521 test suite":
|
||||||
for i in 6..<9:
|
for i in 6..<9:
|
||||||
var key1 = fromHex(stripSpaces(ECDHEPrivateKeys[i * 2]))
|
var key1 = fromHex(stripSpaces(ECDHEPrivateKeys[i * 2]))
|
||||||
var key2 = fromHex(stripSpaces(ECDHEPrivateKeys[i * 2 + 1]))
|
var key2 = fromHex(stripSpaces(ECDHEPrivateKeys[i * 2 + 1]))
|
||||||
var seckey1 = EcPrivateKey.initRaw(key1)
|
var seckey1 = EcPrivateKey.initRaw(key1).expect("private key")
|
||||||
var seckey2 = EcPrivateKey.initRaw(key2)
|
var seckey2 = EcPrivateKey.initRaw(key2).expect("private key")
|
||||||
var pubkey1 = seckey1.getKey()
|
var pubkey1 = seckey1.getKey().expect("public key")
|
||||||
var pubkey2 = seckey2.getKey()
|
var pubkey2 = seckey2.getKey().expect("public key")
|
||||||
var secret1 = getSecret(pubkey2, seckey1)
|
var secret1 = getSecret(pubkey2, seckey1)
|
||||||
var secret2 = getSecret(pubkey1, seckey2)
|
var secret2 = getSecret(pubkey1, seckey2)
|
||||||
var expsecret = fromHex(stripSpaces(ECDHESecrets[i]))
|
var expsecret = fromHex(stripSpaces(ECDHESecrets[i]))
|
||||||
|
@ -575,44 +575,44 @@ suite "EC NIST-P256/384/521 test suite":
|
||||||
|
|
||||||
test "[secp521r1] ECDSA test vectors":
|
test "[secp521r1] ECDSA test vectors":
|
||||||
for i in 4..<6:
|
for i in 4..<6:
|
||||||
var sk = EcPrivateKey.init(stripSpaces(SignatureSecKeys[i]))
|
var sk = EcPrivateKey.init(stripSpaces(SignatureSecKeys[i])).expect("private key")
|
||||||
var expectpk = EcPublicKey.init(stripSpaces(SignaturePubKeys[i]))
|
var expectpk = EcPublicKey.init(stripSpaces(SignaturePubKeys[i])).expect("public key")
|
||||||
var checkpk = sk.getKey()
|
var checkpk = sk.getKey().expect("public key")
|
||||||
check expectpk == checkpk
|
check expectpk == checkpk
|
||||||
var checksig = sk.sign(SignatureMessages[i])
|
var checksig = sk.sign(SignatureMessages[i]).expect("signature")
|
||||||
var expectsig = EcSignature.init(stripSpaces(SignatureVectors[i]))
|
var expectsig = EcSignature.init(stripSpaces(SignatureVectors[i])).expect("signature")
|
||||||
check:
|
check:
|
||||||
checksig == expectsig
|
checksig == expectsig
|
||||||
checksig.verify(SignatureMessages[i], checkpk) == true
|
checksig.verify(SignatureMessages[i], checkpk) == true
|
||||||
let error = len(checksig.buffer) - 1
|
let error = checksig.buffer.high
|
||||||
checksig.buffer[error] = not(checksig.buffer[error])
|
checksig.buffer[error] = not(checksig.buffer[error])
|
||||||
check checksig.verify(SignatureMessages[i], checkpk) == false
|
check checksig.verify(SignatureMessages[i], checkpk) == false
|
||||||
|
|
||||||
test "[secp521r1] ECDSA non-deterministic test vectors":
|
test "[secp521r1] ECDSA non-deterministic test vectors":
|
||||||
var sk = EcPrivateKey.init(stripSpaces(NDPrivateKeys[2]))
|
var sk = EcPrivateKey.init(stripSpaces(NDPrivateKeys[2])).expect("private key")
|
||||||
var pk = EcPublicKey.init(stripSpaces(NDPublicKeys[2]))
|
var pk = EcPublicKey.init(stripSpaces(NDPublicKeys[2])).expect("public key")
|
||||||
var checkpk = sk.getKey()
|
var checkpk = sk.getKey().expect("public key")
|
||||||
check pk == checkpk
|
check pk == checkpk
|
||||||
for i in 12..<18:
|
for i in 12..<18:
|
||||||
var message = NDMessages[i]
|
var message = NDMessages[i]
|
||||||
var checksig = EcSignature.init(stripSpaces(NDSignatures[i]))
|
var checksig = EcSignature.init(stripSpaces(NDSignatures[i])).expect("signature")
|
||||||
check checksig.verify(message, pk) == true
|
check checksig.verify(message, pk) == true
|
||||||
let error = len(checksig.buffer) - 1
|
let error = checksig.buffer.high
|
||||||
checksig.buffer[error] = not(checksig.buffer[error])
|
checksig.buffer[error] = not(checksig.buffer[error])
|
||||||
check checksig.verify(message, pk) == false
|
check checksig.verify(message, pk) == false
|
||||||
|
|
||||||
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)
|
var kp = EcKeyPair.random(Secp521r1).expect("random key")
|
||||||
var sig = kp.seckey.sign(message)
|
var sig = kp.seckey.sign(message).expect("signature")
|
||||||
var sersk = kp.seckey.getBytes()
|
var sersk = kp.seckey.getBytes().expect("bytes")
|
||||||
var serpk = kp.pubkey.getBytes()
|
var serpk = kp.pubkey.getBytes().expect("bytes")
|
||||||
var sersig = sig.getBytes()
|
var sersig = sig.getBytes().expect("bytes")
|
||||||
discard EcPrivateKey.init(sersk)
|
discard EcPrivateKey.init(sersk).expect("private key")
|
||||||
var pubkey = EcPublicKey.init(serpk)
|
var pubkey = EcPublicKey.init(serpk).expect("public key")
|
||||||
var csig = EcSignature.init(sersig)
|
var csig = EcSignature.init(sersig).expect("signature")
|
||||||
check csig.verify(message, pubkey) == true
|
check csig.verify(message, pubkey) == true
|
||||||
let error = len(csig.buffer) - 1
|
let error = csig.buffer.high
|
||||||
csig.buffer[error] = not(csig.buffer[error])
|
csig.buffer[error] = not(csig.buffer[error])
|
||||||
check csig.verify(message, pubkey) == false
|
check csig.verify(message, pubkey) == false
|
||||||
|
|
|
@ -111,15 +111,15 @@ 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()
|
var key = EdPrivateKey.random().expect("private key")
|
||||||
var skey1 = key.getBytes()
|
var skey1 = key.getBytes()
|
||||||
check:
|
check:
|
||||||
key.toBytes(skey2) > 0
|
key.toBytes(skey2) > 0
|
||||||
check:
|
check:
|
||||||
rkey1.init(skey1) == true
|
rkey1.init(skey1) == true
|
||||||
rkey2.init(skey2) == true
|
rkey2.init(skey2) == true
|
||||||
var rkey3 = EdPrivateKey.init(skey1)
|
var rkey3 = EdPrivateKey.init(skey1).expect("key/sig")
|
||||||
var rkey4 = EdPrivateKey.init(skey2)
|
var rkey4 = EdPrivateKey.init(skey2).expect("key/sig")
|
||||||
check:
|
check:
|
||||||
rkey1 == key
|
rkey1 == key
|
||||||
rkey2 == key
|
rkey2 == key
|
||||||
|
@ -135,14 +135,14 @@ 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()
|
var pair = EdKeyPair.random().expect("random key pair")
|
||||||
var skey1 = pair.pubkey.getBytes()
|
var skey1 = pair.pubkey.getBytes()
|
||||||
check:
|
check:
|
||||||
pair.pubkey.toBytes(skey2) > 0
|
pair.pubkey.toBytes(skey2) > 0
|
||||||
rkey1.init(skey1) == true
|
rkey1.init(skey1) == true
|
||||||
rkey2.init(skey2) == true
|
rkey2.init(skey2) == true
|
||||||
var rkey3 = EdPublicKey.init(skey1)
|
var rkey3 = EdPublicKey.init(skey1).expect("key/sig")
|
||||||
var rkey4 = EdPublicKey.init(skey2)
|
var rkey4 = EdPublicKey.init(skey2).expect("key/sig")
|
||||||
check:
|
check:
|
||||||
rkey1 == pair.pubkey
|
rkey1 == pair.pubkey
|
||||||
rkey2 == pair.pubkey
|
rkey2 == pair.pubkey
|
||||||
|
@ -156,13 +156,13 @@ suite "Ed25519 test suite":
|
||||||
|
|
||||||
test "RFC8032 test vectors":
|
test "RFC8032 test vectors":
|
||||||
for i in 0..<5:
|
for i in 0..<5:
|
||||||
var key = EdPrivateKey.init(stripSpaces(SecretKeys[i]))
|
var key = EdPrivateKey.init(stripSpaces(SecretKeys[i])).expect("key/sig")
|
||||||
var exppub = EdPublicKey.init(stripSpaces(PublicKeys[i]))
|
var exppub = EdPublicKey.init(stripSpaces(PublicKeys[i])).expect("key/sig")
|
||||||
var pubkey = key.getKey()
|
var pubkey = key.getKey()
|
||||||
check pubkey == exppub
|
check pubkey == exppub
|
||||||
var msg = fromHex(stripSpaces(Messages[i]))
|
var msg = fromHex(stripSpaces(Messages[i]))
|
||||||
var sig = key.sign(msg)
|
var sig = key.sign(msg)
|
||||||
var expsig = EdSignature.init(fromHex(stripSpaces(Signatures[i])))
|
var expsig = EdSignature.init(fromHex(stripSpaces(Signatures[i]))).expect("key/sig")
|
||||||
check sig == expsig
|
check sig == expsig
|
||||||
check sig.verify(msg, pubkey) == true
|
check sig.verify(msg, pubkey) == true
|
||||||
sig.data[32] = not(sig.data[32])
|
sig.data[32] = not(sig.data[32])
|
||||||
|
@ -171,15 +171,15 @@ 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()
|
var kp = EdKeyPair.random().expect("random key pair")
|
||||||
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()
|
||||||
var sersig = sig.getBytes()
|
var sersig = sig.getBytes()
|
||||||
discard EdPrivateKey.init(sersk)
|
discard EdPrivateKey.init(sersk)
|
||||||
var pubkey = EdPublicKey.init(serpk)
|
var pubkey = EdPublicKey.init(serpk).expect("key/sig")
|
||||||
var csig = EdSignature.init(sersig)
|
var csig = EdSignature.init(sersig).expect("key/sig")
|
||||||
check csig.verify(message, pubkey) == true
|
check csig.verify(message, pubkey) == true
|
||||||
let error = len(csig.data) - 1
|
let error = csig.data.high
|
||||||
csig.data[error] = not(csig.data[error])
|
csig.data[error] = not(csig.data[error])
|
||||||
check csig.verify(message, pubkey) == false
|
check csig.verify(message, pubkey) == false
|
||||||
|
|
|
@ -21,7 +21,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")
|
let ma: MultiAddress = Multiaddress.init("/ip4/0.0.0.0/tcp/0")
|
||||||
let remoteSecKey = PrivateKey.random(RSA)
|
let remoteSecKey = PrivateKey.random(RSA).get()
|
||||||
let remotePeerInfo = PeerInfo.init(remoteSecKey,
|
let remotePeerInfo = PeerInfo.init(remoteSecKey,
|
||||||
[ma],
|
[ma],
|
||||||
["/test/proto1/1.0.0",
|
["/test/proto1/1.0.0",
|
||||||
|
@ -41,12 +41,12 @@ suite "Identify":
|
||||||
let transport2: TcpTransport = newTransport(TcpTransport)
|
let transport2: TcpTransport = newTransport(TcpTransport)
|
||||||
let conn = await transport2.dial(transport1.ma)
|
let conn = await transport2.dial(transport1.ma)
|
||||||
|
|
||||||
var peerInfo = PeerInfo.init(PrivateKey.random(RSA), [ma])
|
var peerInfo = PeerInfo.init(PrivateKey.random(RSA).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)
|
||||||
|
|
||||||
check id.pubKey.get() == remoteSecKey.getKey()
|
check id.pubKey.get() == remoteSecKey.getKey().get()
|
||||||
check id.addrs[0] == ma
|
check id.addrs[0] == ma
|
||||||
check id.protoVersion.get() == ProtoVersion
|
check id.protoVersion.get() == ProtoVersion
|
||||||
# check id.agentVersion.get() == AgentVersion
|
# check id.agentVersion.get() == AgentVersion
|
||||||
|
@ -66,7 +66,7 @@ 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")
|
let ma: MultiAddress = Multiaddress.init("/ip4/0.0.0.0/tcp/0")
|
||||||
var remotePeerInfo = PeerInfo.init(PrivateKey.random(RSA), [ma])
|
var remotePeerInfo = PeerInfo.init(PrivateKey.random(RSA).get(), [ma])
|
||||||
let identifyProto1 = newIdentify(remotePeerInfo)
|
let identifyProto1 = newIdentify(remotePeerInfo)
|
||||||
let msListen = newMultistream()
|
let msListen = newMultistream()
|
||||||
|
|
||||||
|
@ -85,12 +85,12 @@ suite "Identify":
|
||||||
let transport2: TcpTransport = newTransport(TcpTransport)
|
let transport2: TcpTransport = newTransport(TcpTransport)
|
||||||
let conn = await transport2.dial(transport1.ma)
|
let conn = await transport2.dial(transport1.ma)
|
||||||
|
|
||||||
var localPeerInfo = PeerInfo.init(PrivateKey.random(RSA), [ma])
|
var localPeerInfo = PeerInfo.init(PrivateKey.random(RSA).get(), [ma])
|
||||||
let identifyProto2 = newIdentify(localPeerInfo)
|
let identifyProto2 = newIdentify(localPeerInfo)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
discard await msDial.select(conn, IdentifyCodec)
|
discard await msDial.select(conn, IdentifyCodec)
|
||||||
discard await identifyProto2.identify(conn, PeerInfo.init(PrivateKey.random(RSA)))
|
discard await identifyProto2.identify(conn, PeerInfo.init(PrivateKey.random(RSA).get()))
|
||||||
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()
|
||||||
|
|
|
@ -66,7 +66,7 @@ proc createNode*(privKey: Option[PrivateKey] = none(PrivateKey),
|
||||||
gossip: bool = false): Switch =
|
gossip: bool = false): Switch =
|
||||||
var seckey = privKey
|
var seckey = privKey
|
||||||
if privKey.isNone:
|
if privKey.isNone:
|
||||||
seckey = some(PrivateKey.random(RSA))
|
seckey = some(PrivateKey.random(RSA).get())
|
||||||
|
|
||||||
var peerInfo = NativePeerInfo.init(seckey.get(), [Multiaddress.init(address)])
|
var peerInfo = NativePeerInfo.init(seckey.get(), [Multiaddress.init(address)])
|
||||||
proc createMplex(conn: Connection): Muxer = newMplex(conn)
|
proc createMplex(conn: Connection): Muxer = newMplex(conn)
|
||||||
|
|
|
@ -82,8 +82,8 @@ suite "MultiHash test suite":
|
||||||
for item in RustTestVectors:
|
for item in RustTestVectors:
|
||||||
var msg = item[1]
|
var msg = item[1]
|
||||||
var bmsg = cast[seq[byte]](msg)
|
var bmsg = cast[seq[byte]](msg)
|
||||||
var mh1 = MultiHash.digest(item[0], bmsg)
|
var mh1 = MultiHash.digest(item[0], bmsg).get()
|
||||||
var mh2 = MultiHash.init(stripSpaces(item[2]))
|
var mh2 = MultiHash.init(stripSpaces(item[2])).get()
|
||||||
check:
|
check:
|
||||||
hex(mh1) == stripSpaces(item[2])
|
hex(mh1) == stripSpaces(item[2])
|
||||||
hex(mh1) == hex(mh2)
|
hex(mh1) == hex(mh2)
|
||||||
|
|
|
@ -50,7 +50,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(RSA))
|
var peerInfo: PeerInfo = PeerInfo.init(PrivateKey.random(RSA).get())
|
||||||
peerInfo.addrs.add(ma)
|
peerInfo.addrs.add(ma)
|
||||||
let identify = newIdentify(peerInfo)
|
let identify = newIdentify(peerInfo)
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@ suite "Noise":
|
||||||
proc testListenerDialer(): Future[bool] {.async.} =
|
proc testListenerDialer(): Future[bool] {.async.} =
|
||||||
let
|
let
|
||||||
server: MultiAddress = Multiaddress.init("/ip4/0.0.0.0/tcp/0")
|
server: MultiAddress = Multiaddress.init("/ip4/0.0.0.0/tcp/0")
|
||||||
serverInfo = PeerInfo.init(PrivateKey.random(RSA), [server])
|
serverInfo = PeerInfo.init(PrivateKey.random(RSA).get(), [server])
|
||||||
serverNoise = newNoise(serverInfo.privateKey, outgoing = false)
|
serverNoise = newNoise(serverInfo.privateKey, outgoing = false)
|
||||||
|
|
||||||
proc connHandler(conn: Connection) {.async, gcsafe.} =
|
proc connHandler(conn: Connection) {.async, gcsafe.} =
|
||||||
|
@ -93,7 +93,7 @@ suite "Noise":
|
||||||
|
|
||||||
let
|
let
|
||||||
transport2: TcpTransport = newTransport(TcpTransport)
|
transport2: TcpTransport = newTransport(TcpTransport)
|
||||||
clientInfo = PeerInfo.init(PrivateKey.random(RSA), [transport1.ma])
|
clientInfo = PeerInfo.init(PrivateKey.random(RSA).get(), [transport1.ma])
|
||||||
clientNoise = newNoise(clientInfo.privateKey, outgoing = true)
|
clientNoise = newNoise(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)
|
||||||
|
@ -115,7 +115,7 @@ suite "Noise":
|
||||||
proc testListenerDialer(): Future[bool] {.async.} =
|
proc testListenerDialer(): Future[bool] {.async.} =
|
||||||
let
|
let
|
||||||
server: MultiAddress = Multiaddress.init("/ip4/0.0.0.0/tcp/0")
|
server: MultiAddress = Multiaddress.init("/ip4/0.0.0.0/tcp/0")
|
||||||
serverInfo = PeerInfo.init(PrivateKey.random(RSA), [server])
|
serverInfo = PeerInfo.init(PrivateKey.random(RSA).get(), [server])
|
||||||
serverNoise = newNoise(serverInfo.privateKey, outgoing = false)
|
serverNoise = newNoise(serverInfo.privateKey, outgoing = false)
|
||||||
readTask = newFuture[void]()
|
readTask = newFuture[void]()
|
||||||
|
|
||||||
|
@ -135,7 +135,7 @@ suite "Noise":
|
||||||
|
|
||||||
let
|
let
|
||||||
transport2: TcpTransport = newTransport(TcpTransport)
|
transport2: TcpTransport = newTransport(TcpTransport)
|
||||||
clientInfo = PeerInfo.init(PrivateKey.random(RSA), [transport1.ma])
|
clientInfo = PeerInfo.init(PrivateKey.random(RSA).get(), [transport1.ma])
|
||||||
clientNoise = newNoise(clientInfo.privateKey, outgoing = true)
|
clientNoise = newNoise(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)
|
||||||
|
@ -156,7 +156,7 @@ suite "Noise":
|
||||||
proc testListenerDialer(): Future[bool] {.async.} =
|
proc testListenerDialer(): Future[bool] {.async.} =
|
||||||
let
|
let
|
||||||
server: MultiAddress = Multiaddress.init("/ip4/0.0.0.0/tcp/0")
|
server: MultiAddress = Multiaddress.init("/ip4/0.0.0.0/tcp/0")
|
||||||
serverInfo = PeerInfo.init(PrivateKey.random(RSA), [server])
|
serverInfo = PeerInfo.init(PrivateKey.random(RSA).get(), [server])
|
||||||
serverNoise = newNoise(serverInfo.privateKey, outgoing = false)
|
serverNoise = newNoise(serverInfo.privateKey, outgoing = false)
|
||||||
readTask = newFuture[void]()
|
readTask = newFuture[void]()
|
||||||
|
|
||||||
|
@ -178,7 +178,7 @@ suite "Noise":
|
||||||
|
|
||||||
let
|
let
|
||||||
transport2: TcpTransport = newTransport(TcpTransport)
|
transport2: TcpTransport = newTransport(TcpTransport)
|
||||||
clientInfo = PeerInfo.init(PrivateKey.random(RSA), [transport1.ma])
|
clientInfo = PeerInfo.init(PrivateKey.random(RSA).get(), [transport1.ma])
|
||||||
clientNoise = newNoise(clientInfo.privateKey, outgoing = true)
|
clientNoise = newNoise(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)
|
||||||
|
|
|
@ -101,8 +101,8 @@ const
|
||||||
suite "Peer testing suite":
|
suite "Peer testing suite":
|
||||||
test "Go PeerID test vectors":
|
test "Go PeerID test vectors":
|
||||||
for i in 0..<len(PrivateKeys):
|
for i in 0..<len(PrivateKeys):
|
||||||
var seckey = PrivateKey.init(stripSpaces(PrivateKeys[i]))
|
var seckey = PrivateKey.init(stripSpaces(PrivateKeys[i])).get()
|
||||||
var pubkey = seckey.getKey()
|
var pubkey = seckey.getKey().get()
|
||||||
var p1 = PeerID.init(seckey)
|
var p1 = PeerID.init(seckey)
|
||||||
var p2 = PeerID.init(pubkey)
|
var p2 = PeerID.init(pubkey)
|
||||||
var p3 = PeerID.init(PeerIDs[i])
|
var p3 = PeerID.init(PeerIDs[i])
|
||||||
|
|
|
@ -13,29 +13,29 @@ suite "PeerInfo":
|
||||||
check tracker.isLeaked() == false
|
check tracker.isLeaked() == false
|
||||||
|
|
||||||
test "Should init with private key":
|
test "Should init with private key":
|
||||||
let seckey = PrivateKey.random(RSA)
|
let seckey = PrivateKey.random(RSA).get()
|
||||||
var peerInfo = PeerInfo.init(seckey)
|
var peerInfo = PeerInfo.init(seckey)
|
||||||
var peerId = PeerID.init(seckey)
|
var peerId = PeerID.init(seckey)
|
||||||
|
|
||||||
check peerId == peerInfo.peerId
|
check peerId == peerInfo.peerId
|
||||||
check seckey == peerInfo.privateKey
|
check seckey == peerInfo.privateKey
|
||||||
check seckey.getKey == 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(RSA)
|
let seckey = PrivateKey.random(RSA).get()
|
||||||
var peerInfo = PeerInfo.init(seckey.getKey())
|
var peerInfo = PeerInfo.init(seckey.getKey().get())
|
||||||
var peerId = PeerID.init(seckey.getKey())
|
var peerId = PeerID.init(seckey.getKey().get())
|
||||||
|
|
||||||
check peerId == peerInfo.peerId
|
check peerId == peerInfo.peerId
|
||||||
check seckey.getKey == 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)
|
let seckey = PrivateKey.random(Ed25519).get()
|
||||||
var peerInfo = PeerInfo.init(PeerID.init(seckey.getKey()))
|
var peerInfo = PeerInfo.init(PeerID.init(seckey.getKey.get()))
|
||||||
var peerId = PeerID.init(seckey.getKey())
|
var peerId = PeerID.init(seckey.getKey.get())
|
||||||
|
|
||||||
check peerId == peerInfo.peerId
|
check peerId == peerInfo.peerId
|
||||||
check seckey.getKey == peerInfo.publicKey.get()
|
check seckey.getKey.get() == peerInfo.publicKey.get()
|
||||||
|
|
||||||
test "Should init from CIDv0 string":
|
test "Should init from CIDv0 string":
|
||||||
var peerInfo = PeerInfo.init("QmYyQSo1c1Ym7orWxLYvCrM2EmxFTANf8wXmmE7DWjhx5N")
|
var peerInfo = PeerInfo.init("QmYyQSo1c1Ym7orWxLYvCrM2EmxFTANf8wXmmE7DWjhx5N")
|
||||||
|
@ -52,16 +52,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(RSA)))
|
let peerInfo = PeerInfo.init(PeerID.init(PrivateKey.random(RSA).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)))
|
let peerInfo = PeerInfo.init(PeerID.init(PrivateKey.random(Ed25519).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)))
|
let peerInfo = PeerInfo.init(PeerID.init(PrivateKey.random(Ed25519).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
|
||||||
|
|
|
@ -273,14 +273,14 @@ 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(512)
|
var key = RsaPrivateKey.random(512).expect("random key")
|
||||||
var skey1 = key.getBytes()
|
var skey1 = key.getBytes().expect("bytes")
|
||||||
check key.toBytes(skey2) > 0
|
check key.toBytes(skey2).expect("bytes") > 0
|
||||||
check:
|
check:
|
||||||
rkey1.init(skey1).isOk()
|
rkey1.init(skey1).isOk()
|
||||||
rkey2.init(skey2).isOk()
|
rkey2.init(skey2).isOk()
|
||||||
var rkey3 = RsaPrivateKey.init(skey1)
|
var rkey3 = RsaPrivateKey.init(skey1).expect("key initialization")
|
||||||
var rkey4 = RsaPrivateKey.init(skey2)
|
var rkey4 = RsaPrivateKey.init(skey2).expect("key initialization")
|
||||||
check:
|
check:
|
||||||
rkey1 == key
|
rkey1 == key
|
||||||
rkey2 == key
|
rkey2 == key
|
||||||
|
@ -291,14 +291,14 @@ 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)
|
var key = RsaPrivateKey.random(1024).expect("random failed")
|
||||||
var skey1 = key.getBytes()
|
var skey1 = key.getBytes().expect("bytes")
|
||||||
check key.toBytes(skey2) > 0
|
check key.toBytes(skey2).expect("bytes") > 0
|
||||||
check:
|
check:
|
||||||
rkey1.init(skey1).isOk()
|
rkey1.init(skey1).isOk()
|
||||||
rkey2.init(skey2).isOk()
|
rkey2.init(skey2).isOk()
|
||||||
var rkey3 = RsaPrivateKey.init(skey1)
|
var rkey3 = RsaPrivateKey.init(skey1).expect("key initialization")
|
||||||
var rkey4 = RsaPrivateKey.init(skey2)
|
var rkey4 = RsaPrivateKey.init(skey2).expect("key initialization")
|
||||||
check:
|
check:
|
||||||
rkey1 == key
|
rkey1 == key
|
||||||
rkey2 == key
|
rkey2 == key
|
||||||
|
@ -308,14 +308,14 @@ 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)
|
var key = RsaPrivateKey.random(2048).expect("random failed")
|
||||||
var skey1 = key.getBytes()
|
var skey1 = key.getBytes().expect("bytes")
|
||||||
check key.toBytes(skey2) > 0
|
check key.toBytes(skey2).expect("bytes") > 0
|
||||||
check:
|
check:
|
||||||
rkey1.init(skey1).isOk()
|
rkey1.init(skey1).isOk()
|
||||||
rkey2.init(skey2).isOk()
|
rkey2.init(skey2).isOk()
|
||||||
var rkey3 = RsaPrivateKey.init(skey1)
|
var rkey3 = RsaPrivateKey.init(skey1).expect("key initialization")
|
||||||
var rkey4 = RsaPrivateKey.init(skey2)
|
var rkey4 = RsaPrivateKey.init(skey2).expect("key initialization")
|
||||||
check:
|
check:
|
||||||
rkey1 == key
|
rkey1 == key
|
||||||
rkey2 == key
|
rkey2 == key
|
||||||
|
@ -327,14 +327,14 @@ 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)
|
var key = RsaPrivateKey.random(4096).expect("random failed")
|
||||||
var skey1 = key.getBytes()
|
var skey1 = key.getBytes().expect("bytes")
|
||||||
check key.toBytes(skey2) > 0
|
check key.toBytes(skey2).expect("bytes") > 0
|
||||||
check:
|
check:
|
||||||
rkey1.init(skey1).isOk()
|
rkey1.init(skey1).isOk()
|
||||||
rkey2.init(skey2).isOk()
|
rkey2.init(skey2).isOk()
|
||||||
var rkey3 = RsaPrivateKey.init(skey1)
|
var rkey3 = RsaPrivateKey.init(skey1).expect("key initialization")
|
||||||
var rkey4 = RsaPrivateKey.init(skey2)
|
var rkey4 = RsaPrivateKey.init(skey2).expect("key initialization")
|
||||||
check:
|
check:
|
||||||
rkey1 == key
|
rkey1 == key
|
||||||
rkey2 == key
|
rkey2 == key
|
||||||
|
@ -345,14 +345,14 @@ 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)
|
var pair = RsaKeyPair.random(512).expect("random failed")
|
||||||
var skey1 = pair.pubkey().getBytes()
|
var skey1 = pair.pubkey().getBytes().expect("bytes")
|
||||||
check:
|
check:
|
||||||
pair.pubkey.toBytes(skey2) > 0
|
pair.pubkey.toBytes(skey2).expect("bytes") > 0
|
||||||
rkey1.init(skey1).isOk()
|
rkey1.init(skey1).isOk()
|
||||||
rkey2.init(skey2).isOk()
|
rkey2.init(skey2).isOk()
|
||||||
var rkey3 = RsaPublicKey.init(skey1)
|
var rkey3 = RsaPublicKey.init(skey1).expect("key initialization")
|
||||||
var rkey4 = RsaPublicKey.init(skey2)
|
var rkey4 = RsaPublicKey.init(skey2).expect("key initialization")
|
||||||
check:
|
check:
|
||||||
rkey1 == pair.pubkey
|
rkey1 == pair.pubkey
|
||||||
rkey2 == pair.pubkey
|
rkey2 == pair.pubkey
|
||||||
|
@ -363,14 +363,14 @@ 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)
|
var pair = RsaKeyPair.random(1024).expect("random failed")
|
||||||
var skey1 = pair.pubkey.getBytes()
|
var skey1 = pair.pubkey.getBytes().expect("bytes")
|
||||||
check:
|
check:
|
||||||
pair.pubkey.toBytes(skey2) > 0
|
pair.pubkey.toBytes(skey2).expect("bytes") > 0
|
||||||
rkey1.init(skey1).isOk()
|
rkey1.init(skey1).isOk()
|
||||||
rkey2.init(skey2).isOk()
|
rkey2.init(skey2).isOk()
|
||||||
var rkey3 = RsaPublicKey.init(skey1)
|
var rkey3 = RsaPublicKey.init(skey1).expect("key initialization")
|
||||||
var rkey4 = RsaPublicKey.init(skey2)
|
var rkey4 = RsaPublicKey.init(skey2).expect("key initialization")
|
||||||
check:
|
check:
|
||||||
rkey1 == pair.pubkey
|
rkey1 == pair.pubkey
|
||||||
rkey2 == pair.pubkey
|
rkey2 == pair.pubkey
|
||||||
|
@ -380,14 +380,14 @@ 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)
|
var pair = RsaKeyPair.random(2048).expect("random failed")
|
||||||
var skey1 = pair.pubkey.getBytes()
|
var skey1 = pair.pubkey.getBytes().expect("bytes")
|
||||||
check:
|
check:
|
||||||
pair.pubkey.toBytes(skey2) > 0
|
pair.pubkey.toBytes(skey2).expect("bytes") > 0
|
||||||
rkey1.init(skey1).isOk()
|
rkey1.init(skey1).isOk()
|
||||||
rkey2.init(skey2).isOk()
|
rkey2.init(skey2).isOk()
|
||||||
var rkey3 = RsaPublicKey.init(skey1)
|
var rkey3 = RsaPublicKey.init(skey1).expect("key initialization")
|
||||||
var rkey4 = RsaPublicKey.init(skey2)
|
var rkey4 = RsaPublicKey.init(skey2).expect("key initialization")
|
||||||
check:
|
check:
|
||||||
rkey1 == pair.pubkey
|
rkey1 == pair.pubkey
|
||||||
rkey2 == pair.pubkey
|
rkey2 == pair.pubkey
|
||||||
|
@ -398,14 +398,14 @@ 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)
|
var pair = RsaKeyPair.random(4096).expect("random failed")
|
||||||
var skey1 = pair.pubkey.getBytes()
|
var skey1 = pair.pubkey.getBytes().expect("bytes")
|
||||||
check:
|
check:
|
||||||
pair.pubkey.toBytes(skey2) > 0
|
pair.pubkey.toBytes(skey2).expect("bytes") > 0
|
||||||
rkey1.init(skey1).isOk()
|
rkey1.init(skey1).isOk()
|
||||||
rkey2.init(skey2).isOk()
|
rkey2.init(skey2).isOk()
|
||||||
var rkey3 = RsaPublicKey.init(skey1)
|
var rkey3 = RsaPublicKey.init(skey1).expect("key initialization")
|
||||||
var rkey4 = RsaPublicKey.init(skey2)
|
var rkey4 = RsaPublicKey.init(skey2).expect("key initialization")
|
||||||
check:
|
check:
|
||||||
rkey1 == pair.pubkey
|
rkey1 == pair.pubkey
|
||||||
rkey2 == pair.pubkey
|
rkey2 == pair.pubkey
|
||||||
|
@ -415,154 +415,154 @@ 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)
|
var kp = RsaKeyPair.random(512).expect("RsaKeyPair.random failed")
|
||||||
var sig = kp.seckey.sign(message)
|
var sig = kp.seckey.sign(message).expect("signature")
|
||||||
var sersk = kp.seckey.getBytes()
|
var sersk = kp.seckey.getBytes().expect("bytes")
|
||||||
var serpk = kp.pubkey.getBytes()
|
var serpk = kp.pubkey.getBytes().expect("bytes")
|
||||||
var sersig = sig.getBytes()
|
var sersig = sig.getBytes().expect("bytes")
|
||||||
discard RsaPrivateKey.init(sersk)
|
discard RsaPrivateKey.init(sersk).expect("RsaPrivateKey.key initialization")
|
||||||
var pubkey = RsaPublicKey.init(serpk)
|
var pubkey = RsaPublicKey.init(serpk).expect("RsaPublicKey.key initialization")
|
||||||
var csig = RsaSignature.init(sersig)
|
var csig = RsaSignature.init(sersig).expect("RsaSignature.key initialization")
|
||||||
check csig.verify(message, pubkey) == true
|
check csig.verify(message, pubkey) == true
|
||||||
let error = len(csig.buffer) - 1
|
let error = csig.buffer.high
|
||||||
csig.buffer[error] = not(csig.buffer[error])
|
csig.buffer[error] = not(csig.buffer[error])
|
||||||
check csig.verify(message, pubkey) == false
|
check csig.verify(message, pubkey) == false
|
||||||
|
|
||||||
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)
|
var kp = RsaKeyPair.random(1024).expect("RsaPrivateKey.random failed")
|
||||||
var sig = kp.seckey.sign(message)
|
var sig = kp.seckey.sign(message).expect("signature")
|
||||||
var sersk = kp.seckey.getBytes()
|
var sersk = kp.seckey.getBytes().expect("bytes")
|
||||||
var serpk = kp.pubkey.getBytes()
|
var serpk = kp.pubkey.getBytes().expect("bytes")
|
||||||
var sersig = sig.getBytes()
|
var sersig = sig.getBytes().expect("bytes")
|
||||||
discard RsaPrivateKey.init(sersk)
|
discard RsaPrivateKey.init(sersk).expect("key initialization")
|
||||||
var pubkey = RsaPublicKey.init(serpk)
|
var pubkey = RsaPublicKey.init(serpk).expect("key initialization")
|
||||||
var csig = RsaSignature.init(sersig)
|
var csig = RsaSignature.init(sersig).expect("key initialization")
|
||||||
check csig.verify(message, pubkey) == true
|
check csig.verify(message, pubkey) == true
|
||||||
let error = len(csig.buffer) - 1
|
let error = csig.buffer.high
|
||||||
csig.buffer[error] = not(csig.buffer[error])
|
csig.buffer[error] = not(csig.buffer[error])
|
||||||
check csig.verify(message, pubkey) == false
|
check csig.verify(message, pubkey) == false
|
||||||
|
|
||||||
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)
|
var kp = RsaKeyPair.random(2048).expect("RsaPrivateKey.random failed")
|
||||||
var sig = kp.seckey.sign(message)
|
var sig = kp.seckey.sign(message).expect("signature")
|
||||||
var sersk = kp.seckey.getBytes()
|
var sersk = kp.seckey.getBytes().expect("bytes")
|
||||||
var serpk = kp.pubkey.getBytes()
|
var serpk = kp.pubkey.getBytes().expect("bytes")
|
||||||
var sersig = sig.getBytes()
|
var sersig = sig.getBytes().expect("bytes")
|
||||||
discard RsaPrivateKey.init(sersk)
|
discard RsaPrivateKey.init(sersk).expect("key initialization")
|
||||||
var pubkey = RsaPublicKey.init(serpk)
|
var pubkey = RsaPublicKey.init(serpk).expect("key initialization")
|
||||||
var csig = RsaSignature.init(sersig)
|
var csig = RsaSignature.init(sersig).expect("key initialization")
|
||||||
check csig.verify(message, pubkey) == true
|
check csig.verify(message, pubkey) == true
|
||||||
let error = len(csig.buffer) - 1
|
let error = csig.buffer.high
|
||||||
csig.buffer[error] = not(csig.buffer[error])
|
csig.buffer[error] = not(csig.buffer[error])
|
||||||
check csig.verify(message, pubkey) == false
|
check csig.verify(message, pubkey) == false
|
||||||
|
|
||||||
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)
|
var kp = RsaKeyPair.random(2048).expect("RsaPrivateKey.random failed")
|
||||||
var sig = kp.seckey.sign(message)
|
var sig = kp.seckey.sign(message).expect("signature")
|
||||||
var sersk = kp.seckey.getBytes()
|
var sersk = kp.seckey.getBytes().expect("bytes")
|
||||||
var serpk = kp.pubkey.getBytes()
|
var serpk = kp.pubkey.getBytes().expect("bytes")
|
||||||
var sersig = sig.getBytes()
|
var sersig = sig.getBytes().expect("bytes")
|
||||||
discard RsaPrivateKey.init(sersk)
|
discard RsaPrivateKey.init(sersk).expect("key initialization")
|
||||||
var pubkey = RsaPublicKey.init(serpk)
|
var pubkey = RsaPublicKey.init(serpk).expect("key initialization")
|
||||||
var csig = RsaSignature.init(sersig)
|
var csig = RsaSignature.init(sersig).expect("key initialization")
|
||||||
check csig.verify(message, pubkey) == true
|
check csig.verify(message, pubkey) == true
|
||||||
let error = len(csig.buffer) - 1
|
let error = csig.buffer.high
|
||||||
csig.buffer[error] = not(csig.buffer[error])
|
csig.buffer[error] = not(csig.buffer[error])
|
||||||
check csig.verify(message, pubkey) == false
|
check csig.verify(message, pubkey) == false
|
||||||
|
|
||||||
test "[rsa512] Test vectors":
|
test "[rsa512] Test vectors":
|
||||||
var prvser = fromHex(stripSpaces(PrivateKeys[0]))
|
var prvser = fromHex(stripSpaces(PrivateKeys[0]))
|
||||||
var pubser = fromHex(stripSpaces(PublicKeys[0]))
|
var pubser = fromHex(stripSpaces(PublicKeys[0]))
|
||||||
var seckey = RsaPrivateKey.init(prvser)
|
var seckey = RsaPrivateKey.init(prvser).expect("key initialization")
|
||||||
var pubkey = RsaPublicKey.init(pubser)
|
var pubkey = RsaPublicKey.init(pubser).expect("key initialization")
|
||||||
check:
|
check:
|
||||||
seckey.getBytes() == prvser
|
seckey.getBytes().expect("bytes") == prvser
|
||||||
var cpubkey = seckey.getKey()
|
var cpubkey = seckey.getKey()
|
||||||
check:
|
check:
|
||||||
pubkey == cpubkey
|
pubkey == cpubkey
|
||||||
pubkey.getBytes() == cpubkey.getBytes()
|
pubkey.getBytes().expect("bytes") == cpubkey.getBytes().expect("bytes")
|
||||||
pubkey.getBytes() == pubser
|
pubkey.getBytes().expect("bytes") == pubser
|
||||||
|
|
||||||
for i in 0..1:
|
for i in 0..1:
|
||||||
var sigser = fromHex(stripSpaces(Signatures[i]))
|
var sigser = fromHex(stripSpaces(Signatures[i]))
|
||||||
var sig = RsaSignature.init(sigser)
|
var sig = RsaSignature.init(sigser).expect("key initialization")
|
||||||
var csig = seckey.sign(Messages[i])
|
var csig = seckey.sign(Messages[i]).expect("signature")
|
||||||
check:
|
check:
|
||||||
sig == csig
|
sig == csig
|
||||||
sig.getBytes() == csig.getBytes()
|
sig.getBytes().expect("bytes") == csig.getBytes().expect("bytes")
|
||||||
csig.verify(Messages[i], pubkey) == true
|
csig.verify(Messages[i], pubkey) == true
|
||||||
csig.verify(Messages[(i + 1) mod 2], pubkey) == false
|
csig.verify(Messages[(i + 1) mod 2], pubkey) == false
|
||||||
|
|
||||||
test "[rsa1024] Test vectors":
|
test "[rsa1024] Test vectors":
|
||||||
var prvser = fromHex(stripSpaces(PrivateKeys[1]))
|
var prvser = fromHex(stripSpaces(PrivateKeys[1]))
|
||||||
var pubser = fromHex(stripSpaces(PublicKeys[1]))
|
var pubser = fromHex(stripSpaces(PublicKeys[1]))
|
||||||
var seckey = RsaPrivateKey.init(prvser)
|
var seckey = RsaPrivateKey.init(prvser).expect("key initialization")
|
||||||
var pubkey = RsaPublicKey.init(pubser)
|
var pubkey = RsaPublicKey.init(pubser).expect("key initialization")
|
||||||
check:
|
check:
|
||||||
seckey.getBytes() == prvser
|
seckey.getBytes().expect("bytes") == prvser
|
||||||
var cpubkey = seckey.getKey()
|
var cpubkey = seckey.getKey()
|
||||||
check:
|
check:
|
||||||
pubkey == cpubkey
|
pubkey == cpubkey
|
||||||
pubkey.getBytes() == cpubkey.getBytes()
|
pubkey.getBytes().expect("bytes") == cpubkey.getBytes().expect("bytes")
|
||||||
pubkey.getBytes() == pubser
|
pubkey.getBytes().expect("bytes") == pubser
|
||||||
|
|
||||||
for i in 0..1:
|
for i in 0..1:
|
||||||
var sigser = fromHex(stripSpaces(Signatures[2 + i]))
|
var sigser = fromHex(stripSpaces(Signatures[2 + i]))
|
||||||
var sig = RsaSignature.init(sigser)
|
var sig = RsaSignature.init(sigser).expect("key initialization")
|
||||||
var csig = seckey.sign(Messages[2 + i])
|
var csig = seckey.sign(Messages[2 + i]).expect("signature")
|
||||||
check:
|
check:
|
||||||
sig == csig
|
sig == csig
|
||||||
sig.getBytes() == csig.getBytes()
|
sig.getBytes().expect("bytes") == csig.getBytes().expect("bytes")
|
||||||
csig.verify(Messages[2 + i], pubkey) == true
|
csig.verify(Messages[2 + i], pubkey) == true
|
||||||
csig.verify(Messages[2 + (i + 1) mod 2], pubkey) == false
|
csig.verify(Messages[2 + (i + 1) mod 2], pubkey) == false
|
||||||
|
|
||||||
test "[rsa2048] Test vectors":
|
test "[rsa2048] Test vectors":
|
||||||
var prvser = fromHex(stripSpaces(PrivateKeys[2]))
|
var prvser = fromHex(stripSpaces(PrivateKeys[2]))
|
||||||
var pubser = fromHex(stripSpaces(PublicKeys[2]))
|
var pubser = fromHex(stripSpaces(PublicKeys[2]))
|
||||||
var seckey = RsaPrivateKey.init(prvser)
|
var seckey = RsaPrivateKey.init(prvser).expect("key initialization")
|
||||||
var pubkey = RsaPublicKey.init(pubser)
|
var pubkey = RsaPublicKey.init(pubser).expect("key initialization")
|
||||||
check:
|
check:
|
||||||
seckey.getBytes() == prvser
|
seckey.getBytes().expect("bytes") == prvser
|
||||||
var cpubkey = seckey.getKey()
|
var cpubkey = seckey.getKey()
|
||||||
check:
|
check:
|
||||||
pubkey == cpubkey
|
pubkey == cpubkey
|
||||||
pubkey.getBytes() == cpubkey.getBytes()
|
pubkey.getBytes().expect("bytes") == cpubkey.getBytes().expect("bytes")
|
||||||
pubkey.getBytes() == pubser
|
pubkey.getBytes().expect("bytes") == pubser
|
||||||
|
|
||||||
for i in 0..1:
|
for i in 0..1:
|
||||||
var sigser = fromHex(stripSpaces(Signatures[4 + i]))
|
var sigser = fromHex(stripSpaces(Signatures[4 + i]))
|
||||||
var sig = RsaSignature.init(sigser)
|
var sig = RsaSignature.init(sigser).expect("key initialization")
|
||||||
var csig = seckey.sign(Messages[4 + i])
|
var csig = seckey.sign(Messages[4 + i]).expect("signature")
|
||||||
check:
|
check:
|
||||||
sig == csig
|
sig == csig
|
||||||
sig.getBytes() == csig.getBytes()
|
sig.getBytes().expect("bytes") == csig.getBytes().expect("bytes")
|
||||||
csig.verify(Messages[4 + i], pubkey) == true
|
csig.verify(Messages[4 + i], pubkey) == true
|
||||||
csig.verify(Messages[4 + (i + 1) mod 2], pubkey) == false
|
csig.verify(Messages[4 + (i + 1) mod 2], pubkey) == false
|
||||||
|
|
||||||
test "[rsa4096] Test vectors":
|
test "[rsa4096] Test vectors":
|
||||||
var prvser = fromHex(stripSpaces(PrivateKeys[3]))
|
var prvser = fromHex(stripSpaces(PrivateKeys[3]))
|
||||||
var pubser = fromHex(stripSpaces(PublicKeys[3]))
|
var pubser = fromHex(stripSpaces(PublicKeys[3]))
|
||||||
var seckey = RsaPrivateKey.init(prvser)
|
var seckey = RsaPrivateKey.init(prvser).expect("key initialization")
|
||||||
var pubkey = RsaPublicKey.init(pubser)
|
var pubkey = RsaPublicKey.init(pubser).expect("key initialization")
|
||||||
check:
|
check:
|
||||||
seckey.getBytes() == prvser
|
seckey.getBytes().expect("bytes") == prvser
|
||||||
var cpubkey = seckey.getKey()
|
var cpubkey = seckey.getKey()
|
||||||
check:
|
check:
|
||||||
pubkey == cpubkey
|
pubkey == cpubkey
|
||||||
pubkey.getBytes() == cpubkey.getBytes()
|
pubkey.getBytes().expect("bytes") == cpubkey.getBytes().expect("bytes")
|
||||||
pubkey.getBytes() == pubser
|
pubkey.getBytes().expect("bytes") == pubser
|
||||||
|
|
||||||
for i in 0..1:
|
for i in 0..1:
|
||||||
var sigser = fromHex(stripSpaces(Signatures[6 + i]))
|
var sigser = fromHex(stripSpaces(Signatures[6 + i]))
|
||||||
var sig = RsaSignature.init(sigser)
|
var sig = RsaSignature.init(sigser).expect("key initialization")
|
||||||
var csig = seckey.sign(Messages[6 + i])
|
var csig = seckey.sign(Messages[6 + i]).expect("signature")
|
||||||
check:
|
check:
|
||||||
sig == csig
|
sig == csig
|
||||||
sig.getBytes() == csig.getBytes()
|
sig.getBytes().expect("bytes") == csig.getBytes().expect("bytes")
|
||||||
csig.verify(Messages[6 + i], pubkey) == true
|
csig.verify(Messages[6 + i], pubkey) == true
|
||||||
csig.verify(Messages[6 + (i + 1) mod 2], pubkey) == false
|
csig.verify(Messages[6 + (i + 1) mod 2], pubkey) == false
|
||||||
|
|
|
@ -18,15 +18,15 @@ suite "Secp256k1 testing suite":
|
||||||
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()
|
var key = SkPrivateKey.random().expect("random key")
|
||||||
var skey1 = key.getBytes()
|
var skey1 = key.getBytes()
|
||||||
check:
|
check:
|
||||||
key.toBytes(skey2) > 0
|
key.toBytes(skey2).expect("bytes len") > 0
|
||||||
check:
|
check:
|
||||||
rkey1.init(skey1) == true
|
rkey1.init(skey1).isOk == true
|
||||||
rkey2.init(skey2) == true
|
rkey2.init(skey2).isOk == true
|
||||||
var rkey3 = SkPrivateKey.init(skey1)
|
var rkey3 = SkPrivateKey.init(skey1).expect("private key")
|
||||||
var rkey4 = SkPrivateKey.init(skey2)
|
var rkey4 = SkPrivateKey.init(skey2).expect("private key")
|
||||||
check:
|
check:
|
||||||
rkey1 == key
|
rkey1 == key
|
||||||
rkey2 == key
|
rkey2 == key
|
||||||
|
@ -41,14 +41,14 @@ 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()
|
var pair = SkKeyPair.random().expect("random key pair")
|
||||||
var skey1 = pair.pubkey.getBytes()
|
var skey1 = pair.pubkey.getBytes()
|
||||||
check:
|
check:
|
||||||
pair.pubkey.toBytes(skey2) > 0
|
pair.pubkey.toBytes(skey2).expect("bytes len") > 0
|
||||||
rkey1.init(skey1) == true
|
rkey1.init(skey1).isOk == true
|
||||||
rkey2.init(skey2) == true
|
rkey2.init(skey2).isOk == true
|
||||||
var rkey3 = SkPublicKey.init(skey1)
|
var rkey3 = SkPublicKey.init(skey1).expect("public key")
|
||||||
var rkey4 = SkPublicKey.init(skey2)
|
var rkey4 = SkPublicKey.init(skey2).expect("public key")
|
||||||
check:
|
check:
|
||||||
rkey1 == pair.pubkey
|
rkey1 == pair.pubkey
|
||||||
rkey2 == pair.pubkey
|
rkey2 == pair.pubkey
|
||||||
|
@ -59,16 +59,16 @@ 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()
|
var kp = SkKeyPair.random().expect("random key pair")
|
||||||
var sig = kp.seckey.sign(message)
|
var sig = kp.seckey.sign(message).expect("signature")
|
||||||
var sersk = kp.seckey.getBytes()
|
var sersk = kp.seckey.getBytes()
|
||||||
var serpk = kp.pubkey.getBytes()
|
var serpk = kp.pubkey.getBytes()
|
||||||
var sersig = sig.getBytes()
|
var sersig = sig.getBytes()
|
||||||
discard SkPrivateKey.init(sersk)
|
discard SkPrivateKey.init(sersk).expect("private key")
|
||||||
var pubkey = SkPublicKey.init(serpk)
|
var pubkey = SkPublicKey.init(serpk).expect("public key")
|
||||||
var csig = SkSignature.init(sersig)
|
var csig = SkSignature.init(sersig).expect("signature")
|
||||||
check csig.verify(message, pubkey) == true
|
check csig.verify(message, pubkey) == true
|
||||||
var error = csig.getBytes()
|
var error = csig.getBytes()
|
||||||
error[^1] = not error[^1]
|
error[^1] = not error[^1]
|
||||||
csig = SkSignature.init(error)
|
csig = SkSignature.init(error).expect("signature")
|
||||||
check csig.verify(message, pubkey) == false
|
check csig.verify(message, pubkey) == false
|
||||||
|
|
|
@ -31,7 +31,7 @@ type
|
||||||
TestProto = ref object of LPProtocol
|
TestProto = ref object of LPProtocol
|
||||||
|
|
||||||
proc createSwitch(ma: MultiAddress): (Switch, PeerInfo) =
|
proc createSwitch(ma: MultiAddress): (Switch, PeerInfo) =
|
||||||
var peerInfo: PeerInfo = PeerInfo.init(PrivateKey.random(RSA))
|
var peerInfo: PeerInfo = PeerInfo.init(PrivateKey.random(RSA).tryGet())
|
||||||
peerInfo.addrs.add(ma)
|
peerInfo.addrs.add(ma)
|
||||||
let identify = newIdentify(peerInfo)
|
let identify = newIdentify(peerInfo)
|
||||||
|
|
||||||
|
|
|
@ -263,7 +263,7 @@ suite "Variable integer test suite":
|
||||||
buffer.setLen(PBedgeSizes[i])
|
buffer.setLen(PBedgeSizes[i])
|
||||||
check:
|
check:
|
||||||
PB.putUVarint(buffer, length, PBedgeValues[i]) == VarintStatus.Success
|
PB.putUVarint(buffer, length, PBedgeValues[i]) == VarintStatus.Success
|
||||||
buffer.setLen(len(buffer) - 1)
|
buffer.setlen(buffer.high)
|
||||||
check:
|
check:
|
||||||
PB.getUVarint(buffer, length, value) == VarintStatus.Incomplete
|
PB.getUVarint(buffer, length, value) == VarintStatus.Incomplete
|
||||||
|
|
||||||
|
@ -339,7 +339,7 @@ suite "Variable integer test suite":
|
||||||
buffer.setLen(LPedgeSizes[i])
|
buffer.setLen(LPedgeSizes[i])
|
||||||
check:
|
check:
|
||||||
LP.putUVarint(buffer, length, LPedgeValues[i]) == VarintStatus.Success
|
LP.putUVarint(buffer, length, LPedgeValues[i]) == VarintStatus.Success
|
||||||
buffer.setLen(len(buffer) - 1)
|
buffer.setlen(buffer.high)
|
||||||
check:
|
check:
|
||||||
LP.getUVarint(buffer, length, value) == VarintStatus.Incomplete
|
LP.getUVarint(buffer, length, value) == VarintStatus.Incomplete
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue