Submission for the Ottawa Defence Hackathon "Cryptographic Provenance" challenge.
The system has two parts:
- Auto-graded verification backend —
POST /verifythat takes a product's attestation chain and returns its Canadian-content percentage, designation, validity, and detected integrity anomalies (the contract inprovenance-hackathon-main/TECHNICAL_GUIDE.md§9). - Demo UIs — a Next.js + Convex app (supplier issuing portal, public purchaser/field verification with QR lookup) used for the live presentation.
The verifier logic is one shared, stateless TypeScript core
(convex/lib/provenance/) exposed two ways:
- as a Convex HTTP endpoint (
/verifyon the Convex deployment URL), and - as a standalone Docker service on port 8000 (no Convex dependency).
| Concern | Implementation |
|---|---|
| Canonical serialization | Byte-exact port of reference_lib/canonical.py (canonical.ts) |
| Content hash | SHA-256 over canonical bytes, signature excluded |
| Signatures | Ed25519 verify vs the supplier's registered public key (@noble/ed25519) |
| Registries | Vendored supplier_public_keys.json + anchor_registry.json (registryData.ts) |
| Computation | Flat Canadian % + last substantial transformation + 51/98 designation (spec/computation.md) |
| Hard-rule anomalies | signature, anchor, parent-hash link, dangling/circular, unit, timestamp, mass balance, replay, implausible transformation, cost band |
| Statistical (t4) anomalies | timing / origin / labour outliers learned from the clean training corpus (stats.ts), only applied to otherwise-clean chains |
On the organizer's self_test.py over training_corpus.jsonl this scores
100.0%.
Most reviewers can run the default Docker stack. It starts the verifier, the Next.js app, and the ngrok demo tunnel, then prints the local and public endpoints:
docker compose up --buildThe Compose logs include an endpoint-info section. The verifier endpoint to
give the grader is:
http://localhost:8000/verify
The Next.js app is served at:
http://localhost:3001
The static public demo URL is also printed in the Docker logs and is online while Docker is running:
https://frog-inviting-teal.ngrok-free.app
https://frog-inviting-teal.ngrok-free.app/demo/qr
The manual full-test command is:
python3 provenance-hackathon-main/self_test.py http://localhost:8000/verifyQuick health check:
curl http://localhost:8000/healthThe same commands are also available as npm scripts:
npm run docker:up
npm run docker:verifier
npm run test:verifierThe tunnel uses the hardcoded static domain:
https://frog-inviting-teal.ngrok-free.app
The web container listens on port 3000 internally, but defaults to host port
3001 to avoid colliding with local next dev. To choose another host port:
WEB_PORT=3002 docker compose up --buildThe Docker web image bakes in the public Convex deployment values it needs to boot:
CONVEX_DEPLOYMENT=dev:kindly-sparrow-986
NEXT_PUBLIC_CONVEX_URL=https://kindly-sparrow-986.convex.cloud
NEXT_PUBLIC_CONVEX_SITE_URL=https://kindly-sparrow-986.convex.site
The tunnel still needs NGROK_AUTHTOKEN in .env.local; the token is not
committed or baked into the image.
npm install
npx tsx verifier/server.ts # POST /verify on http://localhost:8000/verifyThe same verifier is registered in convex/http.ts. With npm run dev (or a
deploy), it is served at:
POST https://<your-deployment>.convex.site/verify
This URL accepts the identical request/response contract and can be graded directly if the harness accepts a remote URL.
npx tsx verifier/parity.ts # golden vectors + worked example, byte-exactThis checks the canonical bytes, content hash, and Ed25519 signature against the
frozen golden vectors in reference_lib/tests/, and verifies the worked example
resolves to valid, 58.4%, made_in_canada.
npm run dev # Convex + Next.js, app at http://localhost:3000- Supplier portal:
/login,/register,/dashboard,/attestations/new - Public verification:
/verify,/verify/[slug] - QR presenter page:
/demo/qr
convex/
http.ts # POST /verify Convex HTTP route
lib/provenance/ # shared, stateless verifier core
canonical.ts # byte-exact canonical serialization
crypto.ts # content hash + Ed25519 verify
verify.ts # computation + anomaly detection
types.ts # wire types
registryData.ts # vendored supplier keys + anchor registry (generated)
stats.ts # clean-corpus priors for t4 detection (generated)
verifier/
server.ts # standalone POST /verify on :8000
parity.ts # golden-vector + worked-example checks
Dockerfile # self-contained verifier image
provenance-hackathon-main/ # organizer kit (specs, registries, training data) — read-only
Next.js (App Router), React, Convex, Tailwind CSS, TypeScript, @noble/ed25519
@noble/hashesfor spec-correct crypto, React Flow +qrcode.reactfor the demo UI.