5.5 KiB
crypto-utils
Purpose
@suaveplan/crypto-utils is the cross-package crypto-helper layer for the Suaveplan monorepo. It owns the pure-composition utilities every primitive package builds on: hex / base64 / base64url / base58 encoding (delegated to @suaveplan/bytes where overlap exists), byte helpers (concatBytes, i2osp, os2ip, xor), constant-time equality, cryptographically-secure randomBytes, eager zeroize, the PrimitiveId registry + PrimitiveNotImplemented error, and the KAT / differential-fuzz test harness consumed by every @suaveplan/crypto-* engine selector. The package is deliberately field-arithmetic-free and side-channel-clean (no secret-data branches beyond constant-time compare) so it can ship as the universal-tier dependency for crypto-cipher, crypto-curve, crypto-hash, and the higher-level crypto package.
Requirements
Requirement: Pure-composition utility surface
@suaveplan/crypto-utils SHALL expose encoding, byte, constant-time, and test-harness utilities that are safe to author from scratch (no field arithmetic, no secret-data side channels beyond constant-time equality).
Scenario: Encoding utilities available
- WHEN a consumer imports from
@suaveplan/crypto-utils - THEN
hex,base64,base64url,base58encoders/decoders are exported, each withencode(bytes): stringanddecode(text): Uint8Array - AND
toHex/fromHexandtoBase64/fromBase64delegate to@suaveplan/bytes; decoders throwBytesError(aSuaveplanErrorsubclass) on malformed input - AND
toBase64Url/fromBase64Urlare implemented in-package by post-processing the standard base64 result
Requirement: Encoding delegation to @suaveplan/bytes
@suaveplan/crypto-utils SHALL delegate toHex / fromHex and toBase64 / fromBase64 to @suaveplan/bytes, and concatBytes to concatUint8Arrays from @suaveplan/bytes. The exported function names are preserved so downstream callers need no import changes.
Scenario: Hex delegates to bytes
- WHEN
toHexorfromHexis called - THEN the call is forwarded to
bytesToHex/hexToBytesfrom@suaveplan/bytes - AND errors thrown are
BytesErrorinstances with codeBYTES.ENCODE.INVALID_HEX
Scenario: Standard base64 delegates to bytes
- WHEN
toBase64orfromBase64is called - THEN the call is forwarded to
bytesToBase64/base64ToBytesfrom@suaveplan/bytes - AND errors thrown are
BytesErrorinstances with codeBYTES.ENCODE.INVALID_BASE64
Scenario: concatBytes delegates to bytes
- WHEN
concatBytesis called - THEN the call is forwarded to
concatUint8Arraysfrom@suaveplan/bytes
Scenario: Byte utilities available
- WHEN a consumer imports from
@suaveplan/crypto-utils - THEN
concatBytes(...arrays: Uint8Array[]): Uint8Array,xor(a: Uint8Array, b: Uint8Array): Uint8Array,i2osp(n: bigint, len: number): Uint8Array,os2ip(bytes: Uint8Array): bigintare exported
Scenario: Constant-time, random, and zeroize utilities available
- WHEN a consumer imports from
@suaveplan/crypto-utils - THEN
constantTimeEqual(a: Uint8Array, b: Uint8Array): booleanis exported and implemented without early return - AND
randomBytes(n: number): Uint8Arrayis exported, sourcing fromglobalThis.crypto.getRandomValues - AND
zeroize(bytes: Uint8Array): voidis exported
Requirement: Test-vector and fuzz harness
@suaveplan/crypto-utils SHALL expose harness functions that crypto-hash, crypto-curve, and crypto-cipher use to run KATs and differential fuzz against their primitive impls.
Scenario: KAT harness
- WHEN a primitive test imports
runVectorsfrom@suaveplan/crypto-utils/testing - THEN it can pass a vector list and a set of impls, and receive a per-impl pass/fail/pending report
- AND pending impls (throwing
PrimitiveNotImplemented) are distinguished from failing impls
Scenario: Differential fuzz harness
- WHEN a primitive test imports
diffFuzzfrom@suaveplan/crypto-utils/testing - THEN it can pass two impls, an input generator, and an iteration count, and receive a mismatch report
- AND any byte-level divergence in outputs is reported with the reproducing input
Requirement: Primitive id registry
@suaveplan/crypto-utils SHALL export the PrimitiveId union type enumerating every hash, curve, and AEAD primitive across the crypto family, and a PRIMITIVE_IDS const array for runtime iteration.
Scenario: Registry available
- WHEN a consumer imports
PrimitiveIdandPRIMITIVE_IDSfrom@suaveplan/crypto-utils/primitive-id - THEN
PRIMITIVE_IDScontains every id supported bycrypto-hash,crypto-curve, andcrypto-cipher - AND
PrimitiveIdnarrows to the same union at compile time
Requirement: No vendored code
@suaveplan/crypto-utils SHALL contain only original code authored in this monorepo. No src/vendored/ directory.
Scenario: No vendored directory
- WHEN the package tree is inspected
- THEN no path matches
packages/universal/crypto-utils/src/vendored/**
Requirement: Merkle helpers
@suaveplan/crypto-utils SHALL expose Merkle tree construction and inclusion-proof helpers generic over any hash primitive from @suaveplan/crypto-hash.
Scenario: Merkle helpers available
- WHEN a consumer imports
merkleRootandmerkleProoffrom@suaveplan/crypto-utils/merkle - THEN they accept a hash function parameter and a list of leaves, returning a root and an inclusion proof respectively