Skip to content

Shared Cryptographic Logic

Context

To achieve 100% cryptographic parity between the NestJS Backend and Next.js Frontend, we need a shared source of truth for SHA3-512 hashing and Merkle Tree logic. While a separate package offers isolation, it adds significant complexity to the build pipeline and dependency management. We need a secure solution that follows the KISS principle: maximum security with minimum moving parts.

Comparison (Code Sharing Strategies)

StrategySeparate PackagePath Mapping (Source Sharing)
ComplexityHigh (Build scripts, package.json)Low (Direct TS Import)
SecurityHigh (Isolated)High (Identical Logic)
AuditabilityMedium (Needs build review)Excellent (Raw Source Review)
Developer DXMedium (Symlink issues)High (Instant Feedback)

Decision

We will use TypeScript Path Mapping to share a raw source directory located at /packages/core-crypto. This directory will contain pure logic and types, shared directly between apps without a dedicated build step or package.json.

Rationale

  1. Direct Integrity: By importing the exact same .ts files, we eliminate any risk of "Version Drift" or build-time discrepancies. $SHA3_{backend}(x) \equiv SHA3_{frontend}(x)$ is guaranteed at the source level.
  2. KISS Principle: No npm link, no workspace publishing, and no complex tsconfig inheritance. It's just a folder that both applications treat as their own.
  3. Audit-Friendly: A security auditor only needs to inspect a single folder of raw TypeScript files to understand the entire trust model of the application.
  4. Performance: Next.js (via Turbopack) and NestJS (via SWC/TS-Node) will compile the shared code using their own optimized pipelines, ensuring the best performance for their respective runtimes.

Security Constraints

To prevent the shared folder from becoming a security liability, the following rules are strictly enforced:

  • Leaf Node Only: The core-crypto folder cannot import anything from the rest of the monorepo. It is a "provider," never a "consumer."
  • Pure Functions: Only deterministic, side-effect-free functions are allowed.
  • Primitive Types: Only platform-agnostic types (like Uint8Array and string) are used to ensure compatibility between Node.js and the Browser's V8.
  • Dependency Restriction: The only allowed external dependency is @noble/hashes (audited/zero-dependency).