4.8 KiB
Capability Spec Delta: crypto-hash (crypto-completion)
Package: @suaveplan/crypto-hash
Status: PROPOSED
Every requirement below carries a
**Verified by:**line at authoring time.
ADDED Requirements
Requirement: scrypt KDF primitive
The package SHALL expose scrypt(password, salt, options) from primitives/scrypt/scrypt.ts, where options carries N (CPU/memory cost, must be a power of two ≥ 2), r (block size), p (parallelisation), and dkLen (output length in bytes). The implementation SHALL match RFC 7914 byte-for-byte and SHALL use the @noble/hashes/scrypt::scryptAsync engine in the noble selector. Output is a Uint8Array of length dkLen.
Scenario: matches RFC 7914 known-answer test
- WHEN
scrypt("password", "NaCl", { N: 1024, r: 8, p: 16, dkLen: 64 })is called - THEN the output equals the RFC 7914 §11 KAT for those parameters byte-for-byte
Scenario: invalid N rejected
- WHEN
scrypt(pw, salt, { N: 1000, r: 8, p: 1, dkLen: 32 })is called (1000 is not a power of two) - THEN it throws
SuaveplanErrorwith codeCRYPTO_HASH.SCRYPT_INVALID_Nandcontext.N === 1000
Verified by: packages/crypto/crypto-hash/src/primitives/scrypt/scrypt.test.ts::"matches RFC 7914 known-answer test for N=1024 r=8 p=16" AND packages/crypto/crypto-hash/src/primitives/scrypt/scrypt.spec-conformance.test.ts::"throws SCRYPT_INVALID_N when N is not a power of two"
Requirement: blake2b hash primitive
The package SHALL expose blake2b(message, options) from primitives/blake2b/blake2b.ts, where options carries dkLen (1..64), optional key (≤ 64 bytes), optional salt (16 bytes), and optional personalization (16 bytes). The implementation SHALL match RFC 7693 byte-for-byte.
Scenario: matches RFC 7693 known-answer test
- WHEN
blake2b("abc", { dkLen: 64 })is called - THEN the output equals the RFC 7693 §B Appendix KAT for the input "abc" byte-for-byte
Scenario: dkLen > 64 rejected
- WHEN
blake2b(msg, { dkLen: 65 })is called - THEN it throws
SuaveplanErrorwith codeCRYPTO_HASH.BLAKE2B_OUTPUT_TOO_LONGandcontext.requestedLength === 65
Scenario: key longer than 64 bytes rejected
- WHEN
blake2b(msg, { dkLen: 32, key: 65-byte-buffer })is called - THEN it throws
SuaveplanErrorwith codeCRYPTO_HASH.BLAKE2B_KEY_TOO_LONGandcontext.keyLength === 65
Verified by: packages/crypto/crypto-hash/src/primitives/blake2b/blake2b.test.ts::"matches RFC 7693 known-answer test for input \"abc\"" AND packages/crypto/crypto-hash/src/primitives/blake2b/blake2b.spec-conformance.test.ts::"throws BLAKE2B_OUTPUT_TOO_LONG when dkLen exceeds 64" AND packages/crypto/crypto-hash/src/primitives/blake2b/blake2b.spec-conformance.test.ts::"throws BLAKE2B_KEY_TOO_LONG when key exceeds 64 bytes"
Requirement: blake2b password hashing and verification
The package SHALL expose hashPasswordBlake2b(password, options) returning a stored hash in the format $blake2b$v=1$cf=<costFactor>$<saltHex>$<hashHex>, where costFactor controls iteration count (default 14, doubling each level) and a 16-byte random salt is generated when not supplied. It SHALL also expose verifyPasswordBlake2b(storedHash, password) returning true when the password verifies and false otherwise. Comparison SHALL be constant-time over the hash bytes.
Scenario: hash and verify round-trip
- WHEN
hashPasswordBlake2b("correct horse battery staple")producesstoredandverifyPasswordBlake2b(stored, "correct horse battery staple")is called - THEN the result is
true
Scenario: wrong password verifies as false
- WHEN
verifyPasswordBlake2b(stored, "wrong password")is called - THEN the result is
false(no exception thrown)
Scenario: salt is fresh per call
- WHEN
hashPasswordBlake2b("same password")is called twice - THEN the two stored hashes are not byte-equal (different salts → different outputs)
Scenario: malformed stored hash rejected
- WHEN
verifyPasswordBlake2b("not-a-valid-format", pw)is called - THEN it throws
SuaveplanErrorwith codeCRYPTO_HASH.BLAKE2B_PASSWORD_FORMAT_INVALID
Verified by: packages/crypto/crypto-hash/src/mac/blake2b-password/blake2b-password.test.ts::"hash and verify round-trip with same password" AND packages/crypto/crypto-hash/src/mac/blake2b-password/blake2b-password.test.ts::"verify returns false for wrong password" AND packages/crypto/crypto-hash/src/mac/blake2b-password/blake2b-password.test.ts::"salt is fresh per call so identical inputs hash differently" AND packages/crypto/crypto-hash/src/mac/blake2b-password/blake2b-password.spec-conformance.test.ts::"throws BLAKE2B_PASSWORD_FORMAT_INVALID for malformed stored hash"