diff --git a/lightclient-circuits/Cargo.toml b/lightclient-circuits/Cargo.toml index c1dc9ce..fa18d72 100644 --- a/lightclient-circuits/Cargo.toml +++ b/lightclient-circuits/Cargo.toml @@ -45,6 +45,7 @@ strum_macros = "0.25" rand = "0.8" lazy_static = "1.4" getset = "0.1.2" +rand_chacha = "0.3.0" [dev-dependencies] rstest = "0.18.2" diff --git a/lightclient-circuits/config/sync_step_testnet.json b/lightclient-circuits/config/sync_step_testnet.json index b584876..9659e0c 100644 --- a/lightclient-circuits/config/sync_step_testnet.json +++ b/lightclient-circuits/config/sync_step_testnet.json @@ -2,7 +2,7 @@ "params": { "k": 21, "num_advice_per_phase": [ - 7 + 8 ], "num_fixed": 1, "num_lookup_advice_per_phase": [ @@ -15,12 +15,13 @@ }, "break_points": [ [ - 2097141, - 2097141, 2097142, 2097140, + 2097140, 2097142, - 2097141 + 2097141, + 2097140, + 2097142 ] ] } \ No newline at end of file diff --git a/lightclient-circuits/src/sync_step_circuit.rs b/lightclient-circuits/src/sync_step_circuit.rs index 175f791..f85d4ec 100644 --- a/lightclient-circuits/src/sync_step_circuit.rs +++ b/lightclient-circuits/src/sync_step_circuit.rs @@ -274,32 +274,7 @@ impl StepCircuit { poseidon_commitment, ]] } -} - -// Truncate the SHA256 digest to 253 bits and convert to one field element. -pub fn truncate_sha256_into_single_elem( - ctx: &mut Context, - gate: &impl GateInstructions, - hash_bytes: [AssignedValue; 32], -) -> AssignedValue { - let public_input_commitment_bytes = { - let mut truncated_hash = hash_bytes; - let cleared_byte = { - let bits = gate.num_to_bits(ctx, truncated_hash[31], 8); - gate.bits_to_num(ctx, &bits[..5]) - }; - truncated_hash[31] = cleared_byte; - truncated_hash - }; - - let byte_bases = (0..32) - .map(|i| QuantumCell::Constant(gate.pow_of_two()[i * 8])) - .collect_vec(); - - gate.inner_product(ctx, public_input_commitment_bytes, byte_bases) -} -impl StepCircuit { /// Decompresses siganure from bytes and assigns it to the circuit. fn assign_signature( ctx: &mut Context, @@ -389,6 +364,29 @@ impl StepCircuit { } } +// Truncate the SHA256 digest to 253 bits and convert to one field element. +pub fn truncate_sha256_into_single_elem( + ctx: &mut Context, + gate: &impl GateInstructions, + hash_bytes: [AssignedValue; 32], +) -> AssignedValue { + let public_input_commitment_bytes = { + let mut truncated_hash = hash_bytes; + let cleared_byte = { + let bits = gate.num_to_bits(ctx, truncated_hash[31], 8); + gate.bits_to_num(ctx, &bits[..5]) + }; + truncated_hash[31] = cleared_byte; + truncated_hash + }; + + let byte_bases = (0..32) + .map(|i| QuantumCell::Constant(gate.pow_of_two()[i * 8])) + .collect_vec(); + + gate.inner_product(ctx, public_input_commitment_bytes, byte_bases) +} + impl AppCircuit for StepCircuit { type Pinning = Eth2ConfigPinning; type Witness = witness::SyncStepArgs; diff --git a/lightclient-circuits/src/witness/step.rs b/lightclient-circuits/src/witness/step.rs index 3a33cca..865a836 100644 --- a/lightclient-circuits/src/witness/step.rs +++ b/lightclient-circuits/src/witness/step.rs @@ -5,13 +5,14 @@ use eth_types::Spec; use ethereum_consensus_types::signing::compute_signing_root; use ethereum_consensus_types::BeaconBlockHeader; +use ff::Field; use halo2curves::bls12_381::hash_to_curve::ExpandMsgXmd; use halo2curves::bls12_381::{hash_to_curve, Fr, G1, G2}; use halo2curves::group::Curve; use itertools::Itertools; +use rand::SeedableRng; use serde::{Deserialize, Serialize}; use ssz_rs::{Merkleized, Node}; -use std::iter; use std::marker::PhantomData; use std::ops::Deref; @@ -86,30 +87,38 @@ impl Default for SyncStepArgs { let signing_root = compute_signing_root(attested_header.hash_tree_root().unwrap(), DOMAIN).unwrap(); - let sk = Fr::from_bytes(&[1; 32]).unwrap(); + let mut rng = rand_chacha::ChaCha8Rng::seed_from_u64(0); + + let sks = (0..S::SYNC_COMMITTEE_SIZE) + .map(|_| Fr::random(&mut rng)) + .collect_vec(); let msg = >>::hash_to_curve( signing_root.deref(), S::DST, ) .to_affine(); - let aggregated_signature = vec![msg * sk; S::SYNC_COMMITTEE_SIZE] - .into_iter() + let aggregated_signature = sks + .iter() + .map(|sk| msg * sk) .fold(G2::identity(), |acc, x| acc + x) .to_affine(); let signature_compressed = aggregated_signature.to_compressed_be().to_vec(); - let pubkey_uncompressed = (G1::generator() * sk) - .to_affine() - .to_uncompressed_be() - .to_vec(); + let pubkeys_uncompressed = sks + .iter() + .map(|sk| { + (G1::generator() * sk) + .to_affine() + .to_uncompressed_be() + .to_vec() + }) + .collect_vec(); Self { signature_compressed, - pubkeys_uncompressed: iter::repeat(pubkey_uncompressed) - .take(S::SYNC_COMMITTEE_SIZE) - .collect_vec(), + pubkeys_uncompressed, pariticipation_bits: vec![true; S::SYNC_COMMITTEE_SIZE], domain: DOMAIN, attested_header,