Skip to content

Commit

Permalink
replace onion hashing with input concat
Browse files Browse the repository at this point in the history
  • Loading branch information
nulltea committed Sep 29, 2023
1 parent 19e6448 commit 0c6f3f7
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 43 deletions.
71 changes: 30 additions & 41 deletions lightclient-circuits/src/sync_step_circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ impl<S: Spec, F: Field> SyncStepCircuit<S, F> {
let mut h2c_cache = HashToCurveCache::<F>::default();

// Verify attestted header
let attested_slot: HashInputChunk<_> = args.attested_header.slot.into_witness();
let attested_slot_bytes: HashInputChunk<_> = args.attested_header.slot.into_witness();
let attested_header_state_root = args
.attested_header
.state_root
Expand All @@ -143,7 +143,7 @@ impl<S: Spec, F: Field> SyncStepCircuit<S, F> {
thread_pool,
&sha256_chip,
[
attested_slot.clone(),
attested_slot_bytes.clone(),
args.attested_header.proposer_index.into_witness(),
args.attested_header.parent_root.as_ref().into_witness(),
attested_header_state_root.clone().into(),
Expand All @@ -163,13 +163,12 @@ impl<S: Spec, F: Field> SyncStepCircuit<S, F> {
.map(|&b| thread_pool.main().load_witness(F::from(b as u64)))
.collect_vec();

let finalized_slot: HashInputChunk<_> = args.finalized_header.slot.into_witness();

let finalized_slot_bytes: HashInputChunk<_> = args.finalized_header.slot.into_witness();
let finalized_header_root = ssz_merkleize_chunks(
thread_pool,
&sha256_chip,
[
finalized_slot.clone(),
finalized_slot_bytes.clone(),
args.finalized_header.proposer_index.into_witness(),
args.finalized_header.parent_root.as_ref().into_witness(),
args.finalized_header.state_root.as_ref().into_witness(),
Expand Down Expand Up @@ -229,48 +228,38 @@ impl<S: Spec, F: Field> SyncStepCircuit<S, F> {
)?;

// Public Input Commitment
let h = sha256_chip.digest::<64>(
thread_pool,
HashInput::TwoToOne(attested_slot, finalized_slot),
false,
)?;

// TODO: Investigate if we should hash it all concatinated in one go
let h = sha256_chip.digest::<64>(
thread_pool,
HashInput::TwoToOne(h.output_bytes.into(), finalized_header_root.into()),
false,
)?;

let participation_sum_bytes =
to_bytes_le::<_, 32>(thread_pool.main(), gate, &participation_sum);

let h = sha256_chip.digest::<64>(
thread_pool,
HashInput::TwoToOne(h.output_bytes.into(), participation_sum_bytes.into()),
false,
)?;

let h = sha256_chip.digest::<64>(
thread_pool,
HashInput::TwoToOne(h.output_bytes.into(), execution_payload_root),
false,
)?;
to_bytes_le::<_, 8>(thread_pool.main(), gate, &participation_sum);

let poseidon_commit_bytes =
to_bytes_le::<_, 32>(thread_pool.main(), gate, &poseidon_commit);

let pi_hash_bytes = sha256_chip.digest::<64>(
thread_pool,
HashInput::TwoToOne(h.output_bytes.into(), poseidon_commit_bytes.into()),
false,
)?.output_bytes;
// See "Onion hashing vs. Input concatenation" in https://github.com/ChainSafe/Spectre/issues/17#issuecomment-1740965182
let public_inputs_concat = itertools::chain![
attested_slot_bytes.bytes.into_iter().take(8),
finalized_slot_bytes.bytes.into_iter().take(8),
participation_sum_bytes
.into_iter()
.map(|b| QuantumCell::Existing(b)),
finalized_header_root
.into_iter()
.map(|b| QuantumCell::Existing(b)),
execution_payload_root.bytes.into_iter(),
poseidon_commit_bytes
.into_iter()
.map(|b| QuantumCell::Existing(b)),
]
.collect_vec();

let pi_commit = truncate_sha256_into_signle_elem(
thread_pool.main(),
range,
pi_hash_bytes,
);
let pi_hash_bytes = sha256_chip
.digest::<{ 8 * 3 + 32 * 3 }>(
thread_pool,
HashInputChunk::new(public_inputs_concat).into(),
false,
)?
.output_bytes;

let pi_commit = truncate_sha256_into_signle_elem(thread_pool.main(), range, pi_hash_bytes);

Ok(vec![pi_commit])
}
Expand Down
7 changes: 5 additions & 2 deletions lightclient-circuits/src/witness/hashing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,11 @@ pub struct HashInputChunk<T> {
}

impl<T> HashInputChunk<T> {
pub fn new(bytes: Vec<T>, is_rlc: bool) -> Self {
Self { bytes, is_rlc }
pub fn new(bytes: Vec<T>) -> Self {
Self {
is_rlc: bytes.len() >= 32,
bytes,
}
}

pub fn map<B, F: FnMut(T) -> B>(self, f: F) -> HashInputChunk<B> {
Expand Down

0 comments on commit 0c6f3f7

Please sign in to comment.