Skip to content

Commit 0d9c9e1

Browse files
committed
Merge branch 'mig/missing' into HEAD
2 parents c0c8eb8 + d3ac68f commit 0d9c9e1

68 files changed

Lines changed: 6849 additions & 1716 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.cargo/config.toml‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,21 @@
1+
# leanVM proves over a binary field tower, whose multiplication is a carryless
2+
# multiply. Both entries below have to enable it, or the prover falls back to
3+
# scalar bit-twiddling: `+pclmulqdq` on x86, and on aarch64 the `aes` feature,
4+
# which is what LLVM gates PMULL behind.
15
[target.x86_64-unknown-linux-gnu]
26
rustflags = [
37
"-Ctarget-cpu=x86-64-v3",
48
"-Ctarget-feature=+avx2,+sse2,+ssse3,+sse4.1,+sse4.2,+bmi1,+lzcnt,+pclmulqdq",
59
]
610

11+
[target.aarch64-unknown-linux-gnu]
12+
rustflags = [
13+
# Baseline armv8.2 (the floor for Apple silicon and Neoverse N1/V1), plus the
14+
# crypto extensions carrying PMULL and SHA-2.
15+
"-Ctarget-cpu=neoverse-n1",
16+
"-Ctarget-feature=+aes,+sha2,+neon",
17+
]
18+
719
# Supply-chain cooldown for dependency resolution (unstable min-publish-age,
820
# tracking issue rust-lang/cargo#17009): crate versions published less than
921
# 14 days ago are excluded when the resolver runs on a nightly cargo.

‎.github/workflows/ci.yml‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,12 @@ jobs:
5959
- name: Clippy
6060
run: cargo clippy --locked --workspace --all-targets -- -D warnings
6161

62+
# The leanSpec spectests are `test = false` while the released fixtures
63+
# lag leanVM, and `--all-targets` leaves such targets out. Name them so
64+
# they keep compiling until they run again.
65+
- name: Clippy (skipped spectests)
66+
run: cargo clippy --locked --workspace --test forkchoice_spectests --test signature_spectests --test stf_spectests --test ssz_spectests -- -D warnings
67+
6268
# Two features gate code that no step in `lint` reaches, so both would rot
6369
# silently between merges.
6470
#

‎.github/workflows/pr-main_mdbook.yml‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,13 @@ on:
88
- main
99
paths:
1010
- "docs/**"
11+
- "theme/**"
1112
- "book.toml"
1213
- ".github/workflows/pr-main_mdbook.yml"
1314
pull_request:
1415
paths:
1516
- "docs/**"
17+
- "theme/**"
1618
- "book.toml"
1719
- ".github/workflows/pr-main_mdbook.yml"
1820
workflow_dispatch:

‎CLAUDE.md‎

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ crates/
3939
└─ src/metrics.rs # State transition timing + counters
4040
common/
4141
├─ types/ # Core types (State, Block, Attestation, Checkpoint)
42-
├─ crypto/ # XMSS aggregation (leansig wrapper)
42+
├─ crypto/ # XMSS sign/verify + aggregation (leanVM wrapper)
4343
├─ ssz-tree/ # Persistent Merkle tree (List/Vector) behind the beacon registry and balances
4444
├─ metrics/ # Prometheus re-exports, TimingGuard, gather utilities
4545
└─ test-fixtures/ # Spec-fixture loading (prod dep of rpc's Hive test driver)
@@ -279,9 +279,39 @@ actual_slot = finalized_slot + 1 + relative_index
279279

280280
**XMSS (eXtended Merkle Signature Scheme):**
281281
- Post-quantum signature scheme
282-
- 52-byte public keys, 2536-byte signatures (`SIGNATURE_SIZE` in `common/types/src/signature.rs`)
282+
- Wire sizes: `PUBLIC_KEY_SIZE` (`common/types/src/state.rs`) and `SIGNATURE_SIZE`
283+
(`common/types/src/attestation.rs`), static-asserted against leanVM's scheme
284+
constants in `common/crypto/src/signature.rs`
283285
- Epoch-based to prevent reuse
284-
- Aggregation via leanVM (previously leanMultisig) for efficiency
286+
- Signing, verification, and aggregation all come from leanVM, which internalized
287+
XMSS in its own `xmss` crate; there is no external leanSig dependency
288+
- BLAKE2s over binary fields, not Poseidon over KoalaBear: a leanVM `main` bump
289+
across that rewrite invalidates every genesis key and every stored proof, even
290+
when the wire sizes happen to match
291+
- `ethlambda_crypto::init_leanvm(use_arena)` must run once at startup, before any
292+
proving or proof decoding. `--prover-arena` opts into leanVM's bump arena,
293+
which recycles the prover's large buffers across proofs instead of re-faulting
294+
them, so its pages stay resident for the node's lifetime
295+
- `ethlambda keygen` generates genesis validator keys through the same
296+
`ValidatorSecretKey` the node loads them with, so a key set cannot be built
297+
against a different leanVM than the client reading it. Keys are only usable by
298+
a client on the matching revision, and no file size changes when the scheme
299+
does, so the manifest records `leanvm_rev`. See [`docs/keygen.md`](docs/keygen.md)
300+
301+
**Aggregation shape (one leanVM `AggregateSignature`, grouped by `(epoch, message)`):**
302+
- Type-1 and Type-2 are the same object: one `XmssGroup` per `(epoch, message)`
303+
pair, carrying that group's sorted, deduplicated keys
304+
- **A slot can carry several messages.** Validators attesting moments apart
305+
disagree within a slot, so two distinct `AttestationData` at one slot is
306+
ordinary rather than equivocation and a block routinely carries both. The
307+
groups are sorted on the whole pair: with two of them at one slot, sorting on
308+
the epoch alone rebuilds a different signer set and fails a valid proof
309+
- **The binding is off the wire.** `to_bytes_without_pubkeys()` carries neither
310+
the keys nor the `(slot, message)` pairs, so every decode rebuilds the whole
311+
signer set from a `SignerSet` per claim. A wrong set, message or slot decodes
312+
fine and fails inside the SNARK verifier, so there is no cheap binding check
313+
- Narrowing replaces splitting: re-aggregate the parent with a `declare` naming
314+
the group to keep (`split_type_2_by_message`)
285315

286316
**Signature Aggregation (Two-Phase):**
287317
1. **Gossip signatures**: Fresh XMSS from network → aggregate via leanVM
@@ -674,7 +704,7 @@ transitions are in `ethlambda-types`, per the section above. Nothing above
674704
GENESIS_TIME: 1770407233
675705
MILLISECONDS_PER_SLOT: 4000 # optional, defaults to DEFAULT_MILLISECONDS_PER_SLOT
676706
GENESIS_VALIDATORS:
677-
- attestation_pubkey: "cd323f232b34ab26d6db7402c886e74ca81cfd3a..." # 52-byte XMSS pubkeys (hex)
707+
- attestation_pubkey: "cd323f232b34ab26d6db7402c886e74ca81cfd3a..." # XMSS pubkeys, hex, PUBLIC_KEY_SIZE bytes
678708
proposal_pubkey: "b7b0f72e24801b02bda64073cb4de6699a416b37..."
679709
```
680710
- Validator indices are assigned sequentially (0, 1, 2, ...) based on array order
@@ -780,7 +810,9 @@ behavior.
780810
## External Dependencies
781811

782812
**Critical:**
783-
- `leansig`: XMSS signatures (leanEthereum project)
813+
- `leanvm`: XMSS signatures and recursive aggregation, taken from leanVM's facade
814+
crate (which re-exports `xmss`, `rec_aggregation` and its `rand`) and pinned to
815+
one `main` revision (leanEthereum project)
784816
- `libssz` / `libssz-derive` / `libssz-types`: SSZ serialization
785817
- `libssz-merkle`: Merkle tree hashing (`hash_tree_root()`)
786818
- `spawned-concurrency`: Actor model

‎CONTRIBUTING.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ crates/
2525
└─ state_transition/ # Process slots, blocks, attestations
2626
common/
2727
├─ types/ # Core types
28-
├─ crypto/ # XMSS aggregation (leansig wrapper)
28+
├─ crypto/ # XMSS sign/verify + aggregation (leanVM wrapper)
2929
└─ metrics/ # Prometheus metrics
3030
net/
3131
├─ p2p/ # libp2p: gossipsub + req-resp

0 commit comments

Comments
 (0)