Problem Statement / Feature Objective
The BLS aggregate signature verification routine does not defensively validate that each participating public key is in the correct prime-order subgroup G1 prior to aggregation. Without a subgroup check (BLS12-381, r = 52435875175126190479447740508185965837690552500527637822603658699938581184513), an adversary can supply a rogue low-order public key, forge aggregate signatures that pass batch verification, and trigger a false-positive slashing event.
Technical Invariants & Bounds
- Curve: BLS12-381, G1 prime subgroup order r as above.
- Aggregate signature size: 48 bytes (G1 compressed).
- Public keys must satisfy pk * r == O_G1 (identity check).
- Maximum validators per aggregate: 2^16 (protocol bound).
- Signature verification must reject aggregates containing any invalid subgroup element.
Codebase Navigation Guide
- src/crypto/bls-keys.rs - public key deserialization and subgroup validation.
- src/attestation/bls-aggregator.rs - aggregation and batch verification logic.
- src/slashing/condition-engine.rs - slashing event dispatch that consumes aggregate proofs.
- src/crypto/verifier.rs - low-level pairing check routines.
- tests/crypto/bls_subgroup_test.rs - existing test harness.
Implementation Blueprint
- Add subgroup_check(pk: &G1Point) -> bool in src/crypto/bls-keys.rs that multiplies the decompressed point by r and verifies the result is the identity element.
- Call this check inside src/attestation/bls-aggregator.rs at the start of aggregate_signatures() and verify_aggregate(), before any pairing computation.
- On failure, return a typed AggregateError::RogueKey instead of panicking.
- Add property-based tests that inject low-order points and assert rejection.
- Update the slashing condition engine's evaluate() path to propagate the error and mark the attestation as invalid.
Problem Statement / Feature Objective
The BLS aggregate signature verification routine does not defensively validate that each participating public key is in the correct prime-order subgroup G1 prior to aggregation. Without a subgroup check (BLS12-381, r = 52435875175126190479447740508185965837690552500527637822603658699938581184513), an adversary can supply a rogue low-order public key, forge aggregate signatures that pass batch verification, and trigger a false-positive slashing event.
Technical Invariants & Bounds
Codebase Navigation Guide
Implementation Blueprint