Crypto wave 2: BLS12-381 signature scheme + field-multiply HW#83
Merged
Conversation
goldilocksMulHW — multiply mod the Goldilocks prime 2^64-2^32+1 (the STARK field), as a multi-cycle circuit do FSM. Behavioural test checks cycle-by-cycle against the pure-data Goldilocks.mul; SynthesisChecks section emits #synthesizeVerilog. 64-bit field, the cheapest of the four field-mul HW modules in this wave.
secp256k1MulHW — multiply mod the secp256k1 field prime 2^256-2^32-977 (Bitcoin/Ethereum curve), multi-cycle circuit do. Behavioural check vs pure-data Secp256k1Field.mul + #synthesizeVerilog.
p256MulHW — multiply mod the NIST P-256 field prime, multi-cycle circuit do. Behavioural check vs pure-data P256Field.mul + #synthesizeVerilog.
ed25519FieldMulHW — multiply mod 2^255-19, the HW follow-up the
Ed25519Field.lean docstring promised ("the HW engine ... follows
in L.2.b"). Multi-cycle circuit do; behavioural check vs the
pure-data Ed25519Field.mul + #synthesizeVerilog.
BLS signatures on the BLS12-381 pairing-friendly curve — the curve
Ethereum 2.0 consensus (validator aggregate signatures), zk-rollup
proof verification, and threshold-signature schemes are built on.
Sparkle had no BLS / pairing IP before this.
Pure-data (Nat/BitVec, no Signal) reference, layered like the
existing Ed25519 tower:
Fp — prime field mod the 381-bit BLS12-381 base prime
Fp2 — Fp[u]/(u²+1)
Fp6 — Fp2[v]/(v³-ξ), ξ = u+1
Fp12 — Fp6[w]/(w²-v) (the pairing target group GT)
G1 — E(Fp): y² = x³ + 4
G2 — E'(Fp2): y² = x³ + 4(u+1) (the twist)
Pairing — optimal ate: Miller loop + final exponentiation,
transcribed line-for-line from Ethereum's py_ecc
reference (loop parameter, linefunc, final exp).
sign / verify / aggregate / verifyAggregate
The test (`bls12381-test`) checks: Fp12 pairing bilinearity +
non-degeneracy, sign→verify round-trip PASSES, tampered signature
FAILS, and a 3-signature aggregate over one message verifies.
Scope notes (documented in-file):
- **hash-to-curve is a SIMPLE deterministic placeholder**, not the
full RFC 9380 `hash_to_curve` suite — enough for the
sign/verify/aggregate self-consistency the test exercises, but
NOT interoperable with real Ethereum signatures. Marked clearly
so nobody mistakes it for a production H2C.
- **No HW module for the pairing** — 381-bit modmul + a Miller loop
on an FPGA is a research project, explicitly out of scope. BLS's
value here is the machine-checkable reference + IP-catalog
presence; the tractable HW unit (field multiply) ships separately
in this wave for the smaller curves.
lakefile.lean: 5 new lean_exe stanzas (bls12381-test,
{goldilocks,secp256k1,p256,ed25519}-mul-hw-test), each
supportInterpreter := true, pointed at Tests/Drivers/*Main.lean.
Tests/AllTests.lean: 5 new imports + .main calls in the release-gate
runner. ip-tests.yml crypto/crypto-hw groups already cover the
Crypto dir; the new exes ride along there.
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.
Summary
Wave 2 of the Crypto HW/reference build-out (wave 1 = AES/Keccak/SHA-512/HKDF/RLP/Merkle HW, PR #80). Adds the BLS12-381 signature scheme (pure-data reference — the load-bearing addition) plus field-multiply HW for four curves.
Deliverable A — BLS12-381 (primary)
IP/Crypto/BLS12_381.lean(~640 LOC). BLS signatures on theBLS12-381 pairing-friendly curve — the curve Ethereum 2.0 consensus
(validator aggregate signatures), zk-rollup proof verification, and
threshold-signature schemes are built on. Sparkle had no BLS /
pairing IP before this.
Full tower, layered like the existing Ed25519 tower:
optimized_bls12_381(pseudo-binary loop encoding, D-type untwistψ(x,y)=(x·w⁻², y·w⁻³), homogeneous-projective
linefuncwithnum/den accumulation, full
(p¹²−1)/rfinal exp). Verifiedbilinear + non-degenerate — the property that makes
sign/verify work.
expand_message_xmd(SHA-256) feeding a documented SIMPLEplaceholder
hashToG2(scalar·generator), NOT the SSWU suite —so it is intentionally not blst/eth2-KAT interoperable. Clearly
marked so nobody mistakes it for production H2C.
bls12381-test): Fp12 pairing bilinearity +non-degeneracy, sign→verify PASSES, tampered-sig /
wrong-message / wrong-keyset REJECTED, 3-sig aggregate
verifies. Self-consistency (documented), not third-party KAT.
loop on an FPGA is a research project. BLS's value here is the
machine-checkable reference + IP-catalog presence.
Deliverable B — field-multiply HW (4 curves)
Bit-serial double-and-add modular multiply (MSB-first, per-bit
conditional-subtract reduction), each a
circuit doFSM + simcross-check vs the pure-data
mul+#synthesizeVerilog:GoldilocksHW.leangoldilocks-mul-hw-test✅Secp256k1FieldHW.leansecp256k1-mul-hw-test✅P256FieldHW.leanp256-mul-hw-test✅Ed25519FieldHW.leaned25519-mul-hw-test✅Ed25519's HW is the follow-up its own docstring promised ("the HW
engine … follows in L.2.b"). All four share one verified generic
shift-add mod-p skeleton (not Solinas/field-specific fast reduction —
that's a follow-up); each matches
(a·b) mod pexactly.Punted (as scoped): RSA-PSS HW (2048-bit modexp), point-op /
scalar-mul HW, pairing HW.
Verification (local)
lake buildclean — all#synthesizeVerilogcompile.bls12381-test,{goldilocks,secp256k1,p256,ed25519}-mul-hw-test.lake exe test: 13/13 lspec.#synthesizeVeriloginvocations (3 per field HW).New Sparkle-side limitation found
A
@[reducible, inline]helper wrapping aSignal.muxover an<*>-built comparison fails synth ("Cannot instantiate Seq.seq")though it sim-passes — the conditional-subtract must be inlined
directly into the
circuit dobody. Also: useBitVec.ule(not<=) andBitVec.append (0#k) v(not.setWidth) forzero-extend. (Extends the gotcha inventory from PR #79/#80.)
CI wiring
lakefile.lean— 5 newlean_exestanzas.Tests/AllTests.lean—5 imports +
.maincalls (release-gate runner). Synth runs atlake build; behavioural mains underlake test.