zena:crypto

zena
import {…} from 'zena:crypto';

Cryptography: SHA-256, HMAC-SHA256, HKDF-SHA256, and ECDSA on P-256 and secp256k1. Pure Zena.

zena
import {hmacSha256, p256, sha256Hex} from 'zena:crypto';

let digest = sha256Hex(bytes);
let mac = hmacSha256(key, message);
let signature = p256.sign(privateKey, message);

Classes

HkdfError

zena
class HkdfError extends Error
Extends Error
Re-exported from zena:crypto/hmac.zena

An HKDF output length outside what RFC 5869 allows.

Constructors
zena
new(message: String)
#
2 inherited members
From Error
Properties
zena
message: String
#
Methods
zena
getStackTrace(): String | null
#

EcdsaError

zena
class EcdsaError extends Error
Extends Error
Re-exported from zena:crypto/ecdsa.zena

A private key out of range, a malformed public key, or a digest that is not 32 bytes.

Constructors
zena
new(message: String)
#
2 inherited members
From Error
Properties
zena
message: String
#
Methods
zena
getStackTrace(): String | null
#

EcdsaCurve

zena
final class EcdsaCurve
Re-exported from zena:crypto/ecdsa.zena

A curve to sign and verify on: p256 or secp256k1.

Constructors
zena
new(curve: Curve)
#
Properties
zena
name: String { get; }
#

P-256 or secp256k1.

Methods
zena
publicKey(privateKey: FixedArray<u8>, compressed: boolean = true): FixedArray<u8>
#

The SEC1 encoding of the public key for privateKey. Throws an EcdsaError when the private key is not 32 bytes or not from 1 to n - 1, as sign does.

zena
compressPublicKey(key: FixedArray<u8>): FixedArray<u8>
#

The 33-byte compressed form of a SEC1 public key in either form. Throws an EcdsaError when key is malformed or not on the curve.

zena
decompressPublicKey(key: FixedArray<u8>): FixedArray<u8>
#

The 65-byte uncompressed form of a SEC1 public key, as compressPublicKey takes it.

zena
sign(privateKey: FixedArray<u8>, message: FixedArray<u8>): FixedArray<u8>
#

The low-S signature of the SHA-256 hash of message.

zena
signDigest(privateKey: FixedArray<u8>, digest: FixedArray<u8>): FixedArray<u8>
#

The low-S signature of a 32-byte SHA-256 digest, with the nonce derived from the key and the digest as RFC 6979 section 3.2 describes.

zena
signatureFromDer(der: FixedArray<u8>): FixedArray<u8>
#

The 64-byte low-S signature an ASN.1 DER ECDSA-Sig-Value holds: SEQUENCE { r INTEGER, s INTEGER }, as X.509, PKCS #11 and key management services such as Cloud KMS write signatures. A high-S signature, which they may give, is turned into its low-S twin, which signs the same message. Throws an EcdsaError for anything else, or an r or s that is 0 or not below the group order.

zena
verify(key: FixedArray<u8>, message: FixedArray<u8>, signature: FixedArray<u8>, allowHighS: boolean = false): boolean
#

Whether signature is a valid signature of the SHA-256 hash of message under the SEC1 public key key. False for a malformed signature or key, a key not on the curve, and, unless allowHighS, a high-S signature.

zena
verifyDigest(key: FixedArray<u8>, digest: FixedArray<u8>, signature: FixedArray<u8>, allowHighS: boolean = false): boolean
#

verify for a SHA-256 digest of the message. Throws an EcdsaError when digest is not 32 bytes.

Functions

sha256

zena
function sha256(data: FixedArray<u8>): FixedArray<u8>
Re-exported from zena:crypto/sha256.zena

The 32-byte SHA-256 digest of data.

toHex

zena
function toHex(bytes: FixedArray<u8>): String
Re-exported from zena:crypto/sha256.zena

bytes as lowercase hex; the same as hex.encode from zena:encoding.

sha256Hex

zena
function sha256Hex(data: FixedArray<u8>): String
Re-exported from zena:crypto/sha256.zena

The digest as a lowercase hex string.

sha256HexOfString

zena
function sha256HexOfString(s: String): String
Re-exported from zena:crypto/sha256.zena

The digest of a string's bytes as a lowercase hex string.

hmacSha256

zena
function hmacSha256(key: FixedArray<u8>, message: FixedArray<u8>): FixedArray<u8>
Re-exported from zena:crypto/hmac.zena

The HMAC-SHA256 of message under key.

constantTimeEquals

zena
function constantTimeEquals(a: FixedArray<u8>, b: FixedArray<u8>): boolean
Re-exported from zena:crypto/hmac.zena

Whether a and b hold the same bytes, taking as long whichever byte differs, so that comparing a MAC or a secret's hash with the expected one does not show, by its timing, how much of it was right. Only the lengths, which are not secret, end it early.

hkdfExtract

zena
function hkdfExtract(salt: FixedArray<u8>, ikm: FixedArray<u8>): FixedArray<u8>
Re-exported from zena:crypto/hmac.zena

HKDF's extract step: a 32-byte pseudorandom key from input keying material and an optional salt. RFC 5869 says an empty salt stands for 32 zero bytes; HMAC pads its key with zeros to a block either way, so passing the empty salt through gives the same result.

hkdfExpand

zena
function hkdfExpand(prk: FixedArray<u8>, info: FixedArray<u8>, length: i32): FixedArray<u8>
Re-exported from zena:crypto/hmac.zena

HKDF's expand step: length bytes from a pseudorandom key and context info. length is at most 255 * 32 bytes.

hkdf

zena
function hkdf(salt: FixedArray<u8>, ikm: FixedArray<u8>, info: FixedArray<u8>, length: i32): FixedArray<u8>
Re-exported from zena:crypto/hmac.zena

HKDF-SHA256: extract, then expand to length bytes.

Variables

p256

zena
let p256: EcdsaCurve
Re-exported from zena:crypto/ecdsa.zena

NIST P-256, also called secp256r1 and prime256v1.

secp256k1

zena
let secp256k1: EcdsaCurve
Re-exported from zena:crypto/ecdsa.zena

secp256k1, the curve Bitcoin uses.