diff --git a/libp2p/crypto/crypto.nim b/libp2p/crypto/crypto.nim index 820bde77d..1a448c315 100644 --- a/libp2p/crypto/crypto.nim +++ b/libp2p/crypto/crypto.nim @@ -70,13 +70,15 @@ when supported(PKScheme.Secp256k1): import ecnist, bearssl import ../protobuf/minprotobuf, ../vbuffer, ../multihash, ../multicodec -import nimcrypto/[rijndael, twofish, sha2, hash, hmac, utils] +import nimcrypto/[rijndael, twofish, sha2, hash, hmac] +# We use `ncrutils` for constant-time hexadecimal encoding/decoding procedures. +import nimcrypto/utils as ncrutils import ../utility import stew/results export results # This is workaround for Nim's `import` bug -export rijndael, twofish, sha2, hash, hmac, utils +export rijndael, twofish, sha2, hash, hmac, ncrutils from strutils import split @@ -514,20 +516,14 @@ proc init*[T: PrivateKey|PublicKey](key: var T, data: string): bool = ## hexadecimal string representation. ## ## Returns ``true`` on success. - try: - key.init(utils.fromHex(data)) - except ValueError: - false + key.init(ncrutils.fromHex(data)) proc init*(sig: var Signature, data: string): bool = ## Initialize signature ``sig`` from serialized hexadecimal string ## representation. ## ## Returns ``true`` on success. - try: - sig.init(utils.fromHex(data)) - except ValueError: - false + sig.init(ncrutils.fromHex(data)) proc init*(t: typedesc[PrivateKey], data: openarray[byte]): CryptoResult[PrivateKey] = @@ -559,10 +555,7 @@ proc init*(t: typedesc[Signature], proc init*(t: typedesc[PrivateKey], data: string): CryptoResult[PrivateKey] = ## Create new private key from libp2p's protobuf serialized hexadecimal string ## form. - try: - t.init(utils.fromHex(data)) - except ValueError: - err(KeyError) + t.init(ncrutils.fromHex(data)) when supported(PKScheme.RSA): proc init*(t: typedesc[PrivateKey], key: rsa.RsaPrivateKey): PrivateKey = @@ -591,17 +584,11 @@ when supported(PKScheme.ECDSA): proc init*(t: typedesc[PublicKey], data: string): CryptoResult[PublicKey] = ## Create new public key from libp2p's protobuf serialized hexadecimal string ## form. - try: - t.init(utils.fromHex(data)) - except ValueError: - err(KeyError) + t.init(ncrutils.fromHex(data)) proc init*(t: typedesc[Signature], data: string): CryptoResult[Signature] = ## Create new signature from serialized hexadecimal string form. - try: - t.init(utils.fromHex(data)) - except ValueError: - err(SigError) + t.init(ncrutils.fromHex(data)) proc `==`*(key1, key2: PublicKey): bool {.inline.} = ## Return ``true`` if two public keys ``key1`` and ``key2`` of the same @@ -709,7 +696,7 @@ func shortLog*(key: PrivateKey|PublicKey): string = proc `$`*(sig: Signature): string = ## Get string representation of signature ``sig``. - result = toHex(sig.data) + result = ncrutils.toHex(sig.data) proc sign*(key: PrivateKey, data: openarray[byte]): CryptoResult[Signature] {.gcsafe.} = diff --git a/libp2p/crypto/ecnist.nim b/libp2p/crypto/ecnist.nim index ad8312613..8c3ebdce5 100644 --- a/libp2p/crypto/ecnist.nim +++ b/libp2p/crypto/ecnist.nim @@ -17,7 +17,8 @@ {.push raises: [Defect].} import bearssl -import nimcrypto/utils +# We use `ncrutils` for constant-time hexadecimal encoding/decoding procedures. +import nimcrypto/utils as ncrutils import minasn1 export minasn1.Asn1Error import stew/[results, ctops] @@ -289,7 +290,7 @@ proc `$`*(seckey: EcPrivateKey): string = result = "Corrupted key" else: let e = offset + cast[int](seckey.key.xlen) - 1 - result = toHex(seckey.buffer.toOpenArray(offset, e)) + result = ncrutils.toHex(seckey.buffer.toOpenArray(offset, e)) proc `$`*(pubkey: EcPublicKey): string = ## Return string representation of EC public key. @@ -305,14 +306,14 @@ proc `$`*(pubkey: EcPublicKey): string = result = "Corrupted key" else: let e = offset + cast[int](pubkey.key.qlen) - 1 - result = toHex(pubkey.buffer.toOpenArray(offset, e)) + result = ncrutils.toHex(pubkey.buffer.toOpenArray(offset, e)) proc `$`*(sig: EcSignature): string = ## Return hexadecimal string representation of EC signature. if isNil(sig) or len(sig.buffer) == 0: result = "Empty or uninitialized ECNIST signature" else: - result = toHex(sig.buffer) + result = ncrutils.toHex(sig.buffer) proc toRawBytes*(seckey: EcPrivateKey, data: var openarray[byte]): EcResult[int] = ## Serialize EC private key ``seckey`` to raw binary form and store it @@ -708,14 +709,16 @@ proc init*(sig: var EcSignature, data: openarray[byte]): Result[void, Asn1Error] else: err(Asn1Error.Incorrect) -proc init*[T: EcPKI](sospk: var T, data: string): Result[void, Asn1Error] {.inline.} = +proc init*[T: EcPKI](sospk: var T, + data: string): Result[void, Asn1Error] {.inline.} = ## Initialize EC `private key`, `public key` or `signature` ``sospk`` from ## ASN.1 DER hexadecimal string representation ``data``. ## ## Procedure returns ``Asn1Status``. - sospk.init(fromHex(data)) + sospk.init(ncrutils.fromHex(data)) -proc init*(t: typedesc[EcPrivateKey], data: openarray[byte]): EcResult[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. var key: EcPrivateKey @@ -725,7 +728,8 @@ proc init*(t: typedesc[EcPrivateKey], data: openarray[byte]): EcResult[EcPrivate else: ok(key) -proc init*(t: typedesc[EcPublicKey], data: openarray[byte]): EcResult[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. var key: EcPublicKey @@ -735,7 +739,8 @@ proc init*(t: typedesc[EcPublicKey], data: openarray[byte]): EcResult[EcPublicKe else: ok(key) -proc init*(t: typedesc[EcSignature], data: openarray[byte]): EcResult[EcSignature] = +proc init*(t: typedesc[EcSignature], + data: openarray[byte]): EcResult[EcSignature] = ## Initialize EC signature from raw binary representation ``data`` and ## return constructed object. var sig: EcSignature @@ -748,10 +753,7 @@ proc init*(t: typedesc[EcSignature], data: openarray[byte]): EcResult[EcSignatur 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. - try: - t.init(fromHex(data)) - except ValueError: - err(EcKeyIncorrectError) + t.init(ncrutils.fromHex(data)) proc initRaw*(key: var EcPrivateKey, data: openarray[byte]): bool = ## Initialize EC `private key` or `scalar` ``key`` from raw binary @@ -833,9 +835,10 @@ proc initRaw*[T: EcPKI](sospk: var T, data: string): bool {.inline.} = ## raw hexadecimal string representation ``data``. ## ## Procedure returns ``true`` on success, ``false`` otherwise. - result = sospk.initRaw(fromHex(data)) + result = sospk.initRaw(ncrutils.fromHex(data)) -proc initRaw*(t: typedesc[EcPrivateKey], data: openarray[byte]): EcResult[EcPrivateKey] = +proc initRaw*(t: typedesc[EcPrivateKey], + data: openarray[byte]): EcResult[EcPrivateKey] = ## Initialize EC private key from raw binary representation ``data`` and ## return constructed object. var res: EcPrivateKey @@ -844,7 +847,8 @@ proc initRaw*(t: typedesc[EcPrivateKey], data: openarray[byte]): EcResult[EcPriv else: ok(res) -proc initRaw*(t: typedesc[EcPublicKey], data: openarray[byte]): EcResult[EcPublicKey] = +proc initRaw*(t: typedesc[EcPublicKey], + data: openarray[byte]): EcResult[EcPublicKey] = ## Initialize EC public key from raw binary representation ``data`` and ## return constructed object. var res: EcPublicKey @@ -853,7 +857,8 @@ proc initRaw*(t: typedesc[EcPublicKey], data: openarray[byte]): EcResult[EcPubli else: ok(res) -proc initRaw*(t: typedesc[EcSignature], data: openarray[byte]): EcResult[EcSignature] = +proc initRaw*(t: typedesc[EcSignature], + data: openarray[byte]): EcResult[EcSignature] = ## Initialize EC signature from raw binary representation ``data`` and ## return constructed object. var res: EcSignature @@ -865,7 +870,7 @@ proc initRaw*(t: typedesc[EcSignature], data: openarray[byte]): EcResult[EcSigna proc initRaw*[T: EcPKI](t: typedesc[T], data: string): T {.inline.} = ## Initialize EC `private key`, `public key` or `signature` from raw ## hexadecimal string representation ``data`` and return constructed object. - result = t.initRaw(fromHex(data)) + result = t.initRaw(ncrutils.fromHex(data)) proc scalarMul*(pub: EcPublicKey, sec: EcPrivateKey): EcPublicKey = ## Return scalar multiplication of ``pub`` and ``sec``. @@ -926,7 +931,7 @@ 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]): EcResult[EcSignature] {.gcsafe.} = + message: openarray[T]): EcResult[EcSignature] {.gcsafe.} = ## Get ECDSA signature of data ``message`` using private key ``seckey``. if isNil(seckey): return err(EcKeyIncorrectError) diff --git a/libp2p/crypto/ed25519/ed25519.nim b/libp2p/crypto/ed25519/ed25519.nim index 3c16b7cf6..663cee97f 100644 --- a/libp2p/crypto/ed25519/ed25519.nim +++ b/libp2p/crypto/ed25519/ed25519.nim @@ -14,7 +14,9 @@ {.push raises: Defect.} import constants, bearssl -import nimcrypto/[hash, sha2, utils] +import nimcrypto/[hash, sha2] +# We use `ncrutils` for constant-time hexadecimal encoding/decoding procedures. +import nimcrypto/utils as ncrutils import stew/[results, ctops] export results @@ -1735,14 +1737,17 @@ proc `==`*(eda, edb: EdSignature): bool = ## Compare ED25519 `signature` objects for equality. result = CT.isEqual(eda.data, edb.data) -proc `$`*(key: EdPrivateKey): string = toHex(key.data) +proc `$`*(key: EdPrivateKey): string = ## Return string representation of ED25519 `private key`. + ncrutils.toHex(key.data) -proc `$`*(key: EdPublicKey): string = toHex(key.data) +proc `$`*(key: EdPublicKey): string = ## Return string representation of ED25519 `private key`. + ncrutils.toHex(key.data) -proc `$`*(sig: EdSignature): string = toHex(sig.data) +proc `$`*(sig: EdSignature): string = ## Return string representation of ED25519 `signature`. + ncrutils.toHex(sig.data) proc init*(key: var EdPrivateKey, data: openarray[byte]): bool = ## Initialize ED25519 `private key` ``key`` from raw binary @@ -1779,32 +1784,24 @@ proc init*(key: var EdPrivateKey, data: string): bool = ## representation ``data``. ## ## Procedure returns ``true`` on success. - try: - init(key, fromHex(data)) - except ValueError: - false + init(key, ncrutils.fromHex(data)) proc init*(key: var EdPublicKey, data: string): bool = ## Initialize ED25519 `public key` ``key`` from hexadecimal string ## representation ``data``. ## ## Procedure returns ``true`` on success. - try: - init(key, fromHex(data)) - except ValueError: - false + init(key, ncrutils.fromHex(data)) proc init*(sig: var EdSignature, data: string): bool = ## Initialize ED25519 `signature` ``sig`` from hexadecimal string ## representation ``data``. ## ## Procedure returns ``true`` on success. - try: - init(sig, fromHex(data)) - except ValueError: - false + init(sig, ncrutils.fromHex(data)) -proc init*(t: typedesc[EdPrivateKey], data: openarray[byte]): Result[EdPrivateKey, EdError] = +proc init*(t: typedesc[EdPrivateKey], + data: openarray[byte]): Result[EdPrivateKey, EdError] = ## Initialize ED25519 `private key` from raw binary representation ``data`` ## and return constructed object. var res: t @@ -1813,7 +1810,8 @@ proc init*(t: typedesc[EdPrivateKey], data: openarray[byte]): Result[EdPrivateKe else: ok(res) -proc init*(t: typedesc[EdPublicKey], data: openarray[byte]): Result[EdPublicKey, EdError] = +proc init*(t: typedesc[EdPublicKey], + data: openarray[byte]): Result[EdPublicKey, EdError] = ## Initialize ED25519 `public key` from raw binary representation ``data`` ## and return constructed object. var res: t @@ -1822,7 +1820,8 @@ proc init*(t: typedesc[EdPublicKey], data: openarray[byte]): Result[EdPublicKey, else: ok(res) -proc init*(t: typedesc[EdSignature], data: openarray[byte]): Result[EdSignature, EdError] = +proc init*(t: typedesc[EdSignature], + data: openarray[byte]): Result[EdSignature, EdError] = ## Initialize ED25519 `signature` from raw binary representation ``data`` ## and return constructed object. var res: t @@ -1831,7 +1830,8 @@ proc init*(t: typedesc[EdSignature], data: openarray[byte]): Result[EdSignature, else: ok(res) -proc init*(t: typedesc[EdPrivateKey], data: string): Result[EdPrivateKey, EdError] = +proc init*(t: typedesc[EdPrivateKey], + data: string): Result[EdPrivateKey, EdError] = ## Initialize ED25519 `private key` from hexadecimal string representation ## ``data`` and return constructed object. var res: t @@ -1840,7 +1840,8 @@ proc init*(t: typedesc[EdPrivateKey], data: string): Result[EdPrivateKey, EdErro else: ok(res) -proc init*(t: typedesc[EdPublicKey], data: string): Result[EdPublicKey, EdError] = +proc init*(t: typedesc[EdPublicKey], + data: string): Result[EdPublicKey, EdError] = ## Initialize ED25519 `public key` from hexadecimal string representation ## ``data`` and return constructed object. var res: t @@ -1849,7 +1850,8 @@ proc init*(t: typedesc[EdPublicKey], data: string): Result[EdPublicKey, EdError] else: ok(res) -proc init*(t: typedesc[EdSignature], data: string): Result[EdSignature, EdError] = +proc init*(t: typedesc[EdSignature], + data: string): Result[EdSignature, EdError] = ## Initialize ED25519 `signature` from hexadecimal string representation ## ``data`` and return constructed object. var res: t diff --git a/libp2p/crypto/minasn1.nim b/libp2p/crypto/minasn1.nim index 9363d2118..32c71fe51 100644 --- a/libp2p/crypto/minasn1.nim +++ b/libp2p/crypto/minasn1.nim @@ -13,7 +13,8 @@ import stew/[endians2, results] export results -import nimcrypto/utils +# We use `ncrutils` for constant-time hexadecimal encoding/decoding procedures. +import nimcrypto/utils as ncrutils type Asn1Error* {.pure.} = enum @@ -593,7 +594,7 @@ proc init*(t: typedesc[Asn1Buffer], data: openarray[byte]): Asn1Buffer = proc init*(t: typedesc[Asn1Buffer], data: string): Asn1Buffer = ## Initialize ``Asn1Buffer`` from hexadecimal string ``data``. - result.buffer = fromHex(data) + result.buffer = ncrutils.fromHex(data) proc init*(t: typedesc[Asn1Buffer]): Asn1Buffer = ## Initialize empty ``Asn1Buffer``. @@ -612,7 +613,7 @@ proc init*(t: typedesc[Asn1Composite], idx: int): Asn1Composite = proc `$`*(buffer: Asn1Buffer): string = ## Return string representation of ``buffer``. - result = toHex(buffer.toOpenArray()) + result = ncrutils.toHex(buffer.toOpenArray()) proc `$`*(field: Asn1Field): string = ## Return string representation of ``field``. @@ -621,7 +622,7 @@ proc `$`*(field: Asn1Field): string = result.add("]") if field.kind == Asn1Tag.NoSupport: result.add(" ") - result.add(toHex(field.toOpenArray())) + result.add(ncrutils.toHex(field.toOpenArray())) elif field.kind == Asn1Tag.Boolean: result.add(" ") result.add($field.vbool) @@ -630,24 +631,24 @@ proc `$`*(field: Asn1Field): string = if field.length <= 8: result.add($field.vint) else: - result.add(toHex(field.toOpenArray())) + result.add(ncrutils.toHex(field.toOpenArray())) elif field.kind == Asn1Tag.BitString: result.add(" ") result.add("(") result.add($field.ubits) result.add(" bits) ") - result.add(toHex(field.toOpenArray())) + result.add(ncrutils.toHex(field.toOpenArray())) elif field.kind == Asn1Tag.OctetString: result.add(" ") - result.add(toHex(field.toOpenArray())) + result.add(ncrutils.toHex(field.toOpenArray())) elif field.kind == Asn1Tag.Null: result.add(" NULL") elif field.kind == Asn1Tag.Oid: result.add(" ") - result.add(toHex(field.toOpenArray())) + result.add(ncrutils.toHex(field.toOpenArray())) elif field.kind == Asn1Tag.Sequence: result.add(" ") - result.add(toHex(field.toOpenArray())) + result.add(ncrutils.toHex(field.toOpenArray())) proc write*[T: Asn1Buffer|Asn1Composite](abc: var T, tag: Asn1Tag) = ## Write empty value to buffer or composite with ``tag``. diff --git a/libp2p/crypto/rsa.nim b/libp2p/crypto/rsa.nim index 835c9370a..6eee3c520 100644 --- a/libp2p/crypto/rsa.nim +++ b/libp2p/crypto/rsa.nim @@ -14,13 +14,13 @@ ## Copyright(C) 2018 Thomas Pornin . {.push raises: Defect.} - -import nimcrypto/utils import bearssl import minasn1 -export Asn1Error import stew/[results, ctops] -export results +# We use `ncrutils` for constant-time hexadecimal encoding/decoding procedures. +import nimcrypto/utils as ncrutils + +export Asn1Error, results const DefaultPublicExponent* = 65537'u32 @@ -574,14 +574,16 @@ proc init*(sig: var RsaSignature, data: openarray[byte]): Result[void, Asn1Error else: err(Asn1Error.Incorrect) -proc init*[T: RsaPKI](sospk: var T, data: string): Result[void, Asn1Error] {.inline.} = +proc init*[T: RsaPKI](sospk: var T, + data: string): Result[void, Asn1Error] {.inline.} = ## Initialize EC `private key`, `public key` or `scalar` ``sospk`` from ## hexadecimal string representation ``data``. ## ## Procedure returns ``Result[void, Asn1Status]``. - sospk.init(fromHex(data)) + sospk.init(ncrutils.fromHex(data)) -proc init*(t: typedesc[RsaPrivateKey], data: openarray[byte]): RsaResult[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. var res: RsaPrivateKey @@ -590,7 +592,8 @@ proc init*(t: typedesc[RsaPrivateKey], data: openarray[byte]): RsaResult[RsaPriv else: ok(res) -proc init*(t: typedesc[RsaPublicKey], data: openarray[byte]): RsaResult[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. var res: RsaPublicKey @@ -599,7 +602,8 @@ proc init*(t: typedesc[RsaPublicKey], data: openarray[byte]): RsaResult[RsaPubli else: ok(res) -proc init*(t: typedesc[RsaSignature], data: openarray[byte]): RsaResult[RsaSignature] = +proc init*(t: typedesc[RsaSignature], + data: openarray[byte]): RsaResult[RsaSignature] = ## Initialize RSA signature from raw binary representation ``data`` and ## return constructed object. var res: RsaSignature @@ -611,7 +615,7 @@ proc init*(t: typedesc[RsaSignature], data: openarray[byte]): RsaResult[RsaSigna proc init*[T: RsaPKI](t: typedesc[T], data: string): T {.inline.} = ## Initialize RSA `private key`, `public key` or `signature` from hexadecimal ## string representation ``data`` and return constructed object. - result = t.init(fromHex(data)) + result = t.init(ncrutils.fromHex(data)) proc `$`*(key: RsaPrivateKey): string = ## Return string representation of RSA private key. @@ -622,21 +626,24 @@ proc `$`*(key: RsaPrivateKey): string = result.add($key.seck.nBitlen) result.add(" bits)\n") result.add("p = ") - result.add(toHex(getArray(key.buffer, key.seck.p, key.seck.plen))) + result.add(ncrutils.toHex(getArray(key.buffer, key.seck.p, key.seck.plen))) result.add("\nq = ") - result.add(toHex(getArray(key.buffer, key.seck.q, key.seck.qlen))) + result.add(ncrutils.toHex(getArray(key.buffer, key.seck.q, key.seck.qlen))) result.add("\ndp = ") - result.add(toHex(getArray(key.buffer, key.seck.dp, key.seck.dplen))) + result.add(ncrutils.toHex(getArray(key.buffer, key.seck.dp, + key.seck.dplen))) result.add("\ndq = ") - result.add(toHex(getArray(key.buffer, key.seck.dq, key.seck.dqlen))) + result.add(ncrutils.toHex(getArray(key.buffer, key.seck.dq, + key.seck.dqlen))) result.add("\niq = ") - result.add(toHex(getArray(key.buffer, key.seck.iq, key.seck.iqlen))) + result.add(ncrutils.toHex(getArray(key.buffer, key.seck.iq, + key.seck.iqlen))) result.add("\npre = ") - result.add(toHex(getArray(key.buffer, key.pexp, key.pexplen))) + result.add(ncrutils.toHex(getArray(key.buffer, key.pexp, key.pexplen))) result.add("\nm = ") - result.add(toHex(getArray(key.buffer, key.pubk.n, key.pubk.nlen))) + result.add(ncrutils.toHex(getArray(key.buffer, key.pubk.n, key.pubk.nlen))) result.add("\npue = ") - result.add(toHex(getArray(key.buffer, key.pubk.e, key.pubk.elen))) + result.add(ncrutils.toHex(getArray(key.buffer, key.pubk.e, key.pubk.elen))) result.add("\n") proc `$`*(key: RsaPublicKey): string = @@ -648,9 +655,9 @@ proc `$`*(key: RsaPublicKey): string = result = "RSA key (" result.add($nbitlen) result.add(" bits)\nn = ") - result.add(toHex(getArray(key.buffer, key.key.n, key.key.nlen))) + result.add(ncrutils.toHex(getArray(key.buffer, key.key.n, key.key.nlen))) result.add("\ne = ") - result.add(toHex(getArray(key.buffer, key.key.e, key.key.elen))) + result.add(ncrutils.toHex(getArray(key.buffer, key.key.e, key.key.elen))) result.add("\n") proc `$`*(sig: RsaSignature): string = @@ -659,7 +666,7 @@ proc `$`*(sig: RsaSignature): string = result = "Empty or uninitialized RSA signature" else: result = "RSA signature (" - result.add(toHex(sig.buffer)) + result.add(ncrutils.toHex(sig.buffer)) result.add(")") proc `==`*(a, b: RsaPrivateKey): bool =