Summary
None of the five exported functions in src/crypto.ts validate their
inputs before operating on them. encryptVote accepts any string as
a key parameter but requires exactly a 64-character hex string
representing 32 bytes — passing a wrong-length key causes Node.js to
throw a generic Invalid key length error with no reference to which
function was called or what format the key should be. decryptVote
accepts any EncryptedPayload but if any field is not valid hex, it
throws a generic buffer parse error. hashIdentifier called with a
non-string input in a JavaScript consumer (TypeScript types do not
prevent this at runtime) will throw a generic type error.
These raw Node.js crypto errors are difficult to debug and give a
developer no guidance on how to fix their integration.
Scope
- Add input validation at the start of each function that throws a
descriptive AnonVoteCryptoError with a clear message before any
crypto operation runs
hashIdentifier — validate input is a string; throw if not
generateToken — no parameters, no validation needed
hashToken — validate input is a non-empty string; throw if not
encryptVote — validate option is a string; validate key is
exactly 64 hex characters; throw with message
"key must be a 64-character hex string (32 bytes)" if not
decryptVote — validate payload has ciphertext, iv, and
authTag fields; validate each is a non-empty hex string; validate
key is exactly 64 hex characters
- Create a custom
AnonVoteCryptoError class that extends Error
with a code field — export it from src/index.ts
- Define error code constants as static properties on the error class:
AnonVoteCryptoError.INVALID_IDENTIFIER, AnonVoteCryptoError.INVALID_KEY,
AnonVoteCryptoError.INVALID_PAYLOAD, etc. — this allows consumers
to catch specific errors programmatically with if (error.code === AnonVoteCryptoError.INVALID_KEY)
instead of parsing error messages
- Add unit tests for each validation path — one test per invalid
input scenario, confirming the error message and code are correct
Relevant Files
src/crypto.ts
src/types.ts
src/index.ts
tests/crypto.test.ts
Acceptance Criteria
Out of Scope
- Changing function signatures
- Runtime type narrowing beyond what is needed for validation
Note for Contributors
The error messages must be actionable — a developer reading them should
know exactly what to fix. "Invalid key" is not acceptable.
"key must be a 64-character hex string — received 32 characters" is.
Summary
None of the five exported functions in
src/crypto.tsvalidate theirinputs before operating on them.
encryptVoteaccepts any string asa
keyparameter but requires exactly a 64-character hex stringrepresenting 32 bytes — passing a wrong-length key causes Node.js to
throw a generic
Invalid key lengtherror with no reference to whichfunction was called or what format the key should be.
decryptVoteaccepts any
EncryptedPayloadbut if any field is not valid hex, itthrows a generic buffer parse error.
hashIdentifiercalled with anon-string input in a JavaScript consumer (TypeScript types do not
prevent this at runtime) will throw a generic type error.
These raw Node.js crypto errors are difficult to debug and give a
developer no guidance on how to fix their integration.
Scope
descriptive
AnonVoteCryptoErrorwith a clear message before anycrypto operation runs
hashIdentifier— validate input is a string; throw if notgenerateToken— no parameters, no validation neededhashToken— validate input is a non-empty string; throw if notencryptVote— validateoptionis a string; validatekeyisexactly 64 hex characters; throw with message
"key must be a 64-character hex string (32 bytes)"if notdecryptVote— validatepayloadhasciphertext,iv, andauthTagfields; validate each is a non-empty hex string; validatekeyis exactly 64 hex charactersAnonVoteCryptoErrorclass that extendsErrorwith a
codefield — export it fromsrc/index.tsAnonVoteCryptoError.INVALID_IDENTIFIER,AnonVoteCryptoError.INVALID_KEY,AnonVoteCryptoError.INVALID_PAYLOAD, etc. — this allows consumersto catch specific errors programmatically with
if (error.code === AnonVoteCryptoError.INVALID_KEY)instead of parsing error messages
input scenario, confirming the error message and code are correct
Relevant Files
src/crypto.tssrc/types.tssrc/index.tstests/crypto.test.tsAcceptance Criteria
AnonVoteCryptoErrorclass created and exported with staticerror code constants (e.g., INVALID_KEY, INVALID_PAYLOAD)
encryptVoteanddecryptVotethrow with a message thatincludes the expected key format
decryptVotevalidates all threeEncryptedPayloadfieldsare present and non-empty hex strings
error codes, not message parsing
Out of Scope
Note for Contributors
The error messages must be actionable — a developer reading them should
know exactly what to fix.
"Invalid key"is not acceptable."key must be a 64-character hex string — received 32 characters"is.