Skip to content

Commit 05ddc3d

Browse files
committed
domain-separation when initializing Fiat Shamir
1 parent c7693cc commit 05ddc3d

11 files changed

Lines changed: 57 additions & 18 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/lean_prover/Cargo.toml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,6 @@ utils.workspace = true
1616
xmss.workspace = true
1717
rand.workspace = true
1818

19-
20-
21-
2219
tracing.workspace = true
2320
air.workspace = true
2421
sub_protocols.workspace = true
@@ -28,4 +25,5 @@ backend.workspace = true
2825
itertools.workspace = true
2926

3027
[dev-dependencies]
31-
xmss.workspace = true
28+
xmss.workspace = true
29+
rec_aggregation.workspace = true

crates/lean_prover/src/lib.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ pub const WHIR_INITIAL_FOLDING_FACTOR: usize = 7;
2424
pub const WHIR_SUBSEQUENT_FOLDING_FACTOR: usize = 5;
2525
pub const RS_DOMAIN_INITIAL_REDUCTION_FACTOR: usize = 5;
2626

27+
pub const SNARK_DOMAIN_SEP: [F; 8] = F::new_array([
28+
1315460930, 529218348, 108777370, 1613857347, 1651741419, 1909799493, 1515625756, 1569520942,
29+
]);
30+
2731
pub fn default_whir_config(starting_log_inv_rate: usize) -> WhirConfigBuilder {
2832
WhirConfigBuilder {
2933
folding_factor: FoldingFactor::new(WHIR_INITIAL_FOLDING_FACTOR, WHIR_SUBSEQUENT_FOLDING_FACTOR),
@@ -39,3 +43,38 @@ pub fn default_whir_config(starting_log_inv_rate: usize) -> WhirConfigBuilder {
3943
starting_log_inv_rate,
4044
}
4145
}
46+
47+
#[cfg(test)]
48+
mod tests {
49+
use backend::default_koalabear_poseidon2_16;
50+
use backend::{PrimeCharacteristicRing, hash_slice};
51+
use lean_vm::F;
52+
use rec_aggregation::{get_aggregation_bytecode, init_aggregation_bytecode};
53+
use utils::poseidon16_compress_pair;
54+
55+
use crate::SNARK_DOMAIN_SEP;
56+
57+
#[test]
58+
fn verify_snark_domain_sep() {
59+
init_aggregation_bytecode();
60+
let recursion_bytecode_hash = get_aggregation_bytecode().hash;
61+
let name_fe = "leanMultisig-0.6.0"
62+
.as_bytes()
63+
.iter()
64+
.map(|b| F::from_u8(*b))
65+
.collect::<Vec<_>>();
66+
let mut prefix_free_name_fe = vec![F::ZERO; 8];
67+
let len = name_fe.len();
68+
prefix_free_name_fe.extend(name_fe);
69+
while prefix_free_name_fe.len() % 8 != 7 {
70+
prefix_free_name_fe.push(F::ZERO);
71+
}
72+
prefix_free_name_fe.push(F::from_u64(len as u64));
73+
let comp = default_koalabear_poseidon2_16();
74+
let name_hash = hash_slice::<_, _, _, 8, 8>(&comp, &prefix_free_name_fe);
75+
76+
let expected_domain_sep = poseidon16_compress_pair(&name_hash, &recursion_bytecode_hash);
77+
78+
assert_eq!(expected_domain_sep, SNARK_DOMAIN_SEP);
79+
}
80+
}

crates/lean_prover/src/prove_execution.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ pub fn prove_execution(
4141
}
4242
let mut prover_state = build_prover_state();
4343
prover_state.observe_scalars(public_input);
44-
prover_state.observe_scalars(&bytecode.hash);
44+
prover_state.observe_scalars(&poseidon16_compress_pair(&bytecode.hash, &SNARK_DOMAIN_SEP));
4545
prover_state.add_base_scalars(
4646
&[
4747
vec![whir_config.starting_log_inv_rate, log2_strict_usize(memory.len())],

crates/lean_prover/src/verify_execution.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ pub fn verify_execution(
1919
) -> Result<(ProofVerificationDetails, RawProof<F>), ProofError> {
2020
let mut verifier_state = VerifierState::<EF, _>::new(proof, get_poseidon16().clone())?;
2121
verifier_state.observe_scalars(public_input);
22-
verifier_state.observe_scalars(&bytecode.hash);
22+
verifier_state.observe_scalars(&poseidon16_compress_pair(&bytecode.hash, &SNARK_DOMAIN_SEP));
2323
let dims = verifier_state
2424
.next_base_scalars_vec(2 + N_TABLES)?
2525
.into_iter()

crates/rec_aggregation/recursion.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ def recursion(inner_public_memory, proof_transcript, bytecode_value_hint):
4747

4848
inner_pub_input = inner_public_memory + NONRESERVED_PROGRAM_INPUT_START
4949
fs = fs_observe(fs, inner_pub_input, PUB_INPUT_SIZE) # observe public input
50-
fs = fs_observe(fs, inner_pub_input + BYTECODE_HASH_OFFSET, DIGEST_LEN) # observe bytecode hash
50+
fs = fs_observe(fs, inner_pub_input + BYTECODE_HASH_OFFSET, DIGEST_LEN) # observe hash(bytecode hash, domain sep)
5151

5252
# table dims
5353
debug_assert(N_TABLES + 1 < DIGEST_LEN)

crates/rec_aggregation/src/compilation.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use crate::{MERKLE_LEVELS_PER_CHUNK_FOR_SLOT, N_MERKLE_CHUNKS_FOR_SLOT};
1717

1818
static BYTECODE: OnceLock<Bytecode> = OnceLock::new();
1919

20-
pub(crate) fn get_aggregation_bytecode() -> &'static Bytecode {
20+
pub fn get_aggregation_bytecode() -> &'static Bytecode {
2121
BYTECODE
2222
.get()
2323
.unwrap_or_else(|| panic!("call init_aggregation_bytecode() first"))

crates/rec_aggregation/src/lib.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#![cfg_attr(not(test), allow(unused_crate_dependencies))]
22
use backend::*;
3+
use lean_prover::SNARK_DOMAIN_SEP;
34
use lean_prover::prove_execution::prove_execution;
45
use lean_prover::verify_execution::ProofVerificationDetails;
56
use lean_prover::verify_execution::verify_execution;
@@ -14,10 +15,10 @@ use xmss::{
1415
use serde::{Deserialize, Serialize};
1516
use std::collections::HashSet;
1617

17-
use crate::compilation::get_aggregation_bytecode;
18+
pub use crate::compilation::{get_aggregation_bytecode, init_aggregation_bytecode};
1819

1920
pub mod benchmark;
20-
pub mod compilation;
21+
mod compilation;
2122

2223
const MERKLE_LEVELS_PER_CHUNK_FOR_SLOT: usize = 4;
2324
const N_MERKLE_CHUNKS_FOR_SLOT: usize = LOG_LIFETIME / MERKLE_LEVELS_PER_CHUNK_FOR_SLOT;
@@ -73,7 +74,7 @@ fn build_non_reserved_public_input(
7374
pi.push(slot_hi);
7475
pi.extend(compute_merkle_chunks_for_slot(slot));
7576
pi.extend_from_slice(bytecode_claim_output);
76-
pi.extend_from_slice(bytecode_hash);
77+
pi.extend_from_slice(&poseidon16_compress_pair(bytecode_hash, &SNARK_DOMAIN_SEP));
7778
pi
7879
}
7980

@@ -411,7 +412,7 @@ pub fn hash_bytecode_claims(claims: &[Evaluation<EF>]) -> [F; DIGEST_LEN] {
411412
data.resize(data.len().next_multiple_of(DIGEST_LEN), F::ZERO);
412413

413414
let claim_hash = poseidon_compress_slice(&data, false);
414-
running_hash = poseidon16_compress_pair(running_hash, claim_hash);
415+
running_hash = poseidon16_compress_pair(&running_hash, &claim_hash);
415416
}
416417
running_hash
417418
}

crates/utils/src/poseidon2.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,10 @@ pub fn poseidon16_compress(input: [KoalaBear; 16]) -> [KoalaBear; 8] {
3131
get_poseidon16().compress(input)[0..8].try_into().unwrap()
3232
}
3333

34-
pub fn poseidon16_compress_pair(left: [KoalaBear; 8], right: [KoalaBear; 8]) -> [KoalaBear; 8] {
34+
pub fn poseidon16_compress_pair(left: &[KoalaBear; 8], right: &[KoalaBear; 8]) -> [KoalaBear; 8] {
3535
let mut input = [KoalaBear::default(); 16];
36-
input[..8].copy_from_slice(&left);
37-
input[8..].copy_from_slice(&right);
36+
input[..8].copy_from_slice(left);
37+
input[8..].copy_from_slice(right);
3838
poseidon16_compress(input)
3939
}
4040

crates/xmss/src/wots.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ impl WotsPublicKey {
109109
}
110110

111111
pub fn iterate_hash(a: &Digest, n: usize) -> Digest {
112-
(0..n).fold(*a, |acc, _| poseidon16_compress_pair(acc, Default::default()))
112+
(0..n).fold(*a, |acc, _| poseidon16_compress_pair(&acc, &Default::default()))
113113
}
114114

115115
pub fn iterate_hash_with_poseidon_trace(

0 commit comments

Comments
 (0)