A Nim wrapper around the micro-ecc C library, providing Elliptic Curve Cryptography (ECC) primitives including ECDSA signing/verification and ECDH shared secret generation.
Copyright (c) 2026 Christian Zietz <czietz@gmx.net>
Licensed under the MIT license.
Types
CurveType = enum Curve_secp160r1, Curve_secp192r1, Curve_secp224r1, Curve_secp256r1, Curve_secp256k1
- Supported curves
ECCError = object of CatchableError
- Exception raised by this library
ECDSASignature = seq[char]
- Represents a ECDSA signature
ECKeyPair = tuple[public: ECPublicKey, private: ECPrivateKey]
- Represents a key pair
ECPrivateKey = object
- Represents a private key
ECPublicKey = object
- Represents a public key
rngFunction = proc (dest: ptr UncheckedArray[char]; size: cuint): cuint {.cdecl.}
Procs
proc `=destroy`(P: var ECPrivateKey) {....raises: [], tags: [RootEffect], forbids: [].}
proc ecDsaHashAndSign(P: ECPrivateKey; message: openArray[char]; hasher = Sha_256): ECDSASignature {....raises: [ECCError], tags: [], forbids: [].}
- Hashes a message with the given hasher, then signs the hash with the given private key, returning the signature.
proc ecDsaHashAndVerify(P: ECPublicKey; message: openArray[char]; signature: ECDSASignature; hasher = Sha_256): bool {. ...raises: [ECCError], tags: [], forbids: [].}
-
Hashes a message with the given hasher, then verifies the hash and signature versus the given public key.
Returns true if the signature is valid.
proc ecDsaSign(P: ECPrivateKey; messageHash: openArray[char]): ECDSASignature {. ...raises: [ECCError], tags: [], forbids: [].}
-
Signs a message hash with the given private key, returning the signature.
Note: According to the standard, the hash is truncated if it is longer than the curve length.
proc ecDsaVerify(P: ECPublicKey; messageHash: openArray[char]; signature: ECDSASignature): bool {....raises: [ECCError], tags: [], forbids: [].}
-
Verifies a message hash and signature versus the given public key
Returns true if the signature is valid.
proc getCurve(P: ECPrivateKey): Curve {....raises: [], tags: [], forbids: [].}
- Returns the Curve the key is on
proc getCurve(P: ECPublicKey): Curve {....raises: [], tags: [], forbids: [].}
- Returns the Curve the key is on
proc getCurveSize(C: Curve): int {....raises: [], tags: [], forbids: [].}
- Returns the curve order / 8 ("length" of the curve in bytes)
proc getCurveType(C: Curve): CurveType {....raises: [], tags: [], forbids: [].}
- Returns the CurveType
proc getPrivateKeySize(C: Curve): int {....raises: [], tags: [], forbids: [].}
- Returns the length in bytes of the private key
proc getPublicKey(P: ECPrivateKey): ECPublicKey {....raises: [ECCError], tags: [], forbids: [].}
- Computes the public key for a given private key
proc getPublicKeySize(C: Curve; compressed = false): int {....raises: [], tags: [], forbids: [].}
- Returns the length in bytes of the public key (uncompressed or compressed)
proc getSignatureSize(C: Curve): int {....raises: [], tags: [], forbids: [].}
- Returns the length in bytes of a ECDSA signature
proc hmacSha256(key: openArray[char]; message: openArray[char]): ShaDigest_256 {. ...raises: [], tags: [], forbids: [].}
-
HMAC SHA-256 (hash-based message authentication code)
Generates the HMAC SHA-256 with a given key and message.
proc loadPrivateKey(C: Curve; bytes: openArray[char]): ECPrivateKey {. ...raises: [ECCError], tags: [], forbids: [].}
- Imports a private key
proc loadPublicKey(C: Curve; bytes: openArray[char]; compressed = false): ECPublicKey {. ...raises: [ECCError], tags: [], forbids: [].}
-
Imports a public key
When compressed is set, compressed SEC1 v2 format is expected. Otherwise guess the key format based on the input length:
- Compressed SEC1 v2 format (as returned by toBytes)
- Uncompressed raw format (as returned by toBytes)
- Uncompressed SEC1 v2 format (as returned by toBytesSec1)
If the key is invalid (wrong length, not on the curve), an ECCError is raised. Thus, this function may be used with untrusted input.
proc makeKeyPair(C: Curve): ECKeyPair {....raises: [ECCError], tags: [], forbids: [].}
- Generates a pair of public and private key
proc toBytes(P: ECPrivateKey): seq[char] {....raises: [], tags: [], forbids: [].}
- Exports a private key for storage
proc toBytes(P: ECPublicKey; compressed = false): seq[char] {....raises: [], tags: [], forbids: [].}
-
Exports a public key for storage, optionally in compressed format
Compressed keys are represented in SEC1 v2 format, whereas uncompressed keys are just the point coordinates. (See toBytesSec1 for export in SEC1 v2 compliant uncompressed format.)
proc toBytesSec1(P: ECPublicKey): seq[char] {....raises: [], tags: [], forbids: [].}
- Exports a public key for storage, in SEC1-v2-compliant uncompressed format
proc useCustomRNG(RNG_func: rngFunction) {....raises: [], tags: [], forbids: [].}
-
Use custom random number generator (RNG)
By default, micro-ecc uses the system's secure random generator. This is the recommended mode of operation. However, on systems where micro-ecc fails to find a secure random generator, you can provide your own RNG. This RNG must be cryptographically secure, otherwise keys and signatures will be weak!
The function signature of the RNG is:
proc (dest: ptr UncheckedArray[char], size: cuint): cuint {.cdecl.}
The RNG must fill in size chars into the array dest and return 1. It can also return 0 to signal that the random generation failed.
proc useWeakInternalRNG(seed: int64) {....deprecated: "this RNG is not cryptographically secure", raises: [], tags: [], forbids: [].}
-
Use Nim's internal random number generator (RNG)
This not cryptographically secure and should only be used for testing! In particular, keys and signatures generated while using this RNG are weak.
Note: By default, micro-ecc uses the system's secure random generator. This is the recommended mode of operation.
proc zeroSequence(s: string) {....raises: [], tags: [], forbids: [].}
- Zeroes the contents of a string
proc zeroSequence[T](s: openArray[T])
- Zeroes the contents of a sequence