Implement Falcon-512 verifier: hint + direct variants, on-chain BLAKE2s hash-to-point#2
Merged
Merged
Conversation
…oint) Replaces the falcon_512 stub with two working, measured Falcon-512 (FN-DSA) verifiers sharing an NTT-domain public key and an on-chain BLAKE2s hash-to-point: hint-based (2 forward NTTs, 60-felt signature) and direct (INTT(NTT(s1) . h_ntt), 31-felt signature, no hint). Both fit the Starknet validation caps at ~76.2M L2 gas / ~669k steps. Validated by a genuine falcon.py-signed fixture (accepted) plus tamper rejection tests; NTT root tables verified from first principles against tprest/falcon.py. Packed inputs are validated canonical on unpack. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Replaces the
falcon_512stub with a real, working Falcon-512 (FN-DSA) verifier — in two registered variants — with the message hashed to a point on-chain via BLAKE2s.Builds directly on the findings of #1 (direct-NTT measurement, honest over-budget reporting): the key change here is storing the public key in the NTT domain, which removes the
NTT(h)transform that put the direct method over budget there, plus an on-chain hash-to-point so the signature is bound tomessage_hash.What
Two schemes in
schemes.json, sharing one crate, one 29-felt NTT-domain public key, and one fixture:falcon_512(hint)mul_hint = s1*hfalcon_512_directs1*h = INTT(NTT(s1) ∘ h_ntt), no hintThe variants cost the same (each needs exactly two 512-point transforms with an NTT-domain key), so the direct variant dominates: half the signature calldata and no signer-supplied hint in the trust surface.
hash_to_point(src/hash_to_point.cairo): the spec's rejection sampling with the XOF instantiated as BLAKE2s in counter mode (core::blakebuiltin) instead of SHAKE-256 — NON-standard, labeled as such everywhere; the profiler shows it is cost-noise next to the NTTs (~80% of steps). Computed on-chain soverifyactually usesmessage_hash(an off-chainmsg_pointcarried in the signature admits(s1, msg_point = s1*h + small)forgeries for arbitrary messages — reasoning recorded inPORTING.md).src/ntt.cairo,src/ntt_constants.cairo,src/zq.cairo): ported from s2morrow (StarkWare, MIT; SPDX headers preserved), ~33M gas per transform. Root tables verified from first principles byscripts/verify_ntt_constants.py(inverse pairing, root-chain, bijection, and an exact cross-check against tprest/falcon.py that pins the interop convention).src/packing.cairo): s2morrow's base-Q layout with the canonical-encoding check the reference lacked — accepted felts are in bijection with coefficient vectors in[0, Q)^512.Correctness gate
scripts/gen_falcon_fixture.pygenerates a genuine signature (tprest/falcon.py NTRU keygen + ffSampling sampler, BLAKE2s hash-to-point, norm 27,616,781 vs bound 34,034,726) and re-checks the full verification equation independently in Python before emittingsrc/bench_fixture.cairo.bench_verify_falcon_512/bench_verify_falcon_512_directaccept it; tampered s1 (canonical swap and non-canonical encoding), hint, salt, public key, message, and input lengths are all rejected in tests.make allregeneratesresults/(committed).Caveats
msg_pointbinding issue above.__validate__scenario (account mock inbench_targets) is future work, as is NTT optimization (~80% of cost).🤖 Generated with Claude Code