Skip to content

Add input validation with descriptive errors to all five crypto functions #26

Description

@Just-Bamford

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

  • AnonVoteCryptoError class created and exported with static
    error code constants (e.g., INVALID_KEY, INVALID_PAYLOAD)
  • All five functions validate inputs before any crypto operation
  • encryptVote and decryptVote throw with a message that
    includes the expected key format
  • decryptVote validates all three EncryptedPayload fields
    are present and non-empty hex strings
  • Consumers can catch specific errors programmatically using
    error codes, not message parsing
  • Unit tests cover all invalid input paths for all five functions
  • Valid inputs still produce correct outputs — no regression

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.

Metadata

Metadata

Assignees

Labels

GrantFox OSSIssue tracked in GrantFox OSSMaybe RewardedIssue may be eligible for a GrantFox rewardOfficial Campaign | FWC26Campaign: Official Campaign | FWC26enhancementNew feature or request

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions