Crypto utilities resultification (#150)

This commit is contained in:
Giovanni Petrantoni 2020-05-18 14:25:55 +09:00 committed by GitHub
parent 167f42ed45
commit 7dcb807f64
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
37 changed files with 1180 additions and 1033 deletions

View File

@ -152,7 +152,7 @@ proc readInput(wfd: AsyncFD) {.thread.} =
proc processInput(rfd: AsyncFD) {.async.} =
let transp = fromPipe(rfd)
let seckey = PrivateKey.random(RSA)
let seckey = PrivateKey.random(RSA).get()
let peerInfo = PeerInfo.init(seckey)
var localAddress = DefaultAddr
while true:

View File

@ -95,7 +95,7 @@ proc decode(data: openarray[byte], cid: var Cid): CidStatus =
if mcodec == InvalidMultiCodec:
return CidStatus.Incorrect
if not MultiHash.validate(vb.buffer.toOpenArray(vb.offset,
len(vb.buffer) - 1)):
vb.buffer.high)):
return CidStatus.Incorrect
vb.finish()
cid.cidver = CIDv1
@ -133,7 +133,7 @@ proc validate*(ctype: typedesc[Cid], data: openarray[byte]): bool =
var res: VarintStatus
if len(data) < 2:
return false
let last = len(data) - 1
let last = data.high
if len(data) == 34:
if data[0] == 0x12'u8 and data[1] == 0x20'u8:
return true
@ -161,8 +161,8 @@ proc mhash*(cid: Cid): MultiHash =
## Returns MultiHash part of CID.
if cid.cidver notin {CIDv0, CIDv1}:
raise newException(CidError, "Incorrect CID!")
result = MultiHash.init(cid.data.buffer.toOpenArray(cid.hpos,
len(cid.data) - 1))
result = MultiHash.init(
cid.data.buffer.toOpenArray(cid.hpos, cid.data.high)).tryGet()
proc contentType*(cid: Cid): MultiCodec =
## Returns content type part of CID
@ -221,11 +221,11 @@ proc `==`*(a: Cid, b: Cid): bool =
## are equal, ``false`` otherwise.
if a.mcodec == b.mcodec:
var ah, bh: MultiHash
if MultiHash.decode(a.data.buffer.toOpenArray(a.hpos,
len(a.data) - 1), ah) == -1:
if MultiHash.decode(
a.data.buffer.toOpenArray(a.hpos, a.data.high), ah).isErr:
return false
if MultiHash.decode(b.data.buffer.toOpenArray(b.hpos,
len(b.data) - 1), bh) == -1:
if MultiHash.decode(
b.data.buffer.toOpenArray(b.hpos, b.data.high), bh).isErr:
return false
result = (ah == bh)

View File

@ -8,6 +8,9 @@
## those terms.
## This module implements Public Key and Private Key interface for libp2p.
{.push raises: [Defect].}
import rsa, ecnist, ed25519/ed25519, secp
import ../protobuf/minprotobuf, ../vbuffer, ../multihash, ../multicodec
import nimcrypto/[rijndael, blowfish, twofish, sha, sha2, hash, hmac, utils]
@ -79,172 +82,177 @@ type
Signature* = object
data*: seq[byte]
P2pKeyError* = object of CatchableError
P2pSigError* = object of CatchableError
CryptoError* = enum
KeyError,
SigError,
HashError,
SchemeError
CryptoResult*[T] = Result[T, CryptoError]
const
SupportedSchemes* = {RSA, Ed25519, Secp256k1, ECDSA}
SupportedSchemesInt* = {int8(RSA), int8(Ed25519), int8(Secp256k1),
int8(ECDSA)}
template orError(exp: untyped, err: CryptoError): untyped =
(exp.mapErr do (_: auto) -> auto: err)
proc random*(t: typedesc[PrivateKey], scheme: PKScheme,
bits = DefaultKeySize): PrivateKey =
bits = DefaultKeySize): CryptoResult[PrivateKey] =
## Generate random private key for scheme ``scheme``.
##
## ``bits`` is number of bits for RSA key, ``bits`` value must be in
## [512, 4096], default value is 2048 bits.
doAssert(scheme in SupportedSchemes)
result = PrivateKey(scheme: scheme)
if scheme == RSA:
result.rsakey = RsaPrivateKey.random(bits)
elif scheme == Ed25519:
result.edkey = EdPrivateKey.random()
elif scheme == ECDSA:
result.eckey = EcPrivateKey.random(Secp256r1)
elif scheme == Secp256k1:
result.skkey = SkPrivateKey.random()
case scheme
of RSA:
let rsakey = ? RsaPrivateKey.random(bits).orError(KeyError)
ok(PrivateKey(scheme: scheme, rsakey: rsakey))
of Ed25519:
let edkey = ? EdPrivateKey.random().orError(KeyError)
ok(PrivateKey(scheme: scheme, edkey: edkey))
of ECDSA:
let eckey = ? EcPrivateKey.random(Secp256r1).orError(KeyError)
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,
bits = DefaultKeySize): KeyPair =
bits = DefaultKeySize): CryptoResult[KeyPair] =
## Generate random key pair for scheme ``scheme``.
##
## ``bits`` is number of bits for RSA key, ``bits`` value must be in
## [512, 4096], default value is 2048 bits.
doAssert(scheme in SupportedSchemes)
result.seckey = PrivateKey(scheme: scheme)
result.pubkey = PublicKey(scheme: scheme)
if scheme == RSA:
var pair = RsaKeyPair.random(bits)
result.seckey.rsakey = pair.seckey
result.pubkey.rsakey = pair.pubkey
elif scheme == Ed25519:
var pair = EdKeyPair.random()
result.seckey.edkey = pair.seckey
result.pubkey.edkey = pair.pubkey
elif scheme == ECDSA:
var pair = EcKeyPair.random(Secp256r1)
result.seckey.eckey = pair.seckey
result.pubkey.eckey = pair.pubkey
elif scheme == Secp256k1:
var pair = SkKeyPair.random()
result.seckey.skkey = pair.seckey
result.pubkey.skkey = pair.pubkey
case scheme
of RSA:
let pair = ? RsaKeyPair.random(bits).orError(KeyError)
ok(KeyPair(
seckey: PrivateKey(scheme: scheme, rsakey: pair.seckey),
pubkey: PublicKey(scheme: scheme, rsakey: pair.pubkey)))
of Ed25519:
let pair = ? EdKeyPair.random().orError(KeyError)
ok(KeyPair(
seckey: PrivateKey(scheme: scheme, edkey: pair.seckey),
pubkey: PublicKey(scheme: scheme, edkey: pair.pubkey)))
of ECDSA:
let pair = ? EcKeyPair.random(Secp256r1).orError(KeyError)
ok(KeyPair(
seckey: PrivateKey(scheme: scheme, eckey: pair.seckey),
pubkey: PublicKey(scheme: scheme, eckey: pair.pubkey)))
of Secp256k1:
let pair = ? SkKeyPair.random().orError(KeyError)
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``.
result = PublicKey(scheme: key.scheme)
if key.scheme == RSA:
result.rsakey = key.rsakey.getKey()
elif key.scheme == Ed25519:
result.edkey = key.edkey.getKey()
elif key.scheme == ECDSA:
result.eckey = key.eckey.getKey()
elif key.scheme == Secp256k1:
result.skkey = key.skkey.getKey()
case key.scheme
of RSA:
let rsakey = key.rsakey.getKey()
ok(PublicKey(scheme: RSA, rsakey: rsakey))
of Ed25519:
let edkey = key.edkey.getKey()
ok(PublicKey(scheme: Ed25519, edkey: edkey))
of ECDSA:
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
## it to ``data``.
##
## Returns number of bytes (octets) needed to store private 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)
case key.scheme
of RSA:
key.rsakey.toBytes(data).orError(KeyError)
of Ed25519:
ok(key.edkey.toBytes(data))
of ECDSA:
key.eckey.toBytes(data).orError(KeyError)
of Secp256k1:
key.skkey.toBytes(data).orError(KeyError)
else:
err(KeyError)
proc toRawBytes*(key: PublicKey, data: var openarray[byte]): int =
## 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] =
proc getRawBytes*(key: PrivateKey | PublicKey): CryptoResult[seq[byte]] =
## Return private 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()
case key.scheme
of RSA:
key.rsakey.getBytes().orError(KeyError)
of Ed25519:
ok(key.edkey.getBytes())
of ECDSA:
key.eckey.getBytes().orError(KeyError)
of Secp256k1:
ok(key.skkey.getBytes())
else:
err(KeyError)
proc getRawBytes*(key: PublicKey): seq[byte] =
## 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 =
proc toBytes*(key: PrivateKey, data: var openarray[byte]): CryptoResult[int] =
## Serialize private key ``key`` (using libp2p protobuf scheme) and store
## it to ``data``.
##
## Returns number of bytes (octets) needed to store private key ``key``.
var msg = initProtoBuffer()
msg.write(initProtoField(1, cast[uint64](key.scheme)))
msg.write(initProtoField(2, key.getRawBytes()))
msg.write(initProtoField(2, ? key.getRawBytes()))
msg.finish()
result = len(msg.buffer)
if len(data) >= result:
copyMem(addr data[0], addr msg.buffer[0], len(msg.buffer))
var blen = len(msg.buffer)
if len(data) >= blen:
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
## it to ``data``.
##
## Returns number of bytes (octets) needed to store public key ``key``.
var msg = initProtoBuffer()
msg.write(initProtoField(1, cast[uint64](key.scheme)))
msg.write(initProtoField(2, key.getRawBytes()))
msg.write(initProtoField(2, ? key.getRawBytes()))
msg.finish()
result = len(msg.buffer)
if len(data) >= result:
copyMem(addr data[0], addr msg.buffer[0], len(msg.buffer))
var blen = len(msg.buffer)
if len(data) >= blen and blen > 0:
copyMem(addr data[0], addr msg.buffer[0], blen)
ok(blen)
proc toBytes*(sig: Signature, data: var openarray[byte]): int =
## Serialize signature ``sig`` and store it to ``data``.
##
## Returns number of bytes (octets) needed to store signature ``sig``.
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))
proc getBytes*(key: PrivateKey): seq[byte] =
proc getBytes*(key: PrivateKey): CryptoResult[seq[byte]] =
## Return private key ``key`` in binary form (using libp2p's protobuf
## serialization).
var msg = initProtoBuffer()
msg.write(initProtoField(1, cast[uint64](key.scheme)))
msg.write(initProtoField(2, key.getRawBytes()))
msg.write(initProtoField(2, ? key.getRawBytes()))
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
## serialization).
var msg = initProtoBuffer()
msg.write(initProtoField(1, cast[uint64](key.scheme)))
msg.write(initProtoField(2, key.getRawBytes()))
msg.write(initProtoField(2, ? key.getRawBytes()))
msg.finish()
result = msg.buffer
ok(msg.buffer)
proc getBytes*(sig: Signature): seq[byte] =
## Return signature ``sig`` in binary form.
@ -277,7 +285,7 @@ proc init*(key: var PrivateKey, data: openarray[byte]): bool =
key = nkey
result = true
elif scheme == Secp256k1:
if init(nkey.skkey, buffer):
if init(nkey.skkey, buffer).isOk:
key = nkey
result = true
@ -308,7 +316,7 @@ proc init*(key: var PublicKey, data: openarray[byte]): bool =
key = nkey
result = true
elif scheme == Secp256k1:
if init(nkey.skkey, buffer):
if init(nkey.skkey, buffer).isOk:
key = nkey
result = true
@ -325,50 +333,77 @@ proc init*(key: var PrivateKey, data: string): bool =
## hexadecimal string representation.
##
## 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 =
## Initialize public key ``key`` from libp2p's protobuf serialized
## hexadecimal string representation.
##
## 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 =
## Initialize signature ``sig`` from serialized hexadecimal string
## representation.
##
## 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.
if not result.init(data):
raise newException(P2pKeyError, "Incorrect binary form")
var res: t
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.
if not result.init(data):
raise newException(P2pKeyError, "Incorrect binary form")
var res: t
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.
if not result.init(data):
raise newException(P2pSigError, "Incorrect binary form")
var res: t
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
## 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
## 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.
result = t.init(fromHex(data))
try:
t.init(fromHex(data))
except ValueError:
err(SigError)
proc `==`*(key1, key2: PublicKey): bool =
## 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``.
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
## signature in raw binary form.
var res: Signature
if key.scheme == RSA:
var sig = key.rsakey.sign(data)
result.data = sig.getBytes()
let sig = ? key.rsakey.sign(data).orError(SigError)
res.data = ? sig.getBytes().orError(SigError)
ok(res)
elif key.scheme == Ed25519:
var sig = key.edkey.sign(data)
result.data = sig.getBytes()
let sig = key.edkey.sign(data)
res.data = sig.getBytes()
ok(res)
elif key.scheme == ECDSA:
var sig = key.eckey.sign(data)
result.data = sig.getBytes()
let sig = ? key.eckey.sign(data).orError(SigError)
res.data = ? sig.getBytes().orError(SigError)
ok(res)
elif key.scheme == Secp256k1:
var sig = key.skkey.sign(data)
result.data = sig.getBytes()
let sig = ? key.skkey.sign(data).orError(SigError)
res.data = sig.getBytes()
ok(res)
else:
err(SigError)
proc verify*(sig: Signature, message: openarray[byte],
key: PublicKey): bool =
proc verify*(sig: Signature, message: openarray[byte], key: PublicKey): bool =
## Verify signature ``sig`` using message ``message`` and public key ``key``.
## Return ``true`` if message signature is valid.
if key.scheme == RSA:
@ -498,7 +539,7 @@ proc verify*(sig: Signature, message: openarray[byte],
result = signature.verify(message, key.eckey)
elif key.scheme == Secp256k1:
var signature: SkSignature
if signature.init(sig.data):
if signature.init(sig.data).isOk:
result = signature.verify(message, key.skkey)
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:
break
inc(offset)
ctx.init(secret.toOpenArray(offset, len(secret) - 1))
ctx.init(secret.toOpenArray(offset, secret.high))
ctx.update(seed)
var a = ctx.finish()
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(seed)
var b = ctx.finish()
@ -523,7 +564,7 @@ template makeSecret(buffer, hmactype, secret, seed: untyped) {.dirty.}=
todo = len(buffer) - j
copyMem(addr buffer[j], addr b.data[0], todo)
j += todo
ctx.init(secret.toOpenArray(offset, len(secret) - 1))
ctx.init(secret.toOpenArray(offset, secret.high))
ctx.update(a.data)
a = ctx.finish()
@ -588,33 +629,32 @@ proc mac*(secret: Secret, id: int): seq[byte] {.inline.} =
offset += secret.ivsize + secret.keysize
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.
var keypair: EcKeyPair
if scheme == Secp256r1:
keypair = EcKeyPair.random(Secp256r1)
keypair = ? EcKeyPair.random(Secp256r1).orError(KeyError)
elif scheme == Secp384r1:
keypair = EcKeyPair.random(Secp384r1)
keypair = ? EcKeyPair.random(Secp384r1).orError(KeyError)
elif scheme == Secp521r1:
keypair = EcKeyPair.random(Secp521r1)
result.seckey = PrivateKey(scheme: ECDSA)
result.pubkey = PublicKey(scheme: ECDSA)
result.seckey.eckey = keypair.seckey
result.pubkey.eckey = keypair.pubkey
keypair = ? EcKeyPair.random(Secp521r1).orError(KeyError)
ok(KeyPair(
seckey: PrivateKey(scheme: ECDSA, eckey: keypair.seckey),
pubkey: PublicKey(scheme: ECDSA, 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.
##
## Currently supported encoding strings are P-256, P-384, P-521, if encoding
## string is not supported P-521 key will be generated.
if scheme == "P-256":
result = ephemeral(Secp256r1)
ephemeral(Secp256r1)
elif scheme == "P-384":
result = ephemeral(Secp384r1)
ephemeral(Secp384r1)
elif scheme == "P-521":
result = ephemeral(Secp521r1)
ephemeral(Secp521r1)
else:
result = ephemeral(Secp521r1)
ephemeral(Secp521r1)
proc makeSecret*(remoteEPublic: PublicKey, localEPrivate: PrivateKey,
data: var openarray[byte]): int =
@ -644,7 +684,7 @@ proc getSecret*(remoteEPublic: PublicKey,
result = getSecret(remoteEPublic.eckey, localEPrivate.eckey)
proc getOrder*(remotePubkey, localNonce: openarray[byte],
localPubkey, remoteNonce: openarray[byte]): int =
localPubkey, remoteNonce: openarray[byte]): CryptoResult[int] =
## Compare values and calculate `order` parameter.
var ctx: sha256
ctx.init()
@ -655,16 +695,18 @@ proc getOrder*(remotePubkey, localNonce: openarray[byte],
ctx.update(localPubkey)
ctx.update(remoteNonce)
var digest2 = ctx.finish()
var mh1 = MultiHash.init(multiCodec("sha2-256"), digest1)
var mh2 = MultiHash.init(multiCodec("sha2-256"), digest2)
var mh1 = ? MultiHash.init(multiCodec("sha2-256"), digest1).orError(HashError)
var mh2 = ? MultiHash.init(multiCodec("sha2-256"), digest2).orError(HashError)
var res = 0;
for i in 0 ..< len(mh1.data.buffer):
result = int(mh1.data.buffer[i]) - int(mh2.data.buffer[i])
if result != 0:
if result < 0:
result = -1
elif result > 0:
result = 1
res = int(mh1.data.buffer[i]) - int(mh2.data.buffer[i])
if res != 0:
if res < 0:
res = -1
elif res > 0:
res = 1
break
ok(res)
proc selectBest*(order: int, p1, p2: string): string =
## Determines which algorithm to use from list `p1` and `p2`.
@ -741,25 +783,25 @@ proc decodeExchange*(message: seq[byte],
## 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``.
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``.
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``.
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``.
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``.
result = initProtoField(index, seckey.getBytes())
result = initProtoField(index, seckey.getBytes().tryGet())
proc initProtoField*(index: int, sig: Signature): ProtoField =
## Initialize ProtoField with Signature ``sig``.

View File

@ -14,6 +14,8 @@
## BearSSL library <https://bearssl.org/>
## Copyright(C) 2018 Thomas Pornin <pornin@bolet.org>.
{.push raises: [Defect].}
import bearssl
import nimcrypto/utils
import minasn1
@ -58,11 +60,14 @@ type
EcPKI* = EcPrivateKey | EcPublicKey | EcSignature
EcError* = object of CatchableError
EcKeyIncorrectError* = object of EcError
EcRngError* = object of EcError
EcPublicKeyError* = object of EcError
EcSignatureError* = object of EcError
EcError* = enum
EcRngError,
EcKeyGenError,
EcPublicKeyError,
EcKeyIncorrectError,
EcSignatureError
EcResult*[T] = Result[T, EcError]
const
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.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
## algorithm.
##
@ -232,37 +237,46 @@ proc random*(t: typedesc[EcPrivateKey], kind: EcCurveKind): EcPrivateKey =
var seeder = brPrngSeederSystem(nil)
brHmacDrbgInit(addr rng, addr sha256Vtable, nil, 0)
if seeder(addr rng.vtable) == 0:
raise newException(ValueError, "Could not seed RNG")
return err(EcRngError)
var ecimp = brEcGetDefault()
result = new EcPrivateKey
result.buffer = newSeq[byte](BR_EC_KBUF_PRIV_MAX_SIZE)
var res = new EcPrivateKey
res.buffer = newSeq[byte](BR_EC_KBUF_PRIV_MAX_SIZE)
if brEcKeygen(addr rng.vtable, ecimp,
addr result.key, addr result.buffer[0],
addr res.key, addr res.buffer[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``.
doAssert(not isNil(seckey))
if isNil(seckey):
return err(EcKeyIncorrectError)
var ecimp = brEcGetDefault()
if seckey.key.curve in EcSupportedCurvesCint:
var length = getPublicKeyLength(cast[EcCurveKind](seckey.key.curve))
result = new EcPublicKey
result.buffer = newSeq[byte](length)
if brEcComputePublicKey(ecimp, addr result.key,
addr result.buffer[0], unsafeAddr seckey.key) == 0:
raise newException(EcKeyIncorrectError, "Could not calculate public key")
var res = new EcPublicKey
res.buffer = newSeq[byte](length)
if brEcComputePublicKey(ecimp, addr res.key,
addr res.buffer[0], unsafeAddr seckey.key) == 0:
err(EcKeyIncorrectError)
else:
ok(res)
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
## HMAC-SHA256-DRBG algorithm.
##
## ``kind`` elliptic curve kind of your choice (secp256r1, secp384r1 or
## secp521r1).
result.seckey = EcPrivateKey.random(kind)
result.pubkey = result.seckey.getKey()
let
seckey = ? EcPrivateKey.random(kind)
pubkey = ? seckey.getKey()
key = EcKeyPair(seckey: seckey, pubkey: pubkey)
ok(key)
proc `$`*(seckey: EcPrivateKey): string =
## Return string representation of EC private key.
@ -303,29 +317,37 @@ proc `$`*(sig: EcSignature): string =
else:
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
## to ``data``.
##
## Returns number of bytes (octets) needed to store EC private key, 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:
result = getPrivateKeyLength(cast[EcCurveKind](seckey.key.curve))
if len(data) >= result:
copyMem(addr data[0], unsafeAddr seckey.buffer[0], result)
let klen = getPrivateKeyLength(cast[EcCurveKind](seckey.key.curve))
if len(data) >= klen:
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
## section 4.3.6 of ANSI X9.62.
##
## Returns number of bytes (octets) needed to store EC public key, 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:
result = getPublicKeyLength(cast[EcCurveKind](pubkey.key.curve))
if len(data) >= result:
copyMem(addr data[0], unsafeAddr pubkey.buffer[0], result)
let klen = getPublicKeyLength(cast[EcCurveKind](pubkey.key.curve))
if len(data) >= klen:
copyMem(addr data[0], unsafeAddr pubkey.buffer[0], klen)
ok(klen)
else:
err(EcKeyIncorrectError)
proc toRawBytes*(sig: EcSignature, data: var openarray[byte]): int =
## 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:
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
## to ``data``.
##
## Procedure returns number of bytes (octets) needed to store EC private key,
## 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:
var offset, length: int
var pubkey = seckey.getKey()
var pubkey = ? seckey.getKey()
var b = Asn1Buffer.init()
var p = Asn1Composite.init(Asn1Tag.Sequence)
var c0 = Asn1Composite.init(0)
@ -374,17 +397,23 @@ proc toBytes*(seckey: EcPrivateKey, data: var openarray[byte]): int =
p.finish()
b.write(p)
b.finish()
result = len(b)
if len(data) >= result:
copyMem(addr data[0], addr b.buffer[0], result)
var blen = len(b)
if len(data) >= blen:
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
## to ``data``.
##
## Procedure returns number of bytes (octets) needed to store EC public key,
## 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:
var b = Asn1Buffer.init()
var p = Asn1Composite.init(Asn1Tag.Sequence)
@ -405,80 +434,97 @@ proc toBytes*(pubkey: EcPublicKey, data: var openarray[byte]): int =
p.finish()
b.write(p)
b.finish()
result = len(b)
if len(data) >= result:
copyMem(addr data[0], addr b.buffer[0], result)
var blen = len(b)
if len(data) >= blen:
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
## to ``data``.
##
## Procedure returns number of bytes (octets) needed to store EC signature,
## or `0` if signature is not in supported curve.
doAssert(not isNil(sig))
result = len(sig.buffer)
if len(data) >= result:
copyMem(addr data[0], unsafeAddr sig.buffer[0], result)
if isNil(sig):
return err(EcSignatureError)
let slen = len(sig.buffer)
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.
doAssert(not isNil(seckey))
if isNil(seckey):
return err(EcKeyIncorrectError)
if seckey.key.curve in EcSupportedCurvesCint:
result = newSeq[byte]()
let length = seckey.toBytes(result)
result.setLen(length)
discard seckey.toBytes(result)
var res = newSeq[byte]()
let length = ? seckey.toBytes(res)
res.setLen(length)
discard ? seckey.toBytes(res)
ok(res)
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.
doAssert(not isNil(pubkey))
if isNil(pubkey):
return err(EcKeyIncorrectError)
if pubkey.key.curve in EcSupportedCurvesCint:
result = newSeq[byte]()
let length = pubkey.toBytes(result)
result.setLen(length)
discard pubkey.toBytes(result)
var res = newSeq[byte]()
let length = ? pubkey.toBytes(res)
res.setLen(length)
discard ? pubkey.toBytes(res)
ok(res)
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.
doAssert(not isNil(sig))
result = newSeq[byte]()
let length = sig.toBytes(result)
result.setLen(length)
discard sig.toBytes(result)
if isNil(sig):
return err(EcSignatureError)
var res = newSeq[byte]()
let length = ? sig.toBytes(res)
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.
doAssert(not isNil(seckey))
if isNil(seckey):
return err(EcKeyIncorrectError)
if seckey.key.curve in EcSupportedCurvesCint:
result = newSeq[byte]()
let length = seckey.toRawBytes(result)
result.setLen(length)
discard seckey.toRawBytes(result)
var res = newSeq[byte]()
let length = ? seckey.toRawBytes(res)
res.setLen(length)
discard ? seckey.toRawBytes(res)
ok(res)
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.
doAssert(not isNil(pubkey))
if isNil(pubkey):
return err(EcKeyIncorrectError)
if pubkey.key.curve in EcSupportedCurvesCint:
result = newSeq[byte]()
let length = pubkey.toRawBytes(result)
result.setLen(length)
discard pubkey.toRawBytes(result)
var res = newSeq[byte]()
let length = ? pubkey.toRawBytes(res)
res.setLen(length)
discard ? pubkey.toRawBytes(res)
ok(res)
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.
doAssert(not isNil(sig))
result = newSeq[byte]()
let length = sig.toBytes(result)
result.setLen(length)
discard sig.toBytes(result)
if isNil(sig):
return err(EcSignatureError)
var res = newSeq[byte]()
let length = ? sig.toBytes(res)
res.setLen(length)
discard ? sig.toBytes(res)
ok(res)
proc `==`*(pubkey1, pubkey2: EcPublicKey): bool =
## 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``.
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
## return constructed object.
let res = result.init(data)
var key: EcPrivateKey
let res = key.init(data)
if res.isErr:
raise newException(EcKeyIncorrectError,
"Incorrect private key (" & $res.error & ")")
err(EcKeyIncorrectError)
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
## return constructed object.
let res = result.init(data)
var key: EcPublicKey
let res = key.init(data)
if res.isErr:
raise newException(EcKeyIncorrectError,
"Incorrect public key (" & $res.error & ")")
err(EcKeyIncorrectError)
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
## return constructed object.
let res = result.init(data)
var sig: EcSignature
let res = sig.init(data)
if res.isErr:
raise newException(EcKeyIncorrectError,
"Incorrect signature (" & $res.error & ")")
err(EcSignatureError)
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
## 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 =
## 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.
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
## return constructed object.
if not result.initRaw(data):
raise newException(EcKeyIncorrectError, "Incorrect private key")
var res: EcPrivateKey
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
## return constructed object.
if not result.initRaw(data):
raise newException(EcKeyIncorrectError, "Incorrect public key")
var res: EcPublicKey
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
## return constructed object.
if not result.initRaw(data):
raise newException(EcKeyIncorrectError, "Incorrect signature")
var res: EcSignature
if not res.initRaw(data):
err(EcSignatureError)
else:
ok(res)
proc initRaw*[T: EcPKI](t: typedesc[T], data: string): T {.inline.} =
## 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)
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``.
doAssert(not isNil(seckey))
if isNil(seckey):
return err(EcKeyIncorrectError)
var hc: BrHashCompatContext
var hash: array[32, byte]
var impl = brEcGetDefault()
if seckey.key.curve in EcSupportedCurvesCint:
result = new EcSignature
result.buffer = newSeq[byte](256)
var sig = new EcSignature
sig.buffer = newSeq[byte](256)
var kv = addr sha256Vtable
kv.init(addr hc.vtable)
if len(message) > 0:
@ -875,15 +940,16 @@ proc sign*[T: byte|char](seckey: EcPrivateKey,
kv.update(addr hc.vtable, nil, 0)
kv.output(addr hc.vtable, addr hash[0])
let res = brEcdsaSignAsn1(impl, kv, addr hash[0], addr seckey.key,
addr result.buffer[0])
addr sig.buffer[0])
# Clear context with initial value
kv.init(addr hc.vtable)
if res != 0:
result.buffer.setLen(res)
sig.buffer.setLen(res)
ok(sig)
else:
raise newException(EcSignatureError, "Could not make signature")
err(EcSignatureError)
else:
raise newException(EcKeyIncorrectError, "Incorrect private key")
err(EcKeyIncorrectError)
proc verify*[T: byte|char](sig: EcSignature, message: openarray[T],
pubkey: EcPublicKey): bool {.inline.} =

View File

@ -10,8 +10,13 @@
## This module implements ED25519.
## This code is a port of the public domain, "ref10" implementation of ed25519
## from SUPERCOP.
{.push raises: Defect.}
import constants
import nimcrypto/[hash, sha2, sysrand, utils]
import stew/results
export results
# This workaround needed because of some bugs in Nim Static[T].
export hash, sha2
@ -38,9 +43,9 @@ type
seckey*: EdPrivateKey
pubkey*: EdPublicKey
EdError* = object of CatchableError
EdRngError* = object of EdError
EdIncorrectError* = object of EdError
EdError* = enum
EdRngError,
EdIncorrectError
proc `-`(x: uint32): uint32 {.inline.} =
result = (0xFFFF_FFFF'u32 - x) + 1'u32
@ -1632,40 +1637,47 @@ proc checkScalar*(scalar: openarray[byte]): uint32 =
for u in scalar:
z = z or u
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]))
else:
c = -1
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.
var
point: GeP3
pk: array[EdPublicKeySize, byte]
if randomBytes(result.data.toOpenArray(0, 31)) != 32:
raise newException(EdRngError, "Could not generate random data")
var hh = sha512.digest(result.data.toOpenArray(0, 31))
hh.data[0] = hh.data[0] and 0xF8'u8
hh.data[31] = hh.data[31] and 0x3F'u8
hh.data[31] = hh.data[31] or 0x40'u8
geScalarMultBase(point, hh.data)
geP3ToBytes(pk, point)
copyMem(addr result.data[32], addr pk[0], 32)
res: EdPrivateKey
if randomBytes(res.data.toOpenArray(0, 31)) != 32:
err(EdRngError)
else:
var hh = sha512.digest(res.data.toOpenArray(0, 31))
hh.data[0] = hh.data[0] and 0xF8'u8
hh.data[31] = hh.data[31] and 0x3F'u8
hh.data[31] = hh.data[31] or 0x40'u8
geScalarMultBase(point, hh.data)
geP3ToBytes(pk, point)
copyMem(addr res.data[32], addr pk[0], 32)
ok(res)
proc random*(t: typedesc[EdKeyPair]): EdKeyPair =
proc random*(t: typedesc[EdKeyPair]): Result[EdKeyPair, EdError] =
## Generate new random ED25519 private and public keypair using OS specific
## CSPRNG.
var point: GeP3
if randomBytes(result.seckey.data.toOpenArray(0, 31)) != 32:
raise newException(EdRngError, "Could not generate random data")
var hh = sha512.digest(result.seckey.data.toOpenArray(0, 31))
hh.data[0] = hh.data[0] and 0xF8'u8
hh.data[31] = hh.data[31] and 0x3F'u8
hh.data[31] = hh.data[31] or 0x40'u8
geScalarMultBase(point, hh.data)
geP3ToBytes(result.pubkey.data, point)
copyMem(addr result.seckey.data[32], addr result.pubkey.data[0], 32)
var
point: GeP3
res: EdKeyPair
if randomBytes(res.seckey.data.toOpenArray(0, 31)) != 32:
err(EdRngError)
else:
var hh = sha512.digest(res.seckey.data.toOpenArray(0, 31))
hh.data[0] = hh.data[0] and 0xF8'u8
hh.data[31] = hh.data[31] and 0x3F'u8
hh.data[31] = hh.data[31] or 0x40'u8
geScalarMultBase(point, hh.data)
geP3ToBytes(res.pubkey.data, point)
copyMem(addr res.seckey.data[32], addr res.pubkey.data[0], 32)
ok(res)
proc getKey*(key: EdPrivateKey): EdPublicKey =
## Calculate and return ED25519 public key from private key ``key``.
@ -1766,57 +1778,84 @@ proc init*(key: var EdPrivateKey, data: string): bool =
## representation ``data``.
##
## 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 =
## Initialize ED25519 `public key` ``key`` from hexadecimal string
## representation ``data``.
##
## 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 =
## Initialize ED25519 `signature` ``sig`` from hexadecimal string
## representation ``data``.
##
## 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``
## and return constructed object.
if not init(result, data):
raise newException(EdIncorrectError, "Incorrect binary form")
var res: t
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``
## and return constructed object.
if not init(result, data):
raise newException(EdIncorrectError, "Incorrect binary form")
var res: t
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``
## and return constructed object.
if not init(result, data):
raise newException(EdIncorrectError, "Incorrect binary form")
var res: t
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
## ``data`` and return constructed object.
if not init(result, data):
raise newException(EdIncorrectError, "Incorrect binary form")
var res: t
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
## ``data`` and return constructed object.
if not init(result, data):
raise newException(EdIncorrectError, "Incorrect binary form")
var res: t
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
## ``data`` and return constructed object.
if not init(result, data):
raise newException(EdIncorrectError, "Incorrect binary form")
var res: t
if not init(res, data):
err(EdIncorrectError)
else:
ok(res)
proc clear*(key: var EdPrivateKey) =
## Wipe and clear memory of ED25519 `private key`.

View File

@ -106,10 +106,10 @@ const
## Encoded ``NULL`` value.
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 =
toOpenArray(ac.buffer, ac.offset, len(ac.buffer) - 1)
toOpenArray(ac.buffer, ac.offset, ac.buffer.high)
template toOpenArray*(af: Asn1Field): untyped =
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 += oidlen
if len(dest) >= result:
let last = len(dest) - 1
let last = dest.high
var offset = 1
dest[0] = Asn1Tag.Oid.code()
offset += asn1EncodeLength(dest.toOpenArray(offset, last), oidlen)

View File

@ -12,6 +12,9 @@
## This module uses unmodified parts of code from
## BearSSL library <https://bearssl.org/>
## Copyright(C) 2018 Thomas Pornin <pornin@bolet.org>.
{.push raises: Defect.}
import nimcrypto/utils
import bearssl
import minasn1
@ -72,11 +75,13 @@ type
RsaPKI* = RsaPrivateKey | RsaPublicKey | RsaSignature
RsaKP* = RsaPrivateKey | RsaKeyPair
RsaError* = object of CatchableError
RsaRngError* = object of RsaError
RsaGenError* = object of RsaError
RsaKeyIncorrectError* = object of RsaError
RsaSignatureError* = object of RsaError
RsaError* = enum
RsaRngError,
RsaGenError,
RsaKeyIncorrectError,
RsaSignatureError
RsaResult*[T] = Result[T, RsaError]
template getStart(bs, os, ls: untyped): untyped =
let p = cast[uint](os)
@ -108,7 +113,7 @@ template trimZeroes(b: seq[byte], pt, ptlen: untyped) =
ptlen -= 1
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
## algorithm.
##
@ -121,7 +126,8 @@ proc random*[T: RsaKP](t: typedesc[T], bits = DefaultKeySize,
var seeder = brPrngSeederSystem(nil)
brHmacDrbgInit(addr rng, addr sha256Vtable, nil, 0)
if seeder(addr rng.vtable) == 0:
raise newException(RsaRngError, "Could not seed RNG")
return err(RsaRngError)
keygen = brRsaKeygenGetDefault()
let length = brRsaPrivateKeyBufferSize(bits) +
@ -131,34 +137,38 @@ proc random*[T: RsaKP](t: typedesc[T], bits = DefaultKeySize,
let pko = brRsaPrivateKeyBufferSize(bits)
let eko = pko + brRsaPublicKeyBufferSize(bits)
when T is RsaKeyPair:
result = new RsaKeyPair
else:
result = new RsaPrivateKey
var res: T
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,
addr result.seck, addr result.buffer[sko],
addr result.pubk, addr result.buffer[pko],
addr res.seck, addr res.buffer[sko],
addr res.pubk, addr res.buffer[pko],
cuint(bits), pubexp) == 0:
raise newException(RsaGenError, "Could not create private key")
return err(RsaGenError)
let compute = brRsaComputePrivexpGetDefault()
let res = compute(addr result.buffer[eko], addr result.seck, pubexp)
if res == 0:
raise newException(RsaGenError, "Could not create private key")
let computed = compute(addr res.buffer[eko], addr res.seck, pubexp)
if computed == 0:
return err(RsaGenError)
result.pexp = cast[ptr cuchar](addr result.buffer[eko])
result.pexplen = res
res.pexp = cast[ptr cuchar](addr res.buffer[eko])
res.pexplen = computed
trimZeroes(result.buffer, result.seck.p, result.seck.plen)
trimZeroes(result.buffer, result.seck.q, result.seck.qlen)
trimZeroes(result.buffer, result.seck.dp, result.seck.dplen)
trimZeroes(result.buffer, result.seck.dq, result.seck.dqlen)
trimZeroes(result.buffer, result.seck.iq, result.seck.iqlen)
trimZeroes(result.buffer, result.pubk.n, result.pubk.nlen)
trimZeroes(result.buffer, result.pubk.e, result.pubk.elen)
trimZeroes(result.buffer, result.pexp, result.pexplen)
trimZeroes(res.buffer, res.seck.p, res.seck.plen)
trimZeroes(res.buffer, res.seck.q, res.seck.qlen)
trimZeroes(res.buffer, res.seck.dp, res.seck.dplen)
trimZeroes(res.buffer, res.seck.dq, res.seck.dqlen)
trimZeroes(res.buffer, res.seck.iq, res.seck.iqlen)
trimZeroes(res.buffer, res.pubk.n, res.pubk.nlen)
trimZeroes(res.buffer, res.pubk.e, res.pubk.elen)
trimZeroes(res.buffer, res.pexp, res.pexplen)
ok(res)
proc copy*[T: RsaPKI](key: T): T =
## 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)
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
## to ``data``.
##
## Procedure returns number of bytes (octets) needed to store RSA private key,
## or `0` if private key is is incorrect.
doAssert(not isNil(key))
if len(key.buffer) > 0:
if isNil(key):
err(RsaKeyIncorrectError)
elif len(key.buffer) > 0:
var b = Asn1Buffer.init()
var p = Asn1Composite.init(Asn1Tag.Sequence)
p.write(0'u64)
@ -304,18 +315,22 @@ proc toBytes*(key: RsaPrivateKey, data: var openarray[byte]): int =
p.finish()
b.write(p)
b.finish()
result = len(b)
if len(data) >= result:
copyMem(addr data[0], addr b.buffer[0], result)
var blen = len(b)
if len(data) >= blen:
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
## to ``data``.
##
## Procedure returns number of bytes (octets) needed to store RSA public key,
## or `0` if public key is incorrect.
doAssert(not isNil(key))
if len(key.buffer) > 0:
if isNil(key):
err(RsaKeyIncorrectError)
elif len(key.buffer) > 0:
var b = Asn1Buffer.init()
var p = 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()
b.write(p)
b.finish()
result = len(b)
if len(data) >= result:
copyMem(addr data[0], addr b.buffer[0], result)
var blen = len(b)
if len(data) >= blen:
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
## to ``data``.
##
## Procedure returns number of bytes (octets) needed to store RSA public key,
## or `0` if public key is incorrect.
doAssert(not isNil(sig))
result = len(sig.buffer)
if len(data) >= result:
copyMem(addr data[0], addr sig.buffer[0], result)
if isNil(sig):
err(RsaSignatureError)
else:
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
## return it.
doAssert(not isNil(key))
result = newSeq[byte](4096)
let length = key.toBytes(result)
if isNil(key):
return err(RsaKeyIncorrectError)
var res = newSeq[byte](4096)
let length = ? key.toBytes(res)
if length > 0:
result.setLen(length)
res.setLen(length)
ok(res)
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
## return it.
doAssert(not isNil(key))
result = newSeq[byte](4096)
let length = key.toBytes(result)
if isNil(key):
return err(RsaKeyIncorrectError)
var res = newSeq[byte](4096)
let length = ? key.toBytes(res)
if length > 0:
result.setLen(length)
res.setLen(length)
ok(res)
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.
doAssert(not isNil(sig))
result = newSeq[byte](4096)
let length = sig.toBytes(result)
if isNil(sig):
return err(RsaSignatureError)
var res = newSeq[byte](4096)
let length = ? sig.toBytes(res)
if length > 0:
result.setLen(length)
res.setLen(length)
ok(res)
else:
raise newException(RsaSignatureError, "Incorrect signature")
err(RsaSignatureError)
proc init*(key: var RsaPrivateKey, data: openarray[byte]): Result[void, Asn1Error] =
## 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]``.
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``
## and return constructed object.
let res = result.init(data)
if res.isErr:
raise newException(RsaKeyIncorrectError,
"Incorrect private key (" & $res.error & ")")
var res: RsaPrivateKey
if res.init(data).isErr:
err(RsaKeyIncorrectError)
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``
## and return constructed object.
let res = result.init(data)
if res.isErr:
raise newException(RsaKeyIncorrectError,
"Incorrect public key (" & $res.error & ")")
var res: RsaPublicKey
if res.init(data).isErr:
err(RsaKeyIncorrectError)
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
## return constructed object.
let res = result.init(data)
if res.isErr:
raise newException(RsaKeyIncorrectError,
"Incorrect signature (" & $res.error & ")")
var res: RsaSignature
if res.init(data).isErr:
err(RsaSignatureError)
else:
ok(res)
proc init*[T: RsaPKI](t: typedesc[T], data: string): T {.inline.} =
## Initialize RSA `private key`, `public key` or `signature` from hexadecimal
@ -714,15 +744,17 @@ proc `==`*(a, b: RsaPublicKey): bool =
result = r1 and r2
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
## key ``key``.
doAssert(not isNil(key))
if isNil(key):
return err(RsaKeyIncorrectError)
var hc: BrHashCompatContext
var hash: array[32, byte]
let impl = BrRsaPkcs1SignGetDefault()
result = new RsaSignature
result.buffer = newSeq[byte]((key.seck.nBitlen + 7) shr 3)
var res = new RsaSignature
res.buffer = newSeq[byte]((key.seck.nBitlen + 7) shr 3)
var kv = addr sha256Vtable
kv.init(addr hc.vtable)
if len(message) > 0:
@ -731,11 +763,13 @@ proc sign*[T: byte|char](key: RsaPrivateKey,
kv.update(addr hc.vtable, nil, 0)
kv.output(addr hc.vtable, addr hash[0])
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),
addr key.seck, cast[ptr cuchar](addr result.buffer[0]))
if res == 0:
raise newException(RsaSignatureError, "Signature generation error")
addr key.seck, cast[ptr cuchar](addr res.buffer[0]))
if implRes == 0:
err(RsaSignatureError)
else:
ok(res)
proc verify*[T: byte|char](sig: RsaSignature, message: openarray[T],
pubkey: RsaPublicKey): bool {.inline.} =

View File

@ -6,8 +6,15 @@
## at your option.
## This file may not be copied, modified, or distributed except according to
## 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
import stew/results
export results
export secp256k1
const
SkRawPrivateKeySize* = 256 div 8
@ -18,169 +25,125 @@ const
## Size of public key in octets (bytes)
type
SkPublicKey* = distinct s.SkPublicKey
SkPrivateKey* = distinct s.SkSecretKey
SkKeyPair* = distinct s.SkKeyPair
SkSignature* = distinct s.SkSignature
SkPrivateKey* = SkSecretKey
Secp256k1Error* = object of CatchableError
## Exceptions generated by `libsecp256k1`
template pubkey*(v: SkKeyPair): SkPublicKey = SkPublicKey(SkKeyPair(v).pubkey)
template seckey*(v: SkKeyPair): SkPrivateKey = SkPrivateKey(SkKeyPair(v).seckey)
template toException(v: cstring): (ref Secp256k1Error) =
(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].} =
proc init*(key: var SkPrivateKey, data: openarray[byte]): SkResult[void] =
## Initialize Secp256k1 `private key` ``key`` from raw binary
## representation ``data``.
##
## Procedure returns ``true`` on success.
if (let v = SkSecretKey.fromRaw(data); v.isOk):
key = SkPrivateKey(v[])
return true
key = ? SkSecretKey.fromRaw(data)
ok()
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
## representation ``data``.
##
## Procedure returns ``true`` on success.
try:
key = SkPrivateKey(SkSecretKey.fromHex(data).tryGet())
return true
except Secp256k1Error:
discard
key = ? SkSecretKey.fromHex(data)
ok()
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
## representation ``data``.
##
## Procedure returns ``true`` on success.
try:
key = SkPublicKey(s.SkPublicKey.fromRaw(data).tryGet())
return true
except Secp256k1Error:
discard
key = ? SkPublicKey.fromRaw(data)
ok()
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
## representation ``data``.
##
## Procedure returns ``true`` on success.
try:
key = SkPublicKey(s.SkPublicKey.fromHex(data).tryGet())
return true
except Secp256k1Error:
discard
key = ? SkPublicKey.fromHex(data)
ok()
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
## representation ``data``.
##
## Procedure returns ``true`` on success.
try:
sig = SkSignature(s.SkSignature.fromDer(data).tryGet())
return true
except Secp256k1Error:
discard
sig = ? SkSignature.fromDer(data)
ok()
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
## representation ``data``.
##
## Procedure returns ``true`` on success.
# TODO DER vs raw here is fishy
var buffer: seq[byte]
try:
buffer = hexToSeqByte(data)
except ValueError:
return false
result = init(sig, buffer)
return err("Hex to bytes failed")
init(sig, buffer)
proc init*(t: typedesc[SkPrivateKey],
data: openarray[byte]): SkPrivateKey {.raises: [Defect, Secp256k1Error].} =
proc init*(t: typedesc[SkPrivateKey], data: openarray[byte]): SkResult[SkPrivateKey] =
## Initialize Secp256k1 `private key` from raw binary
## representation ``data``.
##
## Procedure returns `private key` on success.
SkPrivateKey(s.SkSecretKey.fromRaw(data).tryGet())
SkSecretKey.fromRaw(data)
proc init*(t: typedesc[SkPrivateKey],
data: string): SkPrivateKey {.raises: [Defect, Secp256k1Error].} =
proc init*(t: typedesc[SkPrivateKey], data: string): SkResult[SkPrivateKey] =
## Initialize Secp256k1 `private key` from hexadecimal string
## representation ``data``.
##
## Procedure returns `private key` on success.
s.SkSecretKey.fromHex(data).tryGet()
SkSecretKey.fromHex(data)
proc init*(t: typedesc[SkPublicKey],
data: openarray[byte]): SkPublicKey {.raises: [Defect, Secp256k1Error].} =
proc init*(t: typedesc[SkPublicKey], data: openarray[byte]): SkResult[SkPublicKey] =
## Initialize Secp256k1 `public key` from raw binary
## representation ``data``.
##
## Procedure returns `public key` on success.
if not init(result, data):
raise newException(Secp256k1Error, "Incorrect binary form")
var key: SkPublicKey
key.init(data) and ok(key)
proc init*(t: typedesc[SkPublicKey],
data: string): SkPublicKey {.raises: [Defect, Secp256k1Error].} =
proc init*(t: typedesc[SkPublicKey], data: string): SkResult[SkPublicKey] =
## Initialize Secp256k1 `public key` from hexadecimal string
## representation ``data``.
##
## Procedure returns `public key` on success.
if not init(result, data):
raise newException(Secp256k1Error, "Incorrect binary form")
var key: SkPublicKey
key.init(data) and ok(key)
proc init*(t: typedesc[SkSignature],
data: openarray[byte]): SkSignature {.raises: [Defect, Secp256k1Error].} =
proc init*(t: typedesc[SkSignature], data: openarray[byte]): SkResult[SkSignature] =
## Initialize Secp256k1 `signature` from raw binary
## representation ``data``.
##
## Procedure returns `signature` on success.
if not init(result, data):
raise newException(Secp256k1Error, "Incorrect binary form")
var sig: SkSignature
sig.init(data) and ok(sig)
proc init*(t: typedesc[SkSignature],
data: string): SkSignature {.raises: [Defect, Secp256k1Error].} =
proc init*(t: typedesc[SkSignature], data: string): SkResult[SkSignature] =
## Initialize Secp256k1 `signature` from hexadecimal string
## representation ``data``.
##
## Procedure returns `signature` on success.
if not init(result, data):
raise newException(Secp256k1Error, "Incorrect binary form")
var sig: SkSignature
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``.
SkPublicKey(s.SkSecretKey(key).toPublicKey().tryGet())
key.toPublicKey()
proc random*(t: typedesc[SkPrivateKey]): SkPrivateKey =
## 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 =
proc toBytes*(key: SkPrivateKey, data: var openarray[byte]): SkResult[int] =
## Serialize Secp256k1 `private key` ``key`` to raw binary form and store it
## to ``data``.
##
## Procedure returns number of bytes (octets) needed to store
## Secp256k1 private key.
result = SkRawPrivateKeySize
if len(data) >= SkRawPrivateKeySize:
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
## to ``data``.
##
## Procedure returns number of bytes (octets) needed to store
## Secp256k1 public key.
result = 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 =
## 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
## Secp256k1 signature.
s.SkSignature(sig).toDer(data)
sig.toDer(data)
proc getBytes*(key: SkPrivateKey): seq[byte] {.inline.} =
## Serialize Secp256k1 `private key` and return it.
result = @(s.SkSecretKey(key).toRaw())
result = @(SkSecretKey(key).toRaw())
proc getBytes*(key: SkPublicKey): seq[byte] {.inline.} =
## Serialize Secp256k1 `public key` and return it.
result = @(s.SkPublicKey(key).toRawCompressed())
result = @(key.toRawCompressed())
proc getBytes*(sig: SkSignature): seq[byte] {.inline.} =
## Serialize Secp256k1 `signature` and return it.
@ -204,49 +167,12 @@ proc getBytes*(sig: SkSignature): seq[byte] {.inline.} =
let length = toBytes(sig, result)
result.setLen(length)
proc `==`*(ska, skb: SkPrivateKey): bool =
## 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 =
proc sign*[T: byte|char](key: SkPrivateKey, msg: openarray[T]): SkResult[SkSignature] =
## Sign message `msg` using private key `key` and return signature object.
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],
key: SkPublicKey): bool =
let h = sha256.digest(msg)
verify(s.SkSignature(sig), h, s.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.}
verify(SkSignature(sig), h, SkPublicKey(key))

View File

@ -140,7 +140,7 @@ proc p2pStB(s: string, vb: var VBuffer): bool =
try:
var data = Base58.decode(s)
var mh: MultiHash
if MultiHash.decode(data, mh) >= 0:
if MultiHash.decode(data, mh).isOk:
vb.writeSeq(data)
result = true
except:
@ -151,7 +151,7 @@ proc p2pBtS(vb: var VBuffer, s: var string): bool =
var address = newSeq[byte]()
if vb.readSeq(address) > 0:
var mh: MultiHash
if MultiHash.decode(address, mh) >= 0:
if MultiHash.decode(address, mh).isOk:
s = Base58.encode(address)
result = true
@ -160,7 +160,7 @@ proc p2pVB(vb: var VBuffer): bool =
var address = newSeq[byte]()
if vb.readSeq(address) > 0:
var mh: MultiHash
if MultiHash.decode(address, mh) >= 0:
if MultiHash.decode(address, mh).isOk:
result = true
proc onionStB(s: string, vb: var VBuffer): bool =
@ -426,12 +426,12 @@ const
proc trimRight(s: string, ch: char): string =
## Consume trailing characters ``ch`` from string ``s`` and return result.
var m = 0
for i in countdown(len(s) - 1, 0):
for i in countdown(s.high, 0):
if s[i] == ch:
inc(m)
else:
break
result = s[0..(len(s) - 1 - m)]
result = s[0..(s.high - m)]
proc shcopy*(m1: var MultiAddress, m2: MultiAddress) =
shallowCopy(m1.data.buffer, m2.data.buffer)

View File

@ -392,7 +392,7 @@ proc encode*(mbtype: typedesc[MultiBase], encoding: string,
if isNil(mb.encr) or isNil(mb.encl):
return MultibaseStatus.NotSupported
if len(outbytes) > 1:
result = mb.encr(inbytes, outbytes.toOpenArray(1, len(outbytes) - 1),
result = mb.encr(inbytes, outbytes.toOpenArray(1, outbytes.high),
outlen)
if result == MultiBaseStatus.Overrun:
outlen += 1
@ -452,7 +452,7 @@ proc encode*(mbtype: typedesc[MultiBase], encoding: string,
if length > 0:
buffer = newString(mb.encl(length) + 1)
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:
raise newException(MultiBaseError, "Encoding error [" & $res & "]")
buffer.setLen(outlen + 1)

View File

@ -8,8 +8,13 @@
## those terms.
## This module implements MultiCodec.
{.push raises: [Defect].}
import tables, hashes
import varint, vbuffer
import stew/results
export results
{.deadCodeElim: on.}
@ -230,7 +235,8 @@ const MultiCodecList = [
type
MultiCodec* = distinct int
MultiCodecError* = object of CatchableError
MultiCodecError* = enum
MultiCodecNotSupported
const
InvalidMultiCodec* = MultiCodec(-1)
@ -251,37 +257,32 @@ const
proc multiCodec*(name: string): MultiCodec {.compileTime.} =
## Generate MultiCodec from string ``name`` at compile time.
var code = NameCodecs.getOrDefault(name, -1)
if code == -1:
raise newException(MultiCodecError,
"MultiCodec `" & name & "` not supported!")
result = MultiCodec(code)
let code = NameCodecs.getOrDefault(name, -1)
doAssert(code != -1)
MultiCodec(code)
proc multiCodec*(code: int): MultiCodec {.compileTime.} =
## Generate MultiCodec from integer ``code`` at compile time.
var name = CodeCodecs.getOrDefault(code, "")
if name == "":
raise newException(MultiCodecError,
"MultiCodec with code " & $code & " not supported!")
result = MultiCodec(code)
let name = CodeCodecs.getOrDefault(code, "")
doAssert(name != "")
MultiCodec(code)
proc `$`*(mc: MultiCodec): string =
## Returns string representation of MultiCodec ``mc``.
result = CodeCodecs.getOrDefault(int(mc), "")
if result == "":
raise newException(MultiCodecError,
"MultiCodec with code " & $int(mc) & " not supported!")
let name = CodeCodecs.getOrDefault(int(mc), "")
doAssert(name != "")
name
proc `==`*(mc: MultiCodec, name: string): bool {.inline.} =
## Compares MultiCodec ``mc`` with string ``name``.
var mcname = CodeCodecs.getOrDefault(int(mc), "")
let mcname = CodeCodecs.getOrDefault(int(mc), "")
if mcname == "":
return false
result = (mcname == name)
proc `==`*(mc: MultiCodec, code: int): bool {.inline.} =
## Compares MultiCodec ``mc`` with integer ``code``.
result = (int(mc) == code)
(int(mc) == code)
proc `==`*(a, b: MultiCodec): bool =
## Returns ``true`` if MultiCodecs ``a`` and ``b`` are equal.
@ -293,13 +294,13 @@ proc `!=`*(a, b: MultiCodec): bool =
proc hash*(m: MultiCodec): Hash {.inline.} =
## Hash procedure for tables.
result = hash(int(m))
hash(int(m))
proc codec*(mt: typedesc[MultiCodec], name: string): MultiCodec {.inline.} =
## Return MultiCodec from string representation ``name``.
## If ``name`` is not valid multicodec name, then ``InvalidMultiCodec`` will
## be returned.
result = MultiCodec(NameCodecs.getOrDefault(name, -1))
MultiCodec(NameCodecs.getOrDefault(name, -1))
proc codec*(mt: typedesc[MultiCodec], code: int): MultiCodec {.inline.} =
## Return MultiCodec from integer representation ``code``.
@ -307,9 +308,9 @@ proc codec*(mt: typedesc[MultiCodec], code: int): MultiCodec {.inline.} =
## be returned.
let res = CodeCodecs.getOrDefault(code, "")
if res == "":
result = InvalidMultiCodec
InvalidMultiCodec
else:
result = MultiCodec(code)
MultiCodec(code)
proc write*(vb: var VBuffer, mc: MultiCodec) {.inline.} =
## Write MultiCodec to buffer ``vb``.

View File

@ -20,19 +20,29 @@
## Hashes which are not yet supported
## 1. SKEIN
## 2. MURMUR
{.push raises: [Defect].}
import tables
import nimcrypto/[sha, sha2, keccak, blake2, hash, utils]
import varint, vbuffer, multicodec, multibase
import stew/base58
import stew/results
export results
# This is workaround for Nim `import` bug.
export sha, sha2, keccak, blake2, hash, utils
const
MaxHashSize* = 128
ErrIncorrectName = "Incorrect hash name"
ErrNotSupported = "Hash not supported"
ErrWrongDigestSize = "Incorrect digest size"
ErrDecodeError = "Decoding error from bytes"
ErrParseError = "Parse error fromHex"
type
MHashCoderProc* = proc(data: openarray[byte],
output: var openarray[byte]) {.nimcall, gcsafe.}
output: var openarray[byte]) {.nimcall, gcsafe, raises: [Defect].}
MHash* = object
mcodec*: MultiCodec
size*: int
@ -44,7 +54,7 @@ type
size*: int
dpos*: int
MultiHashError* = object of CatchableError
MhResult*[T] = Result[T, cstring]
proc identhash(data: openarray[byte], output: var openarray[byte]) =
if len(output) > 0:
@ -345,78 +355,87 @@ proc digestImplWithoutHash(hash: MHash, data: openarray[byte]): MultiHash =
result.data.finish()
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
## data array ``data``.
let mc = MultiCodec.codec(hashname)
if mc == InvalidMultiCodec:
raise newException(MultihashError, "Incorrect hash name")
let hash = CodeHashes.getOrDefault(mc)
if isNil(hash.coder):
raise newException(MultihashError, "Hash not supported")
result = digestImplWithHash(hash, data)
err(ErrIncorrectName)
else:
let hash = CodeHashes.getOrDefault(mc)
if isNil(hash.coder):
err(ErrNotSupported)
else:
ok(digestImplWithHash(hash, data))
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
## data array ``data``.
let hash = CodeHashes.getOrDefault(hashcode)
if isNil(hash.coder):
raise newException(MultihashError, "Hash not supported")
result = digestImplWithHash(hash, data)
err(ErrNotSupported)
else:
ok(digestImplWithHash(hash, data))
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
## ``hashname``.
let mc = MultiCodec.codec(hashname)
if mc == InvalidMultiCodec:
raise newException(MultihashError, "Incorrect hash name")
let hash = CodeHashes.getOrDefault(mc)
if isNil(hash.coder):
raise newException(MultihashError, "Hash not supported")
if hash.size != len(mdigest.data):
raise newException(MultiHashError, "Incorrect MDigest[T] size")
result = digestImplWithoutHash(hash, mdigest.data)
err(ErrIncorrectName)
else:
let hash = CodeHashes.getOrDefault(mc)
if isNil(hash.coder):
err(ErrNotSupported)
elif hash.size != len(mdigest.data):
err(ErrWrongDigestSize)
else:
ok(digestImplWithoutHash(hash, mdigest.data))
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
## ``hashcode``.
let hash = CodeHashes.getOrDefault(hashcode)
if isNil(hash.coder):
raise newException(MultihashError, "Hash not supported")
if (hash.size != 0) and (hash.size != len(mdigest.data)):
raise newException(MultiHashError, "Incorrect MDigest[T] size")
result = digestImplWithoutHash(hash, mdigest.data)
err(ErrNotSupported)
elif (hash.size != 0) and (hash.size != len(mdigest.data)):
err(ErrWrongDigestSize)
else:
ok(digestImplWithoutHash(hash, mdigest.data))
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
## ``hashcode``.
let mc = MultiCodec.codec(hashname)
if mc == InvalidMultiCodec:
raise newException(MultihashError, "Incorrect hash name")
let hash = CodeHashes.getOrDefault(mc)
if isNil(hash.coder):
raise newException(MultihashError, "Hash not supported")
if (hash.size != 0) and (hash.size != len(bdigest)):
raise newException(MultiHashError, "Incorrect bdigest size")
result = digestImplWithoutHash(hash, bdigest)
err(ErrIncorrectName)
else:
let hash = CodeHashes.getOrDefault(mc)
if isNil(hash.coder):
err(ErrNotSupported)
elif (hash.size != 0) and (hash.size != len(bdigest)):
err(ErrWrongDigestSize)
else:
ok(digestImplWithoutHash(hash, bdigest))
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
## ``hashcode``.
let hash = CodeHashes.getOrDefault(hashcode)
if isNil(hash.coder):
raise newException(MultihashError, "Hash not supported")
if (hash.size != 0) and (hash.size != len(bdigest)):
raise newException(MultiHashError, "Incorrect bdigest size")
result = digestImplWithoutHash(hash, bdigest)
err(ErrNotSupported)
elif (hash.size != 0) and (hash.size != len(bdigest)):
err(ErrWrongDigestSize)
else:
ok(digestImplWithoutHash(hash, bdigest))
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``.
##
## 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 res, dpos: int
if len(data) < 2:
return -1
return err(ErrDecodeError)
var vb = initVBuffer(data)
if vb.isEmpty():
return -1
return err(ErrDecodeError)
res = vb.readVarint(code)
if res == -1:
return -1
return err(ErrDecodeError)
dpos += res
res = vb.readVarint(size)
if res == -1:
return -1
return err(ErrDecodeError)
dpos += res
if size > 0x7FFF_FFFF'u64:
return -1
return err(ErrDecodeError)
let hash = CodeHashes.getOrDefault(MultiCodec(code))
if isNil(hash.coder):
return -1
return err(ErrDecodeError)
if (hash.size != 0) and (hash.size != int(size)):
return -1
return err(ErrDecodeError)
if not vb.isEnough(int(size)):
return -1
mhash = MultiHash.init(MultiCodec(code),
return err(ErrDecodeError)
mhash = ? MultiHash.init(MultiCodec(code),
vb.buffer.toOpenArray(vb.offset,
vb.offset + int(size) - 1))
result = vb.offset + int(size)
ok(vb.offset + int(size))
proc validate*(mhtype: typedesc[MultiHash], data: openarray[byte]): bool =
## 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
if len(data) < 2:
return false
let last = len(data) - 1
let last = data.high
var offset = 0
var length = 0
res = LP.getUVarint(data.toOpenArray(offset, last), length, code)
@ -483,15 +510,20 @@ proc validate*(mhtype: typedesc[MultiHash], data: openarray[byte]): bool =
result = true
proc init*(mhtype: typedesc[MultiHash],
data: openarray[byte]): MultiHash {.inline.} =
data: openarray[byte]): MhResult[MultiHash] {.inline.} =
## Create MultiHash from bytes array ``data``.
if MultiHash.decode(data, result) == -1:
raise newException(MultihashError, "Incorrect MultiHash binary format")
var hash: MultiHash
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``.
if MultiHash.decode(fromHex(data), result) == -1:
raise newException(MultihashError, "Incorrect MultiHash binary format")
var hash: MultiHash
try:
discard ? MultiHash.decode(fromHex(data), hash)
ok(hash)
except ValueError:
err(ErrParseError)
proc init58*(mhtype: typedesc[MultiHash],
data: string): MultiHash {.inline.} =
@ -518,7 +550,7 @@ proc `==`*[T](mh: MultiHash, mdigest: MDigest[T]): bool =
if len(mdigest.data) != mh.size:
return false
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.} =
## Compares MultiHash with nimcrypto's MDigest[T], returns ``true`` if

View File

@ -91,7 +91,7 @@ proc hasPublicKey*(pid: PeerID): bool =
## Returns ``true`` if ``pid`` is small enough to hold public key inside.
if len(pid.data) > 0:
var mh: MultiHash
if MultiHash.decode(pid.data, mh) > 0:
if MultiHash.decode(pid.data, mh).isOk:
if mh.mcodec == multiCodec("identity"):
result = true
@ -102,7 +102,7 @@ proc extractPublicKey*(pid: PeerID, pubkey: var PublicKey): bool =
## Returns ``false`` otherwise.
var mh: MultiHash
if len(pid.data) > 0:
if MultiHash.decode(pid.data, mh) > 0:
if MultiHash.decode(pid.data, mh).isOk:
if mh.mcodec == multiCodec("identity"):
let length = len(mh.data.buffer)
result = pubkey.init(mh.data.buffer.toOpenArray(mh.dpos, length - 1))
@ -117,7 +117,7 @@ proc `$`*(pid: PeerID): string =
for i in 0..<2:
result.add(spid[i])
result.add("*")
for i in (len(spid) - 6)..(len(spid) - 1):
for i in (len(spid) - 6)..spid.high:
result.add(spid[i])
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 =
## Create new peer id from public key ``pubkey``.
var pubraw = pubkey.getBytes()
var pubraw = pubkey.getBytes().tryGet()
var mh: MultiHash
if len(pubraw) <= maxInlineKeyLength:
mh = MultiHash.digest("identity", pubraw)
mh = MultiHash.digest("identity", pubraw).tryGet()
else:
mh = MultiHash.digest("sha2-256", pubraw)
mh = MultiHash.digest("sha2-256", pubraw).tryGet()
result.data = mh.data.buffer
proc init*(t: typedesc[PeerID], seckey: PrivateKey): PeerID {.inline.} =
## 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.} =
## Returns ``true`` if ``pid`` matches public key ``pubkey``.

View File

@ -118,4 +118,4 @@ proc publicKey*(p: PeerInfo): Option[PublicKey] {.inline.} =
elif p.key.isSome:
result = p.key
else:
result = some(p.privateKey.getKey())
result = some(p.privateKey.getKey().tryGet())

View File

@ -47,7 +47,7 @@ type
proc encodeMsg*(peerInfo: PeerInfo, observedAddrs: Multiaddress): ProtoBuffer =
result = initProtoBuffer()
result.write(initProtoField(1, peerInfo.publicKey.get().getBytes()))
result.write(initProtoField(1, peerInfo.publicKey.get().getBytes().tryGet()))
for ma in peerInfo.addrs:
result.write(initProtoField(2, ma.data.buffer))

View File

@ -33,7 +33,7 @@ proc sign*(msg: Message, p: PeerInfo): Message {.gcsafe.} =
if buff.buffer.len > 0:
result = msg
result.signature = p.privateKey.
sign(cast[seq[byte]](PubSubPrefix) & buff.buffer).
sign(cast[seq[byte]](PubSubPrefix) & buff.buffer).tryGet().
getBytes()
proc verify*(m: Message, p: PeerInfo): bool =
@ -57,7 +57,7 @@ proc newMessage*(p: PeerInfo,
sign: bool = true): Message {.gcsafe.} =
var seqno: seq[byte] = newSeq[byte](20)
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(),
data: data,

View File

@ -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
let
signedPayload = p.localPrivateKey.sign(PayloadString.toBytes & p.noisePublicKey.getBytes)
signedPayload = p.localPrivateKey.sign(
PayloadString.toBytes & p.noisePublicKey.getBytes).tryGet()
var
libp2pProof = initProtoBuffer()
@ -532,7 +533,7 @@ proc newNoise*(privateKey: PrivateKey; outgoing: bool = true; commonPrologue: se
new result
result.outgoing = outgoing
result.localPrivateKey = privateKey
result.localPublicKey = privateKey.getKey()
result.localPublicKey = privateKey.getKey().tryGet()
discard randomBytes(result.noisePrivateKey)
result.noisePublicKey = result.noisePrivateKey.public()
result.commonPrologue = commonPrologue

View File

@ -166,7 +166,7 @@ proc macCheckAndDecode(sconn: SecioConn, data: var seq[byte]): bool =
if not equalMem(addr data[mark], addr macData[0], macsize):
trace "Invalid MAC",
calculated = toHex(macData.toOpenArray(0, macsize - 1)),
stored = toHex(data.toOpenArray(mark, len(data) - 1))
stored = toHex(data.toOpenArray(mark, data.high))
return false
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
remotePeerId: PeerID
localPeerId: PeerID
localBytesPubkey = s.localPublicKey.getBytes()
localBytesPubkey = s.localPublicKey.getBytes().tryGet()
if randomBytes(localNonce) != SecioNonceSize:
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
let order = getOrder(remoteBytesPubkey, localNonce, localBytesPubkey,
remoteNonce)
remoteNonce).tryGet()
trace "Remote proposal", schemes = remoteExchanges, ciphers = remoteCiphers,
hashes = remoteHashes,
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,
hash = hash
var ekeypair = ephemeral(scheme)
var ekeypair = ephemeral(scheme).tryGet()
# 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 signature = s.localPrivateKey.sign(localCorpus)
var signature = s.localPrivateKey.sign(localCorpus).tryGet()
var localExchange = createExchange(epubkey, signature.getBytes())
var remoteExchange = await transactMessage(conn, localExchange)
@ -430,5 +430,5 @@ method init(s: Secio) {.gcsafe.} =
proc newSecio*(localPrivateKey: PrivateKey): Secio =
new result
result.localPrivateKey = localPrivateKey
result.localPublicKey = localPrivateKey.getKey()
result.localPublicKey = localPrivateKey.getKey().tryGet()
result.init()

View File

@ -31,7 +31,7 @@ proc newStandardSwitch*(privKey = none(PrivateKey),
result = newMplex(conn)
let
seckey = privKey.get(otherwise = PrivateKey.random(ECDSA))
seckey = privKey.get(otherwise = PrivateKey.random(ECDSA).tryGet())
peerInfo = PeerInfo.init(seckey, [address])
mplexProvider = newMuxerProvider(createMplex, MplexCodec)
transports = @[Transport(newTransport(TcpTransport, transportFlags))]

View File

@ -24,9 +24,15 @@ template isEnough*(vb: VBuffer, length: int): bool =
## Returns ``true`` if buffer ``vb`` holds at least ``length`` bytes.
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 =
## Returns number of bytes left in buffer ``vb``.
result = len(vb.buffer) - vb.offset
doAssert(result >= 0)
proc isLiteral[T](s: seq[T]): bool {.inline.} =
type
@ -58,7 +64,7 @@ proc writePBVarint*(vb: var VBuffer, value: PBSomeUVarint) =
var length = 0
var v = value and cast[type(value)](0xFFFF_FFFF_FFFF_FFFF)
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)
doAssert(res == VarintStatus.Success)
vb.offset += length
@ -69,7 +75,7 @@ proc writeLPVarint*(vb: var VBuffer, value: LPSomeUVarint) =
# LibP2P varint supports only 63 bits.
var v = value and cast[type(value)](0x7FFF_FFFF_FFFF_FFFF)
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)
doAssert(res == VarintStatus.Success)
vb.offset += length
@ -82,7 +88,7 @@ proc writeSeq*[T: byte|char](vb: var VBuffer, value: openarray[T]) =
## varint length of the array.
var length = 0
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)))
doAssert(res == VarintStatus.Success)
vb.offset += length
@ -113,7 +119,7 @@ proc peekVarint*(vb: var VBuffer, value: var LPSomeUVarint): int =
var length = 0
if not vb.isEmpty():
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:
result = length
@ -129,7 +135,7 @@ proc peekSeq*[T: string|seq[byte]](vb: var VBuffer, value: var T): int =
var length = 0
var size = 0'u64
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:
vb.offset += length
result = length

View File

@ -19,7 +19,7 @@ suite "GossipSub internal":
test "`rebalanceMesh` Degree Lo":
proc testRun(): Future[bool] {.async.} =
let gossipSub = newPubSub(TestGossipSub,
PeerInfo.init(PrivateKey.random(RSA)))
PeerInfo.init(PrivateKey.random(RSA).get()))
let topic = "foobar"
gossipSub.mesh[topic] = initHashSet[string]()
@ -28,7 +28,7 @@ suite "GossipSub internal":
for i in 0..<15:
let conn = newConnection(newBufferStream())
conns &= conn
let peerInfo = PeerInfo.init(PrivateKey.random(RSA))
let peerInfo = PeerInfo.init(PrivateKey.random(RSA).get())
conn.peerInfo = peerInfo
gossipSub.peers[peerInfo.id] = newPubSubPeer(peerInfo, GossipSubCodec)
gossipSub.peers[peerInfo.id].conn = conn
@ -48,7 +48,7 @@ suite "GossipSub internal":
test "`rebalanceMesh` Degree Hi":
proc testRun(): Future[bool] {.async.} =
let gossipSub = newPubSub(TestGossipSub,
PeerInfo.init(PrivateKey.random(RSA)))
PeerInfo.init(PrivateKey.random(RSA).get()))
let topic = "foobar"
gossipSub.gossipsub[topic] = initHashSet[string]()
@ -57,7 +57,7 @@ suite "GossipSub internal":
for i in 0..<15:
let conn = newConnection(newBufferStream())
conns &= conn
let peerInfo = PeerInfo.init(PrivateKey.random(RSA))
let peerInfo = PeerInfo.init(PrivateKey.random(RSA).get())
conn.peerInfo = peerInfo
gossipSub.peers[peerInfo.id] = newPubSubPeer(peerInfo, GossipSubCodec)
gossipSub.peers[peerInfo.id].conn = conn
@ -77,7 +77,7 @@ suite "GossipSub internal":
test "`replenishFanout` Degree Lo":
proc testRun(): Future[bool] {.async.} =
let gossipSub = newPubSub(TestGossipSub,
PeerInfo.init(PrivateKey.random(RSA)))
PeerInfo.init(PrivateKey.random(RSA).get()))
proc handler(peer: PubSubPeer, msg: seq[RPCMsg]) {.async.} =
discard
@ -89,7 +89,7 @@ suite "GossipSub internal":
for i in 0..<15:
let conn = newConnection(newBufferStream())
conns &= conn
var peerInfo = PeerInfo.init(PrivateKey.random(RSA))
var peerInfo = PeerInfo.init(PrivateKey.random(RSA).get())
conn.peerInfo = peerInfo
gossipSub.peers[peerInfo.id] = newPubSubPeer(peerInfo, GossipSubCodec)
gossipSub.peers[peerInfo.id].handler = handler
@ -109,7 +109,7 @@ suite "GossipSub internal":
test "`dropFanoutPeers` drop expired fanout topics":
proc testRun(): Future[bool] {.async.} =
let gossipSub = newPubSub(TestGossipSub,
PeerInfo.init(PrivateKey.random(RSA)))
PeerInfo.init(PrivateKey.random(RSA).get()))
proc handler(peer: PubSubPeer, msg: seq[RPCMsg]) {.async.} =
discard
@ -122,7 +122,7 @@ suite "GossipSub internal":
for i in 0..<6:
let conn = newConnection(newBufferStream())
conns &= conn
let peerInfo = PeerInfo.init(PrivateKey.random(RSA))
let peerInfo = PeerInfo.init(PrivateKey.random(RSA).get())
conn.peerInfo = peerInfo
gossipSub.peers[peerInfo.id] = newPubSubPeer(peerInfo, GossipSubCodec)
gossipSub.peers[peerInfo.id].handler = handler
@ -143,7 +143,7 @@ suite "GossipSub internal":
test "`dropFanoutPeers` leave unexpired fanout topics":
proc testRun(): Future[bool] {.async.} =
let gossipSub = newPubSub(TestGossipSub,
PeerInfo.init(PrivateKey.random(RSA)))
PeerInfo.init(PrivateKey.random(RSA).get()))
proc handler(peer: PubSubPeer, msg: seq[RPCMsg]) {.async.} =
discard
@ -159,7 +159,7 @@ suite "GossipSub internal":
for i in 0..<6:
let conn = newConnection(newBufferStream())
conns &= conn
let peerInfo = PeerInfo.init(PrivateKey.random(RSA))
let peerInfo = PeerInfo.init(PrivateKey.random(RSA).get())
conn.peerInfo = peerInfo
gossipSub.peers[peerInfo.id] = newPubSubPeer(peerInfo, GossipSubCodec)
gossipSub.peers[peerInfo.id].handler = handler
@ -183,7 +183,7 @@ suite "GossipSub internal":
test "`getGossipPeers` - should gather up to degree D non intersecting peers":
proc testRun(): Future[bool] {.async.} =
let gossipSub = newPubSub(TestGossipSub,
PeerInfo.init(PrivateKey.random(RSA)))
PeerInfo.init(PrivateKey.random(RSA).get()))
proc handler(peer: PubSubPeer, msg: seq[RPCMsg]) {.async.} =
discard
@ -196,7 +196,7 @@ suite "GossipSub internal":
for i in 0..<30:
let conn = newConnection(newBufferStream())
conns &= conn
let peerInfo = PeerInfo.init(PrivateKey.random(RSA))
let peerInfo = PeerInfo.init(PrivateKey.random(RSA).get())
conn.peerInfo = peerInfo
gossipSub.peers[peerInfo.id] = newPubSubPeer(peerInfo, GossipSubCodec)
gossipSub.peers[peerInfo.id].handler = handler
@ -208,7 +208,7 @@ suite "GossipSub internal":
for i in 0..<15:
let conn = newConnection(newBufferStream())
conns &= conn
let peerInfo = PeerInfo.init(PrivateKey.random(RSA))
let peerInfo = PeerInfo.init(PrivateKey.random(RSA).get())
conn.peerInfo = peerInfo
gossipSub.peers[peerInfo.id] = newPubSubPeer(peerInfo, GossipSubCodec)
gossipSub.peers[peerInfo.id].handler = handler
@ -234,7 +234,7 @@ suite "GossipSub internal":
test "`getGossipPeers` - should not crash on missing topics in mesh":
proc testRun(): Future[bool] {.async.} =
let gossipSub = newPubSub(TestGossipSub,
PeerInfo.init(PrivateKey.random(RSA)))
PeerInfo.init(PrivateKey.random(RSA).get()))
proc handler(peer: PubSubPeer, msg: seq[RPCMsg]) {.async.} =
discard
@ -246,7 +246,7 @@ suite "GossipSub internal":
for i in 0..<30:
let conn = newConnection(newBufferStream())
conns &= conn
let peerInfo = PeerInfo.init(PrivateKey.random(RSA))
let peerInfo = PeerInfo.init(PrivateKey.random(RSA).get())
conn.peerInfo = peerInfo
gossipSub.peers[peerInfo.id] = newPubSubPeer(peerInfo, GossipSubCodec)
gossipSub.peers[peerInfo.id].handler = handler
@ -268,7 +268,7 @@ suite "GossipSub internal":
test "`getGossipPeers` - should not crash on missing topics in gossip":
proc testRun(): Future[bool] {.async.} =
let gossipSub = newPubSub(TestGossipSub,
PeerInfo.init(PrivateKey.random(RSA)))
PeerInfo.init(PrivateKey.random(RSA).get()))
proc handler(peer: PubSubPeer, msg: seq[RPCMsg]) {.async.} =
discard
@ -280,7 +280,7 @@ suite "GossipSub internal":
for i in 0..<30:
let conn = newConnection(newBufferStream())
conns &= conn
let peerInfo = PeerInfo.init(PrivateKey.random(RSA))
let peerInfo = PeerInfo.init(PrivateKey.random(RSA).get())
conn.peerInfo = peerInfo
gossipSub.peers[peerInfo.id] = newPubSubPeer(peerInfo, GossipSubCodec)
gossipSub.peers[peerInfo.id].handler = handler
@ -302,7 +302,7 @@ suite "GossipSub internal":
test "`getGossipPeers` - should not crash on missing topics in gossip":
proc testRun(): Future[bool] {.async.} =
let gossipSub = newPubSub(TestGossipSub,
PeerInfo.init(PrivateKey.random(RSA)))
PeerInfo.init(PrivateKey.random(RSA).get()))
proc handler(peer: PubSubPeer, msg: seq[RPCMsg]) {.async.} =
discard
@ -314,7 +314,7 @@ suite "GossipSub internal":
for i in 0..<30:
let conn = newConnection(newBufferStream())
conns &= conn
let peerInfo = PeerInfo.init(PrivateKey.random(RSA))
let peerInfo = PeerInfo.init(PrivateKey.random(RSA).get())
conn.peerInfo = peerInfo
gossipSub.peers[peerInfo.id] = newPubSubPeer(peerInfo, GossipSubCodec)
gossipSub.peers[peerInfo.id].handler = handler

View File

@ -25,7 +25,7 @@ import utils, ../../libp2p/[errors,
import ../helpers
proc createGossipSub(): GossipSub =
var peerInfo = PeerInfo.init(PrivateKey.random(RSA))
var peerInfo = PeerInfo.init(PrivateKey.random(RSA).get())
result = newPubSub(GossipSub, peerInfo)
proc waitSub(sender, receiver: auto; key: string) {.async, gcsafe.} =

View File

@ -11,7 +11,7 @@ import ../../libp2p/[peer,
suite "MCache":
test "put/get":
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"))
mCache.put(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)
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"),
topicIDs: @["foo"])
mCache.put(msg)
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"),
topicIDs: @["bar"])
mCache.put(msg)
@ -41,7 +41,7 @@ suite "MCache":
var mCache = newMCache(1, 5)
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"),
topicIDs: @["foo"])
mCache.put(msg)
@ -50,7 +50,7 @@ suite "MCache":
check mCache.window("foo").len == 0
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"),
topicIDs: @["bar"])
mCache.put(msg)
@ -59,7 +59,7 @@ suite "MCache":
check mCache.window("bar").len == 0
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"),
topicIDs: @["baz"])
mCache.put(msg)
@ -71,19 +71,19 @@ suite "MCache":
var mCache = newMCache(1, 5)
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"),
topicIDs: @["foo"])
mCache.put(msg)
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"),
topicIDs: @["bar"])
mCache.put(msg)
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"),
topicIDs: @["baz"])
mCache.put(msg)

View File

@ -38,17 +38,17 @@ suite "Content identifier CID test suite":
var bmsg = cast[seq[byte]](msg)
var bmmsg = cast[seq[byte]](mmsg)
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"),
MultiHash.digest("sha2-256", bmsg))
MultiHash.digest("sha2-256", bmsg).get())
var cid2 = cid1
var cid3 = cid0
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"),
MultiHash.digest("sha2-256", bmmsg))
MultiHash.digest("sha2-256", bmmsg).get())
var cid6 = Cid.init(CIDv1, multiCodec("dag-pb"),
MultiHash.digest("keccak-256", bmsg))
MultiHash.digest("keccak-256", bmsg).get())
check:
cid0 == cid1
cid1 == cid2

View File

@ -378,13 +378,13 @@ suite "Key interface test suite":
test "Go test vectors":
for i in 0..<len(PrivateKeys):
var seckey = PrivateKey.init(fromHex(stripSpaces(PrivateKeys[i])))
var pubkey = PublicKey.init(fromHex(stripSpaces(PublicKeys[i])))
var calckey = seckey.getKey()
var seckey = PrivateKey.init(fromHex(stripSpaces(PrivateKeys[i]))).expect("private key")
var pubkey = PublicKey.init(fromHex(stripSpaces(PublicKeys[i]))).expect("public key")
var calckey = seckey.getKey().expect("public key")
check:
pubkey == calckey
var checkseckey = seckey.getBytes()
var checkpubkey = pubkey.getBytes()
var checkseckey = seckey.getBytes().expect("private key")
var checkpubkey = pubkey.getBytes().expect("public key")
check:
toHex(checkseckey) == stripSpaces(PrivateKeys[i])
toHex(checkpubkey) == stripSpaces(PublicKeys[i])
@ -394,19 +394,19 @@ suite "Key interface test suite":
var bmsg = cast[seq[byte]](msg)
for i in 0..<5:
var seckey = PrivateKey.random(ECDSA)
var pubkey = seckey.getKey()
var pair = KeyPair.random(ECDSA)
var sig1 = pair.seckey.sign(bmsg)
var sig2 = seckey.sign(bmsg)
var seckey = PrivateKey.random(ECDSA).get()
var pubkey = seckey.getKey().get()
var pair = KeyPair.random(ECDSA).get()
var sig1 = pair.seckey.sign(bmsg).get()
var sig2 = seckey.sign(bmsg).get()
var sersig1 = sig1.getBytes()
var sersig2 = sig2.getBytes()
var serpub1 = pair.pubkey.getBytes()
var serpub2 = pubkey.getBytes()
var recsig1 = Signature.init(sersig1)
var recsig2 = Signature.init(sersig2)
var recpub1 = PublicKey.init(serpub1)
var recpub2 = PublicKey.init(serpub2)
var serpub1 = pair.pubkey.getBytes().get()
var serpub2 = pubkey.getBytes().get()
var recsig1 = Signature.init(sersig1).get()
var recsig2 = Signature.init(sersig2).get()
var recpub1 = PublicKey.init(serpub1).get()
var recpub2 = PublicKey.init(serpub2).get()
check:
sig1.verify(bmsg, pair.pubkey) == true
recsig1.verify(bmsg, recpub1) == true
@ -414,19 +414,19 @@ suite "Key interface test suite":
recsig2.verify(bmsg, recpub2) == true
for i in 0..<5:
var seckey = PrivateKey.random(Ed25519)
var pubkey = seckey.getKey()
var pair = KeyPair.random(Ed25519)
var sig1 = pair.seckey.sign(bmsg)
var sig2 = seckey.sign(bmsg)
var seckey = PrivateKey.random(Ed25519).get()
var pubkey = seckey.getKey().get()
var pair = KeyPair.random(Ed25519).get()
var sig1 = pair.seckey.sign(bmsg).get()
var sig2 = seckey.sign(bmsg).get()
var sersig1 = sig1.getBytes()
var sersig2 = sig2.getBytes()
var serpub1 = pair.pubkey.getBytes()
var serpub2 = pubkey.getBytes()
var recsig1 = Signature.init(sersig1)
var recsig2 = Signature.init(sersig2)
var recpub1 = PublicKey.init(serpub1)
var recpub2 = PublicKey.init(serpub2)
var serpub1 = pair.pubkey.getBytes().get()
var serpub2 = pubkey.getBytes().get()
var recsig1 = Signature.init(sersig1).get()
var recsig2 = Signature.init(sersig2).get()
var recpub1 = PublicKey.init(serpub1).get()
var recpub2 = PublicKey.init(serpub2).get()
check:
sig1.verify(bmsg, pair.pubkey) == true
recsig1.verify(bmsg, recpub1) == true
@ -434,19 +434,19 @@ suite "Key interface test suite":
recsig2.verify(bmsg, recpub2) == true
for i in 0..<5:
var seckey = PrivateKey.random(RSA, 512)
var pubkey = seckey.getKey()
var pair = KeyPair.random(RSA, 512)
var sig1 = pair.seckey.sign(bmsg)
var sig2 = seckey.sign(bmsg)
var seckey = PrivateKey.random(RSA, 512).get()
var pubkey = seckey.getKey().get()
var pair = KeyPair.random(RSA, 512).get()
var sig1 = pair.seckey.sign(bmsg).get()
var sig2 = seckey.sign(bmsg).get()
var sersig1 = sig1.getBytes()
var sersig2 = sig2.getBytes()
var serpub1 = pair.pubkey.getBytes()
var serpub2 = pubkey.getBytes()
var recsig1 = Signature.init(sersig1)
var recsig2 = Signature.init(sersig2)
var recpub1 = PublicKey.init(serpub1)
var recpub2 = PublicKey.init(serpub2)
var serpub1 = pair.pubkey.getBytes().get()
var serpub2 = pubkey.getBytes().get()
var recsig1 = Signature.init(sersig1).get()
var recsig2 = Signature.init(sersig2).get()
var recpub1 = PublicKey.init(serpub1).get()
var recpub2 = PublicKey.init(serpub2).get()
check:
sig1.verify(bmsg, pair.pubkey) == true
recsig1.verify(bmsg, recpub1) == true

View File

@ -300,15 +300,15 @@ suite "EC NIST-P256/384/521 test suite":
for i in 0..<TestsCount:
var rkey1, rkey2: EcPrivateKey
var skey2 = newSeq[byte](256)
var key = EcPrivateKey.random(Secp256r1)
var skey1 = key.getBytes()
var key = EcPrivateKey.random(Secp256r1).expect("random key")
var skey1 = key.getBytes().expect("bytes")
check:
key.toBytes(skey2) > 0
key.toBytes(skey2).expect("bytes") > 0
check:
rkey1.init(skey1).isOk
rkey2.init(skey2).isOk
var rkey3 = EcPrivateKey.init(skey1)
var rkey4 = EcPrivateKey.init(skey2)
var rkey3 = EcPrivateKey.init(skey1).expect("private key")
var rkey4 = EcPrivateKey.init(skey2).expect("private key")
check:
rkey1 == key
rkey2 == key
@ -319,14 +319,14 @@ suite "EC NIST-P256/384/521 test suite":
for i in 0..<TestsCount:
var rkey1, rkey2: EcPublicKey
var skey2 = newSeq[byte](256)
var pair = EcKeyPair.random(Secp256r1)
var skey1 = pair.pubkey.getBytes()
var pair = EcKeyPair.random(Secp256r1).expect("random key")
var skey1 = pair.pubkey.getBytes().expect("bytes")
check:
pair.pubkey.toBytes(skey2) > 0
pair.pubkey.toBytes(skey2).expect("bytes") > 0
rkey1.init(skey1).isOk
rkey2.init(skey2).isOk
var rkey3 = EcPublicKey.init(skey1)
var rkey4 = EcPublicKey.init(skey2)
var rkey3 = EcPublicKey.init(skey1).expect("public key")
var rkey4 = EcPublicKey.init(skey2).expect("public key")
check:
rkey1 == pair.pubkey
rkey2 == pair.pubkey
@ -335,8 +335,8 @@ suite "EC NIST-P256/384/521 test suite":
test "[secp256r1] ECDHE test":
for i in 0..<TestsCount:
var kp1 = EcKeyPair.random(Secp256r1)
var kp2 = EcKeyPair.random(Secp256r1)
var kp1 = EcKeyPair.random(Secp256r1).expect("random key")
var kp2 = EcKeyPair.random(Secp256r1).expect("random key")
var shared1 = kp2.pubkey.scalarMul(kp1.seckey)
var shared2 = kp1.pubkey.scalarMul(kp2.seckey)
check:
@ -348,10 +348,10 @@ suite "EC NIST-P256/384/521 test suite":
for i in 0..<3:
var key1 = fromHex(stripSpaces(ECDHEPrivateKeys[i * 2]))
var key2 = fromHex(stripSpaces(ECDHEPrivateKeys[i * 2 + 1]))
var seckey1 = EcPrivateKey.initRaw(key1)
var seckey2 = EcPrivateKey.initRaw(key2)
var pubkey1 = seckey1.getKey()
var pubkey2 = seckey2.getKey()
var seckey1 = EcPrivateKey.initRaw(key1).expect("initRaw key")
var seckey2 = EcPrivateKey.initRaw(key2).expect("initRaw key")
var pubkey1 = seckey1.getKey().expect("public key")
var pubkey2 = seckey2.getKey().expect("public key")
var secret1 = getSecret(pubkey2, seckey1)
var secret2 = getSecret(pubkey1, seckey2)
var expsecret = fromHex(stripSpaces(ECDHESecrets[i]))
@ -361,45 +361,45 @@ suite "EC NIST-P256/384/521 test suite":
test "[secp256r1] ECDSA test vectors":
for i in 0..<2:
var sk = EcPrivateKey.init(stripSpaces(SignatureSecKeys[i]))
var expectpk = EcPublicKey.init(stripSpaces(SignaturePubKeys[i]))
var checkpk = sk.getKey()
var sk = EcPrivateKey.init(stripSpaces(SignatureSecKeys[i])).expect("private key")
var expectpk = EcPublicKey.init(stripSpaces(SignaturePubKeys[i])).expect("private key")
var checkpk = sk.getKey().expect("public key")
check expectpk == checkpk
var checksig = sk.sign(SignatureMessages[i])
var expectsig = EcSignature.init(stripSpaces(SignatureVectors[i]))
var checksig = sk.sign(SignatureMessages[i]).expect("signature")
var expectsig = EcSignature.init(stripSpaces(SignatureVectors[i])).expect("signature")
check:
checksig == expectsig
checksig.verify(SignatureMessages[i], checkpk) == true
let error = len(checksig.buffer) - 1
let error = checksig.buffer.high
checksig.buffer[error] = not(checksig.buffer[error])
check checksig.verify(SignatureMessages[i], checkpk) == false
test "[secp256r1] ECDSA non-deterministic test vectors":
var sk = EcPrivateKey.init(stripSpaces(NDPrivateKeys[0]))
var pk = EcPublicKey.init(stripSpaces(NDPublicKeys[0]))
var checkpk = sk.getKey()
var sk = EcPrivateKey.init(stripSpaces(NDPrivateKeys[0])).expect("private key")
var pk = EcPublicKey.init(stripSpaces(NDPublicKeys[0])).expect("public key")
var checkpk = sk.getKey().expect("public key")
check pk == checkpk
for i in 0..<6:
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
let error = len(checksig.buffer) - 1
let error = checksig.buffer.high
checksig.buffer[error] = not(checksig.buffer[error])
check checksig.verify(message, pk) == false
test "[secp256r1] Generate/Sign/Serialize/Deserialize/Verify test":
var message = "message to sign"
for i in 0..<TestsCount:
var kp = EcKeyPair.random(Secp256r1)
var sig = kp.seckey.sign(message)
var sersk = kp.seckey.getBytes()
var serpk = kp.pubkey.getBytes()
var sersig = sig.getBytes()
var kp = EcKeyPair.random(Secp256r1).expect("random key")
var sig = kp.seckey.sign(message).expect("signature")
var sersk = kp.seckey.getBytes().expect("bytes")
var serpk = kp.pubkey.getBytes().expect("bytes")
var sersig = sig.getBytes().expect("bytes")
discard EcPrivateKey.init(sersk)
var pubkey = EcPublicKey.init(serpk)
var csig = EcSignature.init(sersig)
var pubkey = EcPublicKey.init(serpk).expect("public key")
var csig = EcSignature.init(sersig).expect("signature")
check csig.verify(message, pubkey) == true
let error = len(csig.buffer) - 1
let error = csig.buffer.high
csig.buffer[error] = not(csig.buffer[error])
check csig.verify(message, pubkey) == false
@ -407,15 +407,15 @@ suite "EC NIST-P256/384/521 test suite":
for i in 0..<TestsCount:
var rkey1, rkey2: EcPrivateKey
var skey2 = newSeq[byte](256)
var key = EcPrivateKey.random(Secp384r1)
var skey1 = key.getBytes()
var key = EcPrivateKey.random(Secp384r1).expect("random key")
var skey1 = key.getBytes().expect("bytes")
check:
key.toBytes(skey2) > 0
key.toBytes(skey2).expect("bytes") > 0
check:
rkey1.init(skey1).isOk
rkey2.init(skey2).isOk
var rkey3 = EcPrivateKey.init(skey1)
var rkey4 = EcPrivateKey.init(skey2)
var rkey3 = EcPrivateKey.init(skey1).expect("private key")
var rkey4 = EcPrivateKey.init(skey2).expect("private key")
check:
rkey1 == key
rkey2 == key
@ -426,14 +426,14 @@ suite "EC NIST-P256/384/521 test suite":
for i in 0..<TestsCount:
var rkey1, rkey2: EcPublicKey
var skey2 = newSeq[byte](256)
var pair = EcKeyPair.random(Secp384r1)
var skey1 = pair.pubkey.getBytes()
var pair = EcKeyPair.random(Secp384r1).expect("random key")
var skey1 = pair.pubkey.getBytes().expect("bytes")
check:
pair.pubkey.toBytes(skey2) > 0
pair.pubkey.toBytes(skey2).expect("bytes") > 0
rkey1.init(skey1).isOk
rkey2.init(skey2).isOk
var rkey3 = EcPublicKey.init(skey1)
var rkey4 = EcPublicKey.init(skey2)
var rkey3 = EcPublicKey.init(skey1).expect("public key")
var rkey4 = EcPublicKey.init(skey2).expect("public key")
check:
rkey1 == pair.pubkey
rkey2 == pair.pubkey
@ -442,8 +442,8 @@ suite "EC NIST-P256/384/521 test suite":
test "[secp384r1] ECDHE test":
for i in 0..<TestsCount:
var kp1 = EcKeyPair.random(Secp384r1)
var kp2 = EcKeyPair.random(Secp384r1)
var kp1 = EcKeyPair.random(Secp384r1).expect("random key")
var kp2 = EcKeyPair.random(Secp384r1).expect("random key")
var shared1 = kp2.pubkey.scalarMul(kp1.seckey)
var shared2 = kp1.pubkey.scalarMul(kp2.seckey)
check:
@ -455,10 +455,10 @@ suite "EC NIST-P256/384/521 test suite":
for i in 3..<6:
var key1 = fromHex(stripSpaces(ECDHEPrivateKeys[i * 2]))
var key2 = fromHex(stripSpaces(ECDHEPrivateKeys[i * 2 + 1]))
var seckey1 = EcPrivateKey.initRaw(key1)
var seckey2 = EcPrivateKey.initRaw(key2)
var pubkey1 = seckey1.getKey()
var pubkey2 = seckey2.getKey()
var seckey1 = EcPrivateKey.initRaw(key1).expect("private key")
var seckey2 = EcPrivateKey.initRaw(key2).expect("private key")
var pubkey1 = seckey1.getKey().expect("public key")
var pubkey2 = seckey2.getKey().expect("public key")
var secret1 = getSecret(pubkey2, seckey1)
var secret2 = getSecret(pubkey1, seckey2)
var expsecret = fromHex(stripSpaces(ECDHESecrets[i]))
@ -468,45 +468,45 @@ suite "EC NIST-P256/384/521 test suite":
test "[secp384r1] ECDSA test vectors":
for i in 2..<4:
var sk = EcPrivateKey.init(stripSpaces(SignatureSecKeys[i]))
var expectpk = EcPublicKey.init(stripSpaces(SignaturePubKeys[i]))
var checkpk = sk.getKey()
var sk = EcPrivateKey.init(stripSpaces(SignatureSecKeys[i])).expect("private key")
var expectpk = EcPublicKey.init(stripSpaces(SignaturePubKeys[i])).expect("public key")
var checkpk = sk.getKey().expect("public key")
check expectpk == checkpk
var checksig = sk.sign(SignatureMessages[i])
var expectsig = EcSignature.init(stripSpaces(SignatureVectors[i]))
var checksig = sk.sign(SignatureMessages[i]).expect("signature")
var expectsig = EcSignature.init(stripSpaces(SignatureVectors[i])).expect("signature")
check:
checksig == expectsig
checksig.verify(SignatureMessages[i], checkpk) == true
let error = len(checksig.buffer) - 1
let error = checksig.buffer.high
checksig.buffer[error] = not(checksig.buffer[error])
check checksig.verify(SignatureMessages[i], checkpk) == false
test "[secp384r1] ECDSA non-deterministic test vectors":
var sk = EcPrivateKey.init(stripSpaces(NDPrivateKeys[1]))
var pk = EcPublicKey.init(stripSpaces(NDPublicKeys[1]))
var checkpk = sk.getKey()
var sk = EcPrivateKey.init(stripSpaces(NDPrivateKeys[1])).expect("private key")
var pk = EcPublicKey.init(stripSpaces(NDPublicKeys[1])).expect("public key")
var checkpk = sk.getKey().expect("public key")
check pk == checkpk
for i in 6..<12:
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
let error = len(checksig.buffer) - 1
let error = checksig.buffer.high
checksig.buffer[error] = not(checksig.buffer[error])
check checksig.verify(message, pk) == false
test "[secp384r1] Generate/Sign/Serialize/Deserialize/Verify test":
var message = "message to sign"
for i in 0..<TestsCount:
var kp = EcKeyPair.random(Secp384r1)
var sig = kp.seckey.sign(message)
var sersk = kp.seckey.getBytes()
var serpk = kp.pubkey.getBytes()
var sersig = sig.getBytes()
discard EcPrivateKey.init(sersk)
var pubkey = EcPublicKey.init(serpk)
var csig = EcSignature.init(sersig)
var kp = EcKeyPair.random(Secp384r1).expect("random key")
var sig = kp.seckey.sign(message).expect("signature")
var sersk = kp.seckey.getBytes().expect("bytes")
var serpk = kp.pubkey.getBytes().expect("bytes")
var sersig = sig.getBytes().expect("bytes")
discard EcPrivateKey.init(sersk).expect("private key")
var pubkey = EcPublicKey.init(serpk).expect("public key")
var csig = EcSignature.init(sersig).expect("signature")
check csig.verify(message, pubkey) == true
let error = len(csig.buffer) - 1
let error = csig.buffer.high
csig.buffer[error] = not(csig.buffer[error])
check csig.verify(message, pubkey) == false
@ -514,15 +514,15 @@ suite "EC NIST-P256/384/521 test suite":
for i in 0..<TestsCount:
var rkey1, rkey2: EcPrivateKey
var skey2 = newSeq[byte](256)
var key = EcPrivateKey.random(Secp521r1)
var skey1 = key.getBytes()
var key = EcPrivateKey.random(Secp521r1).expect("random key")
var skey1 = key.getBytes().expect("bytes")
check:
key.toBytes(skey2) > 0
key.toBytes(skey2).expect("bytes") > 0
check:
rkey1.init(skey1).isOk
rkey2.init(skey2).isOk
var rkey3 = EcPrivateKey.init(skey1)
var rkey4 = EcPrivateKey.init(skey2)
var rkey3 = EcPrivateKey.init(skey1).expect("private key")
var rkey4 = EcPrivateKey.init(skey2).expect("private key")
check:
rkey1 == key
rkey2 == key
@ -533,14 +533,14 @@ suite "EC NIST-P256/384/521 test suite":
for i in 0..<TestsCount:
var rkey1, rkey2: EcPublicKey
var skey2 = newSeq[byte](256)
var pair = EcKeyPair.random(Secp521r1)
var skey1 = pair.pubkey.getBytes()
var pair = EcKeyPair.random(Secp521r1).expect("random key")
var skey1 = pair.pubkey.getBytes().expect("bytes")
check:
pair.pubkey.toBytes(skey2) > 0
pair.pubkey.toBytes(skey2).expect("bytes") > 0
rkey1.init(skey1).isOk
rkey2.init(skey2).isOk
var rkey3 = EcPublicKey.init(skey1)
var rkey4 = EcPublicKey.init(skey2)
var rkey3 = EcPublicKey.init(skey1).expect("public key")
var rkey4 = EcPublicKey.init(skey2).expect("public key")
check:
rkey1 == pair.pubkey
rkey2 == pair.pubkey
@ -549,8 +549,8 @@ suite "EC NIST-P256/384/521 test suite":
test "[secp521r1] ECDHE test":
for i in 0..<TestsCount:
var kp1 = EcKeyPair.random(Secp521r1)
var kp2 = EcKeyPair.random(Secp521r1)
var kp1 = EcKeyPair.random(Secp521r1).expect("random key")
var kp2 = EcKeyPair.random(Secp521r1).expect("random key")
var shared1 = kp2.pubkey.scalarMul(kp1.seckey)
var shared2 = kp1.pubkey.scalarMul(kp2.seckey)
check:
@ -562,10 +562,10 @@ suite "EC NIST-P256/384/521 test suite":
for i in 6..<9:
var key1 = fromHex(stripSpaces(ECDHEPrivateKeys[i * 2]))
var key2 = fromHex(stripSpaces(ECDHEPrivateKeys[i * 2 + 1]))
var seckey1 = EcPrivateKey.initRaw(key1)
var seckey2 = EcPrivateKey.initRaw(key2)
var pubkey1 = seckey1.getKey()
var pubkey2 = seckey2.getKey()
var seckey1 = EcPrivateKey.initRaw(key1).expect("private key")
var seckey2 = EcPrivateKey.initRaw(key2).expect("private key")
var pubkey1 = seckey1.getKey().expect("public key")
var pubkey2 = seckey2.getKey().expect("public key")
var secret1 = getSecret(pubkey2, seckey1)
var secret2 = getSecret(pubkey1, seckey2)
var expsecret = fromHex(stripSpaces(ECDHESecrets[i]))
@ -575,44 +575,44 @@ suite "EC NIST-P256/384/521 test suite":
test "[secp521r1] ECDSA test vectors":
for i in 4..<6:
var sk = EcPrivateKey.init(stripSpaces(SignatureSecKeys[i]))
var expectpk = EcPublicKey.init(stripSpaces(SignaturePubKeys[i]))
var checkpk = sk.getKey()
var sk = EcPrivateKey.init(stripSpaces(SignatureSecKeys[i])).expect("private key")
var expectpk = EcPublicKey.init(stripSpaces(SignaturePubKeys[i])).expect("public key")
var checkpk = sk.getKey().expect("public key")
check expectpk == checkpk
var checksig = sk.sign(SignatureMessages[i])
var expectsig = EcSignature.init(stripSpaces(SignatureVectors[i]))
var checksig = sk.sign(SignatureMessages[i]).expect("signature")
var expectsig = EcSignature.init(stripSpaces(SignatureVectors[i])).expect("signature")
check:
checksig == expectsig
checksig.verify(SignatureMessages[i], checkpk) == true
let error = len(checksig.buffer) - 1
let error = checksig.buffer.high
checksig.buffer[error] = not(checksig.buffer[error])
check checksig.verify(SignatureMessages[i], checkpk) == false
test "[secp521r1] ECDSA non-deterministic test vectors":
var sk = EcPrivateKey.init(stripSpaces(NDPrivateKeys[2]))
var pk = EcPublicKey.init(stripSpaces(NDPublicKeys[2]))
var checkpk = sk.getKey()
var sk = EcPrivateKey.init(stripSpaces(NDPrivateKeys[2])).expect("private key")
var pk = EcPublicKey.init(stripSpaces(NDPublicKeys[2])).expect("public key")
var checkpk = sk.getKey().expect("public key")
check pk == checkpk
for i in 12..<18:
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
let error = len(checksig.buffer) - 1
let error = checksig.buffer.high
checksig.buffer[error] = not(checksig.buffer[error])
check checksig.verify(message, pk) == false
test "[secp521r1] Generate/Sign/Serialize/Deserialize/Verify test":
var message = "message to sign"
for i in 0..<TestsCount:
var kp = EcKeyPair.random(Secp521r1)
var sig = kp.seckey.sign(message)
var sersk = kp.seckey.getBytes()
var serpk = kp.pubkey.getBytes()
var sersig = sig.getBytes()
discard EcPrivateKey.init(sersk)
var pubkey = EcPublicKey.init(serpk)
var csig = EcSignature.init(sersig)
var kp = EcKeyPair.random(Secp521r1).expect("random key")
var sig = kp.seckey.sign(message).expect("signature")
var sersk = kp.seckey.getBytes().expect("bytes")
var serpk = kp.pubkey.getBytes().expect("bytes")
var sersig = sig.getBytes().expect("bytes")
discard EcPrivateKey.init(sersk).expect("private key")
var pubkey = EcPublicKey.init(serpk).expect("public key")
var csig = EcSignature.init(sersig).expect("signature")
check csig.verify(message, pubkey) == true
let error = len(csig.buffer) - 1
let error = csig.buffer.high
csig.buffer[error] = not(csig.buffer[error])
check csig.verify(message, pubkey) == false

View File

@ -111,15 +111,15 @@ suite "Ed25519 test suite":
for i in 0..<TestsCount:
var rkey1, rkey2: EdPrivateKey
var skey2 = newSeq[byte](256)
var key = EdPrivateKey.random()
var key = EdPrivateKey.random().expect("private key")
var skey1 = key.getBytes()
check:
key.toBytes(skey2) > 0
check:
rkey1.init(skey1) == true
rkey2.init(skey2) == true
var rkey3 = EdPrivateKey.init(skey1)
var rkey4 = EdPrivateKey.init(skey2)
var rkey3 = EdPrivateKey.init(skey1).expect("key/sig")
var rkey4 = EdPrivateKey.init(skey2).expect("key/sig")
check:
rkey1 == key
rkey2 == key
@ -135,14 +135,14 @@ suite "Ed25519 test suite":
for i in 0..<TestsCount:
var rkey1, rkey2: EdPublicKey
var skey2 = newSeq[byte](256)
var pair = EdKeyPair.random()
var pair = EdKeyPair.random().expect("random key pair")
var skey1 = pair.pubkey.getBytes()
check:
pair.pubkey.toBytes(skey2) > 0
rkey1.init(skey1) == true
rkey2.init(skey2) == true
var rkey3 = EdPublicKey.init(skey1)
var rkey4 = EdPublicKey.init(skey2)
var rkey3 = EdPublicKey.init(skey1).expect("key/sig")
var rkey4 = EdPublicKey.init(skey2).expect("key/sig")
check:
rkey1 == pair.pubkey
rkey2 == pair.pubkey
@ -156,13 +156,13 @@ suite "Ed25519 test suite":
test "RFC8032 test vectors":
for i in 0..<5:
var key = EdPrivateKey.init(stripSpaces(SecretKeys[i]))
var exppub = EdPublicKey.init(stripSpaces(PublicKeys[i]))
var key = EdPrivateKey.init(stripSpaces(SecretKeys[i])).expect("key/sig")
var exppub = EdPublicKey.init(stripSpaces(PublicKeys[i])).expect("key/sig")
var pubkey = key.getKey()
check pubkey == exppub
var msg = fromHex(stripSpaces(Messages[i]))
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.verify(msg, pubkey) == true
sig.data[32] = not(sig.data[32])
@ -171,15 +171,15 @@ suite "Ed25519 test suite":
test "Generate/Sign/Serialize/Deserialize/Verify test":
var message = "message to sign"
for i in 0..<TestsCount:
var kp = EdKeyPair.random()
var kp = EdKeyPair.random().expect("random key pair")
var sig = kp.seckey.sign(message)
var sersk = kp.seckey.getBytes()
var serpk = kp.pubkey.getBytes()
var sersig = sig.getBytes()
discard EdPrivateKey.init(sersk)
var pubkey = EdPublicKey.init(serpk)
var csig = EdSignature.init(sersig)
var pubkey = EdPublicKey.init(serpk).expect("key/sig")
var csig = EdSignature.init(sersig).expect("key/sig")
check csig.verify(message, pubkey) == true
let error = len(csig.data) - 1
let error = csig.data.high
csig.data[error] = not(csig.data[error])
check csig.verify(message, pubkey) == false

View File

@ -21,7 +21,7 @@ suite "Identify":
test "handle identify message":
proc testHandle(): Future[bool] {.async.} =
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,
[ma],
["/test/proto1/1.0.0",
@ -41,12 +41,12 @@ suite "Identify":
let transport2: TcpTransport = newTransport(TcpTransport)
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)
discard await msDial.select(conn, IdentifyCodec)
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.protoVersion.get() == ProtoVersion
# check id.agentVersion.get() == AgentVersion
@ -66,7 +66,7 @@ suite "Identify":
test "handle failed identify":
proc testHandleError() {.async.} =
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 msListen = newMultistream()
@ -85,12 +85,12 @@ suite "Identify":
let transport2: TcpTransport = newTransport(TcpTransport)
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)
try:
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:
await done.wait(5000.millis) # when no issues will not wait that long!
await conn.close()

View File

@ -66,7 +66,7 @@ proc createNode*(privKey: Option[PrivateKey] = none(PrivateKey),
gossip: bool = false): Switch =
var seckey = privKey
if privKey.isNone:
seckey = some(PrivateKey.random(RSA))
seckey = some(PrivateKey.random(RSA).get())
var peerInfo = NativePeerInfo.init(seckey.get(), [Multiaddress.init(address)])
proc createMplex(conn: Connection): Muxer = newMplex(conn)

View File

@ -82,8 +82,8 @@ suite "MultiHash test suite":
for item in RustTestVectors:
var msg = item[1]
var bmsg = cast[seq[byte]](msg)
var mh1 = MultiHash.digest(item[0], bmsg)
var mh2 = MultiHash.init(stripSpaces(item[2]))
var mh1 = MultiHash.digest(item[0], bmsg).get()
var mh2 = MultiHash.init(stripSpaces(item[2])).get()
check:
hex(mh1) == stripSpaces(item[2])
hex(mh1) == hex(mh2)

View File

@ -50,7 +50,7 @@ method init(p: TestProto) {.gcsafe.} =
p.handler = handle
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)
let identify = newIdentify(peerInfo)
@ -77,7 +77,7 @@ suite "Noise":
proc testListenerDialer(): Future[bool] {.async.} =
let
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)
proc connHandler(conn: Connection) {.async, gcsafe.} =
@ -93,7 +93,7 @@ suite "Noise":
let
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)
conn = await transport2.dial(transport1.ma)
sconn = await clientNoise.secure(conn, true)
@ -115,7 +115,7 @@ suite "Noise":
proc testListenerDialer(): Future[bool] {.async.} =
let
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)
readTask = newFuture[void]()
@ -135,7 +135,7 @@ suite "Noise":
let
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)
conn = await transport2.dial(transport1.ma)
sconn = await clientNoise.secure(conn, true)
@ -156,7 +156,7 @@ suite "Noise":
proc testListenerDialer(): Future[bool] {.async.} =
let
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)
readTask = newFuture[void]()
@ -178,7 +178,7 @@ suite "Noise":
let
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)
conn = await transport2.dial(transport1.ma)
sconn = await clientNoise.secure(conn, true)

View File

@ -101,8 +101,8 @@ const
suite "Peer testing suite":
test "Go PeerID test vectors":
for i in 0..<len(PrivateKeys):
var seckey = PrivateKey.init(stripSpaces(PrivateKeys[i]))
var pubkey = seckey.getKey()
var seckey = PrivateKey.init(stripSpaces(PrivateKeys[i])).get()
var pubkey = seckey.getKey().get()
var p1 = PeerID.init(seckey)
var p2 = PeerID.init(pubkey)
var p3 = PeerID.init(PeerIDs[i])

View File

@ -13,29 +13,29 @@ suite "PeerInfo":
check tracker.isLeaked() == false
test "Should init with private key":
let seckey = PrivateKey.random(RSA)
let seckey = PrivateKey.random(RSA).get()
var peerInfo = PeerInfo.init(seckey)
var peerId = PeerID.init(seckey)
check peerId == peerInfo.peerId
check seckey == peerInfo.privateKey
check seckey.getKey == peerInfo.publicKey.get()
check seckey.getKey().get() == peerInfo.publicKey.get()
test "Should init with public key":
let seckey = PrivateKey.random(RSA)
var peerInfo = PeerInfo.init(seckey.getKey())
var peerId = PeerID.init(seckey.getKey())
let seckey = PrivateKey.random(RSA).get()
var peerInfo = PeerInfo.init(seckey.getKey().get())
var peerId = PeerID.init(seckey.getKey().get())
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":
let seckey = PrivateKey.random(Ed25519)
var peerInfo = PeerInfo.init(PeerID.init(seckey.getKey()))
var peerId = PeerID.init(seckey.getKey())
let seckey = PrivateKey.random(Ed25519).get()
var peerInfo = PeerInfo.init(PeerID.init(seckey.getKey.get()))
var peerId = PeerID.init(seckey.getKey.get())
check peerId == peerInfo.peerId
check seckey.getKey == peerInfo.publicKey.get()
check seckey.getKey.get() == peerInfo.publicKey.get()
test "Should init from CIDv0 string":
var peerInfo = PeerInfo.init("QmYyQSo1c1Ym7orWxLYvCrM2EmxFTANf8wXmmE7DWjhx5N")
@ -52,16 +52,16 @@ suite "PeerInfo":
# PeerID.init("bafzbeie5745rpv2m6tjyuugywy4d5ewrqgqqhfnf445he3omzpjbx5xqxe") == peerInfo.peerId
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
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
test "join() and isClosed() test":
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
var joinFut = peerInfo.join()
check joinFut.finished() == false

View File

@ -273,14 +273,14 @@ suite "RSA 512/1024/2048/4096 test suite":
for i in 0..<TestsCount:
var rkey1, rkey2: RsaPrivateKey
var skey2 = newSeq[byte](4096)
var key = RsaPrivateKey.random(512)
var skey1 = key.getBytes()
check key.toBytes(skey2) > 0
var key = RsaPrivateKey.random(512).expect("random key")
var skey1 = key.getBytes().expect("bytes")
check key.toBytes(skey2).expect("bytes") > 0
check:
rkey1.init(skey1).isOk()
rkey2.init(skey2).isOk()
var rkey3 = RsaPrivateKey.init(skey1)
var rkey4 = RsaPrivateKey.init(skey2)
var rkey3 = RsaPrivateKey.init(skey1).expect("key initialization")
var rkey4 = RsaPrivateKey.init(skey2).expect("key initialization")
check:
rkey1 == key
rkey2 == key
@ -291,14 +291,14 @@ suite "RSA 512/1024/2048/4096 test suite":
for i in 0..<TestsCount:
var rkey1, rkey2: RsaPrivateKey
var skey2 = newSeq[byte](4096)
var key = RsaPrivateKey.random(1024)
var skey1 = key.getBytes()
check key.toBytes(skey2) > 0
var key = RsaPrivateKey.random(1024).expect("random failed")
var skey1 = key.getBytes().expect("bytes")
check key.toBytes(skey2).expect("bytes") > 0
check:
rkey1.init(skey1).isOk()
rkey2.init(skey2).isOk()
var rkey3 = RsaPrivateKey.init(skey1)
var rkey4 = RsaPrivateKey.init(skey2)
var rkey3 = RsaPrivateKey.init(skey1).expect("key initialization")
var rkey4 = RsaPrivateKey.init(skey2).expect("key initialization")
check:
rkey1 == key
rkey2 == key
@ -308,14 +308,14 @@ suite "RSA 512/1024/2048/4096 test suite":
test "[rsa2048] Private key serialize/deserialize test":
var rkey1, rkey2: RsaPrivateKey
var skey2 = newSeq[byte](4096)
var key = RsaPrivateKey.random(2048)
var skey1 = key.getBytes()
check key.toBytes(skey2) > 0
var key = RsaPrivateKey.random(2048).expect("random failed")
var skey1 = key.getBytes().expect("bytes")
check key.toBytes(skey2).expect("bytes") > 0
check:
rkey1.init(skey1).isOk()
rkey2.init(skey2).isOk()
var rkey3 = RsaPrivateKey.init(skey1)
var rkey4 = RsaPrivateKey.init(skey2)
var rkey3 = RsaPrivateKey.init(skey1).expect("key initialization")
var rkey4 = RsaPrivateKey.init(skey2).expect("key initialization")
check:
rkey1 == key
rkey2 == key
@ -327,14 +327,14 @@ suite "RSA 512/1024/2048/4096 test suite":
when defined(release):
var rkey1, rkey2: RsaPrivateKey
var skey2 = newSeq[byte](4096)
var key = RsaPrivateKey.random(4096)
var skey1 = key.getBytes()
check key.toBytes(skey2) > 0
var key = RsaPrivateKey.random(4096).expect("random failed")
var skey1 = key.getBytes().expect("bytes")
check key.toBytes(skey2).expect("bytes") > 0
check:
rkey1.init(skey1).isOk()
rkey2.init(skey2).isOk()
var rkey3 = RsaPrivateKey.init(skey1)
var rkey4 = RsaPrivateKey.init(skey2)
var rkey3 = RsaPrivateKey.init(skey1).expect("key initialization")
var rkey4 = RsaPrivateKey.init(skey2).expect("key initialization")
check:
rkey1 == key
rkey2 == key
@ -345,14 +345,14 @@ suite "RSA 512/1024/2048/4096 test suite":
for i in 0..<TestsCount:
var rkey1, rkey2: RsaPublicKey
var skey2 = newSeq[byte](4096)
var pair = RsaKeyPair.random(512)
var skey1 = pair.pubkey().getBytes()
var pair = RsaKeyPair.random(512).expect("random failed")
var skey1 = pair.pubkey().getBytes().expect("bytes")
check:
pair.pubkey.toBytes(skey2) > 0
pair.pubkey.toBytes(skey2).expect("bytes") > 0
rkey1.init(skey1).isOk()
rkey2.init(skey2).isOk()
var rkey3 = RsaPublicKey.init(skey1)
var rkey4 = RsaPublicKey.init(skey2)
var rkey3 = RsaPublicKey.init(skey1).expect("key initialization")
var rkey4 = RsaPublicKey.init(skey2).expect("key initialization")
check:
rkey1 == pair.pubkey
rkey2 == pair.pubkey
@ -363,14 +363,14 @@ suite "RSA 512/1024/2048/4096 test suite":
for i in 0..<TestsCount:
var rkey1, rkey2: RsaPublicKey
var skey2 = newSeq[byte](4096)
var pair = RsaKeyPair.random(1024)
var skey1 = pair.pubkey.getBytes()
var pair = RsaKeyPair.random(1024).expect("random failed")
var skey1 = pair.pubkey.getBytes().expect("bytes")
check:
pair.pubkey.toBytes(skey2) > 0
pair.pubkey.toBytes(skey2).expect("bytes") > 0
rkey1.init(skey1).isOk()
rkey2.init(skey2).isOk()
var rkey3 = RsaPublicKey.init(skey1)
var rkey4 = RsaPublicKey.init(skey2)
var rkey3 = RsaPublicKey.init(skey1).expect("key initialization")
var rkey4 = RsaPublicKey.init(skey2).expect("key initialization")
check:
rkey1 == pair.pubkey
rkey2 == pair.pubkey
@ -380,14 +380,14 @@ suite "RSA 512/1024/2048/4096 test suite":
test "[rsa2048] Public key serialize/deserialize test":
var rkey1, rkey2: RsaPublicKey
var skey2 = newSeq[byte](4096)
var pair = RsaKeyPair.random(2048)
var skey1 = pair.pubkey.getBytes()
var pair = RsaKeyPair.random(2048).expect("random failed")
var skey1 = pair.pubkey.getBytes().expect("bytes")
check:
pair.pubkey.toBytes(skey2) > 0
pair.pubkey.toBytes(skey2).expect("bytes") > 0
rkey1.init(skey1).isOk()
rkey2.init(skey2).isOk()
var rkey3 = RsaPublicKey.init(skey1)
var rkey4 = RsaPublicKey.init(skey2)
var rkey3 = RsaPublicKey.init(skey1).expect("key initialization")
var rkey4 = RsaPublicKey.init(skey2).expect("key initialization")
check:
rkey1 == pair.pubkey
rkey2 == pair.pubkey
@ -398,14 +398,14 @@ suite "RSA 512/1024/2048/4096 test suite":
when defined(release):
var rkey1, rkey2: RsaPublicKey
var skey2 = newSeq[byte](4096)
var pair = RsaKeyPair.random(4096)
var skey1 = pair.pubkey.getBytes()
var pair = RsaKeyPair.random(4096).expect("random failed")
var skey1 = pair.pubkey.getBytes().expect("bytes")
check:
pair.pubkey.toBytes(skey2) > 0
pair.pubkey.toBytes(skey2).expect("bytes") > 0
rkey1.init(skey1).isOk()
rkey2.init(skey2).isOk()
var rkey3 = RsaPublicKey.init(skey1)
var rkey4 = RsaPublicKey.init(skey2)
var rkey3 = RsaPublicKey.init(skey1).expect("key initialization")
var rkey4 = RsaPublicKey.init(skey2).expect("key initialization")
check:
rkey1 == 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":
var message = "message to sign"
for i in 0..<TestsCount:
var kp = RsaKeyPair.random(512)
var sig = kp.seckey.sign(message)
var sersk = kp.seckey.getBytes()
var serpk = kp.pubkey.getBytes()
var sersig = sig.getBytes()
discard RsaPrivateKey.init(sersk)
var pubkey = RsaPublicKey.init(serpk)
var csig = RsaSignature.init(sersig)
var kp = RsaKeyPair.random(512).expect("RsaKeyPair.random failed")
var sig = kp.seckey.sign(message).expect("signature")
var sersk = kp.seckey.getBytes().expect("bytes")
var serpk = kp.pubkey.getBytes().expect("bytes")
var sersig = sig.getBytes().expect("bytes")
discard RsaPrivateKey.init(sersk).expect("RsaPrivateKey.key initialization")
var pubkey = RsaPublicKey.init(serpk).expect("RsaPublicKey.key initialization")
var csig = RsaSignature.init(sersig).expect("RsaSignature.key initialization")
check csig.verify(message, pubkey) == true
let error = len(csig.buffer) - 1
let error = csig.buffer.high
csig.buffer[error] = not(csig.buffer[error])
check csig.verify(message, pubkey) == false
test "[rsa1024] Generate/Sign/Serialize/Deserialize/Verify test":
var message = "message to sign"
for i in 0..<TestsCount:
var kp = RsaKeyPair.random(1024)
var sig = kp.seckey.sign(message)
var sersk = kp.seckey.getBytes()
var serpk = kp.pubkey.getBytes()
var sersig = sig.getBytes()
discard RsaPrivateKey.init(sersk)
var pubkey = RsaPublicKey.init(serpk)
var csig = RsaSignature.init(sersig)
var kp = RsaKeyPair.random(1024).expect("RsaPrivateKey.random failed")
var sig = kp.seckey.sign(message).expect("signature")
var sersk = kp.seckey.getBytes().expect("bytes")
var serpk = kp.pubkey.getBytes().expect("bytes")
var sersig = sig.getBytes().expect("bytes")
discard RsaPrivateKey.init(sersk).expect("key initialization")
var pubkey = RsaPublicKey.init(serpk).expect("key initialization")
var csig = RsaSignature.init(sersig).expect("key initialization")
check csig.verify(message, pubkey) == true
let error = len(csig.buffer) - 1
let error = csig.buffer.high
csig.buffer[error] = not(csig.buffer[error])
check csig.verify(message, pubkey) == false
test "[rsa2048] Generate/Sign/Serialize/Deserialize/Verify test":
var message = "message to sign"
var kp = RsaKeyPair.random(2048)
var sig = kp.seckey.sign(message)
var sersk = kp.seckey.getBytes()
var serpk = kp.pubkey.getBytes()
var sersig = sig.getBytes()
discard RsaPrivateKey.init(sersk)
var pubkey = RsaPublicKey.init(serpk)
var csig = RsaSignature.init(sersig)
var kp = RsaKeyPair.random(2048).expect("RsaPrivateKey.random failed")
var sig = kp.seckey.sign(message).expect("signature")
var sersk = kp.seckey.getBytes().expect("bytes")
var serpk = kp.pubkey.getBytes().expect("bytes")
var sersig = sig.getBytes().expect("bytes")
discard RsaPrivateKey.init(sersk).expect("key initialization")
var pubkey = RsaPublicKey.init(serpk).expect("key initialization")
var csig = RsaSignature.init(sersig).expect("key initialization")
check csig.verify(message, pubkey) == true
let error = len(csig.buffer) - 1
let error = csig.buffer.high
csig.buffer[error] = not(csig.buffer[error])
check csig.verify(message, pubkey) == false
test "[rsa4096] Generate/Sign/Serialize/Deserialize/Verify test":
when defined(release):
var message = "message to sign"
var kp = RsaKeyPair.random(2048)
var sig = kp.seckey.sign(message)
var sersk = kp.seckey.getBytes()
var serpk = kp.pubkey.getBytes()
var sersig = sig.getBytes()
discard RsaPrivateKey.init(sersk)
var pubkey = RsaPublicKey.init(serpk)
var csig = RsaSignature.init(sersig)
var kp = RsaKeyPair.random(2048).expect("RsaPrivateKey.random failed")
var sig = kp.seckey.sign(message).expect("signature")
var sersk = kp.seckey.getBytes().expect("bytes")
var serpk = kp.pubkey.getBytes().expect("bytes")
var sersig = sig.getBytes().expect("bytes")
discard RsaPrivateKey.init(sersk).expect("key initialization")
var pubkey = RsaPublicKey.init(serpk).expect("key initialization")
var csig = RsaSignature.init(sersig).expect("key initialization")
check csig.verify(message, pubkey) == true
let error = len(csig.buffer) - 1
let error = csig.buffer.high
csig.buffer[error] = not(csig.buffer[error])
check csig.verify(message, pubkey) == false
test "[rsa512] Test vectors":
var prvser = fromHex(stripSpaces(PrivateKeys[0]))
var pubser = fromHex(stripSpaces(PublicKeys[0]))
var seckey = RsaPrivateKey.init(prvser)
var pubkey = RsaPublicKey.init(pubser)
var seckey = RsaPrivateKey.init(prvser).expect("key initialization")
var pubkey = RsaPublicKey.init(pubser).expect("key initialization")
check:
seckey.getBytes() == prvser
seckey.getBytes().expect("bytes") == prvser
var cpubkey = seckey.getKey()
check:
pubkey == cpubkey
pubkey.getBytes() == cpubkey.getBytes()
pubkey.getBytes() == pubser
pubkey.getBytes().expect("bytes") == cpubkey.getBytes().expect("bytes")
pubkey.getBytes().expect("bytes") == pubser
for i in 0..1:
var sigser = fromHex(stripSpaces(Signatures[i]))
var sig = RsaSignature.init(sigser)
var csig = seckey.sign(Messages[i])
var sig = RsaSignature.init(sigser).expect("key initialization")
var csig = seckey.sign(Messages[i]).expect("signature")
check:
sig == csig
sig.getBytes() == csig.getBytes()
sig.getBytes().expect("bytes") == csig.getBytes().expect("bytes")
csig.verify(Messages[i], pubkey) == true
csig.verify(Messages[(i + 1) mod 2], pubkey) == false
test "[rsa1024] Test vectors":
var prvser = fromHex(stripSpaces(PrivateKeys[1]))
var pubser = fromHex(stripSpaces(PublicKeys[1]))
var seckey = RsaPrivateKey.init(prvser)
var pubkey = RsaPublicKey.init(pubser)
var seckey = RsaPrivateKey.init(prvser).expect("key initialization")
var pubkey = RsaPublicKey.init(pubser).expect("key initialization")
check:
seckey.getBytes() == prvser
seckey.getBytes().expect("bytes") == prvser
var cpubkey = seckey.getKey()
check:
pubkey == cpubkey
pubkey.getBytes() == cpubkey.getBytes()
pubkey.getBytes() == pubser
pubkey.getBytes().expect("bytes") == cpubkey.getBytes().expect("bytes")
pubkey.getBytes().expect("bytes") == pubser
for i in 0..1:
var sigser = fromHex(stripSpaces(Signatures[2 + i]))
var sig = RsaSignature.init(sigser)
var csig = seckey.sign(Messages[2 + i])
var sig = RsaSignature.init(sigser).expect("key initialization")
var csig = seckey.sign(Messages[2 + i]).expect("signature")
check:
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 + 1) mod 2], pubkey) == false
test "[rsa2048] Test vectors":
var prvser = fromHex(stripSpaces(PrivateKeys[2]))
var pubser = fromHex(stripSpaces(PublicKeys[2]))
var seckey = RsaPrivateKey.init(prvser)
var pubkey = RsaPublicKey.init(pubser)
var seckey = RsaPrivateKey.init(prvser).expect("key initialization")
var pubkey = RsaPublicKey.init(pubser).expect("key initialization")
check:
seckey.getBytes() == prvser
seckey.getBytes().expect("bytes") == prvser
var cpubkey = seckey.getKey()
check:
pubkey == cpubkey
pubkey.getBytes() == cpubkey.getBytes()
pubkey.getBytes() == pubser
pubkey.getBytes().expect("bytes") == cpubkey.getBytes().expect("bytes")
pubkey.getBytes().expect("bytes") == pubser
for i in 0..1:
var sigser = fromHex(stripSpaces(Signatures[4 + i]))
var sig = RsaSignature.init(sigser)
var csig = seckey.sign(Messages[4 + i])
var sig = RsaSignature.init(sigser).expect("key initialization")
var csig = seckey.sign(Messages[4 + i]).expect("signature")
check:
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 + 1) mod 2], pubkey) == false
test "[rsa4096] Test vectors":
var prvser = fromHex(stripSpaces(PrivateKeys[3]))
var pubser = fromHex(stripSpaces(PublicKeys[3]))
var seckey = RsaPrivateKey.init(prvser)
var pubkey = RsaPublicKey.init(pubser)
var seckey = RsaPrivateKey.init(prvser).expect("key initialization")
var pubkey = RsaPublicKey.init(pubser).expect("key initialization")
check:
seckey.getBytes() == prvser
seckey.getBytes().expect("bytes") == prvser
var cpubkey = seckey.getKey()
check:
pubkey == cpubkey
pubkey.getBytes() == cpubkey.getBytes()
pubkey.getBytes() == pubser
pubkey.getBytes().expect("bytes") == cpubkey.getBytes().expect("bytes")
pubkey.getBytes().expect("bytes") == pubser
for i in 0..1:
var sigser = fromHex(stripSpaces(Signatures[6 + i]))
var sig = RsaSignature.init(sigser)
var csig = seckey.sign(Messages[6 + i])
var sig = RsaSignature.init(sigser).expect("key initialization")
var csig = seckey.sign(Messages[6 + i]).expect("signature")
check:
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 + 1) mod 2], pubkey) == false

View File

@ -18,15 +18,15 @@ suite "Secp256k1 testing suite":
for i in 0..<TestsCount:
var rkey1, rkey2: SkPrivateKey
var skey2 = newSeq[byte](256)
var key = SkPrivateKey.random()
var key = SkPrivateKey.random().expect("random key")
var skey1 = key.getBytes()
check:
key.toBytes(skey2) > 0
key.toBytes(skey2).expect("bytes len") > 0
check:
rkey1.init(skey1) == true
rkey2.init(skey2) == true
var rkey3 = SkPrivateKey.init(skey1)
var rkey4 = SkPrivateKey.init(skey2)
rkey1.init(skey1).isOk == true
rkey2.init(skey2).isOk == true
var rkey3 = SkPrivateKey.init(skey1).expect("private key")
var rkey4 = SkPrivateKey.init(skey2).expect("private key")
check:
rkey1 == key
rkey2 == key
@ -41,14 +41,14 @@ suite "Secp256k1 testing suite":
for i in 0..<TestsCount:
var rkey1, rkey2: SkPublicKey
var skey2 = newSeq[byte](256)
var pair = SkKeyPair.random()
var pair = SkKeyPair.random().expect("random key pair")
var skey1 = pair.pubkey.getBytes()
check:
pair.pubkey.toBytes(skey2) > 0
rkey1.init(skey1) == true
rkey2.init(skey2) == true
var rkey3 = SkPublicKey.init(skey1)
var rkey4 = SkPublicKey.init(skey2)
pair.pubkey.toBytes(skey2).expect("bytes len") > 0
rkey1.init(skey1).isOk == true
rkey2.init(skey2).isOk == true
var rkey3 = SkPublicKey.init(skey1).expect("public key")
var rkey4 = SkPublicKey.init(skey2).expect("public key")
check:
rkey1 == pair.pubkey
rkey2 == pair.pubkey
@ -59,16 +59,16 @@ suite "Secp256k1 testing suite":
test "Generate/Sign/Serialize/Deserialize/Verify test":
var message = "message to sign"
for i in 0..<TestsCount:
var kp = SkKeyPair.random()
var sig = kp.seckey.sign(message)
var kp = SkKeyPair.random().expect("random key pair")
var sig = kp.seckey.sign(message).expect("signature")
var sersk = kp.seckey.getBytes()
var serpk = kp.pubkey.getBytes()
var sersig = sig.getBytes()
discard SkPrivateKey.init(sersk)
var pubkey = SkPublicKey.init(serpk)
var csig = SkSignature.init(sersig)
discard SkPrivateKey.init(sersk).expect("private key")
var pubkey = SkPublicKey.init(serpk).expect("public key")
var csig = SkSignature.init(sersig).expect("signature")
check csig.verify(message, pubkey) == true
var error = csig.getBytes()
error[^1] = not error[^1]
csig = SkSignature.init(error)
csig = SkSignature.init(error).expect("signature")
check csig.verify(message, pubkey) == false

View File

@ -31,7 +31,7 @@ type
TestProto = ref object of LPProtocol
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)
let identify = newIdentify(peerInfo)

View File

@ -263,7 +263,7 @@ suite "Variable integer test suite":
buffer.setLen(PBedgeSizes[i])
check:
PB.putUVarint(buffer, length, PBedgeValues[i]) == VarintStatus.Success
buffer.setLen(len(buffer) - 1)
buffer.setlen(buffer.high)
check:
PB.getUVarint(buffer, length, value) == VarintStatus.Incomplete
@ -339,7 +339,7 @@ suite "Variable integer test suite":
buffer.setLen(LPedgeSizes[i])
check:
LP.putUVarint(buffer, length, LPedgeValues[i]) == VarintStatus.Success
buffer.setLen(len(buffer) - 1)
buffer.setlen(buffer.high)
check:
LP.getUVarint(buffer, length, value) == VarintStatus.Incomplete