From ea4fc46147a0f04b8cf76d8a3a8acd683524ac0b Mon Sep 17 00:00:00 2001 From: Zara Date: Thu, 19 Feb 2026 14:21:00 -0800 Subject: [PATCH 1/7] made some optimizations by using one gamma --- .../lib/src/core/threshold/pk_generation.nr | 27 +++++-------------- 1 file changed, 6 insertions(+), 21 deletions(-) diff --git a/circuits/lib/src/core/threshold/pk_generation.nr b/circuits/lib/src/core/threshold/pk_generation.nr index e4ccc80171..d4f244750d 100644 --- a/circuits/lib/src/core/threshold/pk_generation.nr +++ b/circuits/lib/src/core/threshold/pk_generation.nr @@ -100,12 +100,7 @@ impl Vec { + fn payload(self, sk_commitment: Field, pk_commitment: Field) -> Vec { let mut inputs = Vec::new(); // Flatten CRS polynomials a (L polynomials of degree N) @@ -117,7 +112,6 @@ impl(inputs, self.r1); @@ -129,36 +123,27 @@ impl (Field, Field, Field) { - // Step 1: Perform range checks on all secret witness values self.perform_range_checks(); - // Step 2: Compute commitments let sk_commitment = compute_share_computation_sk_commitment::(self.sk); let e_sm_commitment = compute_share_computation_e_sm_commitment::(self.e_sm); let pk_commitment = compute_threshold_pk_commitment::(self.pk0, self.pk1); - // Step 3: Generate Fiat-Shamir challenges using commitments - let gammas = self.generate_challenge(sk_commitment, pk_commitment, e_sm_commitment); + let gammas = self.generate_challenge(sk_commitment, pk_commitment); - // Step 4: Verify public key equations for each modulus + // Use single gamma at index 0 for all modulus evaluations + let gamma = gammas.get(0); for i in 0..L { - let gamma = gammas.get(i); self.verify_public_key_for_modulus(i, gamma); } - // Step 5: Return all commitments (sk_commitment, pk_commitment, e_sm_commitment) } /// Generates Fiat-Shamir challenge values using the SAFE cryptographic sponge - fn generate_challenge( - self, - sk_commitment: Field, - pk_commitment: Field, - e_sm_commitment: Field, - ) -> Vec { - let inputs = self.payload(sk_commitment, pk_commitment, e_sm_commitment); + fn generate_challenge(self, sk_commitment: Field, pk_commitment: Field) -> Vec { + let inputs = self.payload(sk_commitment, pk_commitment); compute_threshold_pk_challenge::(inputs) } From 350fc669cbb52877ca7be3110ede563e53a5f886 Mon Sep 17 00:00:00 2001 From: Zara Date: Thu, 19 Feb 2026 15:25:28 -0800 Subject: [PATCH 2/7] generating one gamma in pk generation --- circuits/lib/src/core/threshold/pk_generation.nr | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/circuits/lib/src/core/threshold/pk_generation.nr b/circuits/lib/src/core/threshold/pk_generation.nr index d4f244750d..304661acf2 100644 --- a/circuits/lib/src/core/threshold/pk_generation.nr +++ b/circuits/lib/src/core/threshold/pk_generation.nr @@ -130,10 +130,8 @@ impl(self.e_sm); let pk_commitment = compute_threshold_pk_commitment::(self.pk0, self.pk1); - let gammas = self.generate_challenge(sk_commitment, pk_commitment); + let gamma = self.generate_challenge(sk_commitment, pk_commitment); - // Use single gamma at index 0 for all modulus evaluations - let gamma = gammas.get(0); for i in 0..L { self.verify_public_key_for_modulus(i, gamma); } @@ -142,10 +140,10 @@ impl Vec { + fn generate_challenge(self, sk_commitment: Field, pk_commitment: Field) -> Field { let inputs = self.payload(sk_commitment, pk_commitment); - compute_threshold_pk_challenge::(inputs) + compute_threshold_pk_challenge(inputs) } /// Performs range checks on all secret witness values From 2bd88beee2d85cb3cc326583ebaf1ed8cf4e9e6b Mon Sep 17 00:00:00 2001 From: 0xjei Date: Fri, 20 Feb 2026 11:58:12 +0100 Subject: [PATCH 3/7] update mirror rust fn --- crates/zk-helpers/src/circuits/commitments.rs | 29 +++++++++---------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/crates/zk-helpers/src/circuits/commitments.rs b/crates/zk-helpers/src/circuits/commitments.rs index 1d7bd61d43..b145b1808d 100644 --- a/crates/zk-helpers/src/circuits/commitments.rs +++ b/crates/zk-helpers/src/circuits/commitments.rs @@ -424,21 +424,16 @@ pub fn compute_aggregated_shares_commitment(agg_shares: &CrtPolynomial, bit_msg: /// /// # Arguments /// * `payload` - Prepared payload as a vector of field elements -/// * `l` - Number of moduli /// /// # Returns -/// A vector of `BigInt` challenges (2*L elements) -pub fn compute_threshold_pk_challenge(payload: Vec, l: usize) -> Vec { +/// A `BigInt` representing the commitment hash value +pub fn compute_threshold_pk_challenge(payload: Vec) -> BigInt { let input_size = payload.len() as u32; - let io_pattern = [0x80000000 | input_size, (2 * l as u32)]; + let io_pattern = [0x80000000 | input_size, 1]; - compute_commitments(payload, DS_CLG_PK_GENERATION, io_pattern) - .into_iter() - .map(|challenge_field| { - let challenge_bytes = challenge_field.into_bigint().to_bytes_le(); - BigInt::from_bytes_le(num_bigint::Sign::Plus, &challenge_bytes) - }) - .collect() + let challenge_field = compute_commitments(payload, DS_CLG_PK_GENERATION, io_pattern)[0]; + let challenge_bytes = challenge_field.into_bigint().to_bytes_le(); + BigInt::from_bytes_le(num_bigint::Sign::Plus, &challenge_bytes) } /// Compute share encryption challenge. @@ -600,12 +595,16 @@ mod tests { } #[test] - fn compute_threshold_pk_challenge_returns_2l_elements() { + fn compute_threshold_pk_challenge_returns_single_bigint() { let payload = vec![Field::from(1u64), Field::from(2u64)]; - let l = 3; + let input_size = payload.len() as u32; + let io_pattern = [0x80000000 | input_size, 1]; + let expected_challenge = field_to_bigint( + compute_commitments(payload.clone(), DS_CLG_PK_GENERATION, io_pattern)[0], + ); - let challenges = compute_threshold_pk_challenge(payload, l); - assert_eq!(challenges.len(), 2 * l); + let challenge = compute_threshold_pk_challenge(payload); + assert_eq!(challenge, expected_challenge); } #[test] From 8aa71a078c4ca7076034386b6440b76fb5b28392 Mon Sep 17 00:00:00 2001 From: Zara Date: Fri, 20 Feb 2026 08:39:39 -0800 Subject: [PATCH 4/7] removed repeated poly evaluations --- .../lib/src/core/threshold/pk_generation.nr | 45 +++++++------------ 1 file changed, 16 insertions(+), 29 deletions(-) diff --git a/circuits/lib/src/core/threshold/pk_generation.nr b/circuits/lib/src/core/threshold/pk_generation.nr index 304661acf2..45b9320c14 100644 --- a/circuits/lib/src/core/threshold/pk_generation.nr +++ b/circuits/lib/src/core/threshold/pk_generation.nr @@ -131,10 +131,7 @@ impl(self.pk0, self.pk1); let gamma = self.generate_challenge(sk_commitment, pk_commitment); - - for i in 0..L { - self.verify_public_key_for_modulus(i, gamma); - } + self.verify_evaluations(gamma); (sk_commitment, pk_commitment, e_sm_commitment) } @@ -173,32 +170,22 @@ impl Date: Fri, 20 Feb 2026 09:45:21 -0800 Subject: [PATCH 5/7] fixed r1 bound in circuit 6 --- .../src/circuits/threshold/share_decryption/computation.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/zk-helpers/src/circuits/threshold/share_decryption/computation.rs b/crates/zk-helpers/src/circuits/threshold/share_decryption/computation.rs index 1a999fe702..839e3dc631 100644 --- a/crates/zk-helpers/src/circuits/threshold/share_decryption/computation.rs +++ b/crates/zk-helpers/src/circuits/threshold/share_decryption/computation.rs @@ -177,11 +177,11 @@ impl Computation for Bounds { // r_2j bounds: [- (q_j-1)/2 , (q_j-1)/2] (cyclotomic quotients) r2_bounds.push(qi_bound.clone()); - // r_1j upper bound: (qi_bound * (qi_bound * n + 3) - qi_bound) / qi_bigint + // r_1j upper bound: (n * ((q_j-1)/2)^2 + 4 * (q_j-1)/2) / q_j // Symmetric lower bound used by range_check_2bounds. Variables: qi_bound = (q_j-1)/2, // qi_bigint = q_j, n = degree. r1_bounds.push( - (&qi_bound * (&qi_bound.clone() * &n + BigInt::from(3)) - &qi_bound.clone()) + (&qi_bound.clone() * &qi_bound.clone() * &n + BigInt::from(4) * &qi_bound.clone()) / &qi_bigint, ); } From dafe017b853bc9f75b49297d41c7211ff047068a Mon Sep 17 00:00:00 2001 From: 0xjei Date: Mon, 23 Feb 2026 10:55:47 +0100 Subject: [PATCH 6/7] update c6 configs based on new r1 comp --- circuits/lib/src/configs/insecure/threshold.nr | 2 +- circuits/lib/src/configs/secure/threshold.nr | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/circuits/lib/src/configs/insecure/threshold.nr b/circuits/lib/src/configs/insecure/threshold.nr index f4b520f984..91bc812cdd 100644 --- a/circuits/lib/src/configs/insecure/threshold.nr +++ b/circuits/lib/src/configs/insecure/threshold.nr @@ -1167,7 +1167,7 @@ pub global THRESHOLD_SHARE_DECRYPTION_BIT_R1: u32 = 43; pub global THRESHOLD_SHARE_DECRYPTION_BIT_R2: u32 = 35; pub global THRESHOLD_SHARE_DECRYPTION_BIT_D: u32 = 35; -pub global THRESHOLD_SHARE_DECRYPTION_R1_BOUNDS: [Field; L] = [8796083584897, 8796061564801]; +pub global THRESHOLD_SHARE_DECRYPTION_R1_BOUNDS: [Field; L] = [8796083584898, 8796061564802]; pub global THRESHOLD_SHARE_DECRYPTION_R2_BOUNDS: [Field; L] = [34359701504, 34359615488]; pub global THRESHOLD_SHARE_DECRYPTION_CONFIGS: ShareDecryptionConfigs = ShareDecryptionConfigs::new( diff --git a/circuits/lib/src/configs/secure/threshold.nr b/circuits/lib/src/configs/secure/threshold.nr index d5dc2c4c52..40ec5fbc58 100644 --- a/circuits/lib/src/configs/secure/threshold.nr +++ b/circuits/lib/src/configs/secure/threshold.nr @@ -32916,7 +32916,7 @@ pub global THRESHOLD_SHARE_DECRYPTION_BIT_R2: u32 = 52; pub global THRESHOLD_SHARE_DECRYPTION_BIT_D: u32 = 52; pub global THRESHOLD_SHARE_DECRYPTION_R1_BOUNDS: [Field; L] = - [4611686035875690497, 9223372037660080129, 9223372045176272897, 9223372051618723841]; + [4611686035875690498, 9223372037660080130, 9223372045176272898, 9223372051618723842]; pub global THRESHOLD_SHARE_DECRYPTION_R2_BOUNDS: [Field; L] = [1125899911102464, 2251799813881856, 2251799815716864, 2251799817289728]; From 44ea9eb5e4b667af9cd8d67c898ad73ae0e129da Mon Sep 17 00:00:00 2001 From: 0xjei Date: Wed, 25 Feb 2026 10:24:26 +0100 Subject: [PATCH 7/7] fix compute of commits --- circuits/lib/src/math/commitments.nr | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/circuits/lib/src/math/commitments.nr b/circuits/lib/src/math/commitments.nr index 9f3d842b21..0da0568ecf 100644 --- a/circuits/lib/src/math/commitments.nr +++ b/circuits/lib/src/math/commitments.nr @@ -244,8 +244,8 @@ pub fn compute_ciphertext_commitment( /// COMMITMENTS FOR CHALLENGES -pub fn compute_threshold_pk_challenge(payload: Vec) -> Vec { - compute_challenge::(payload, DS_CLG_PK_GENERATION) +pub fn compute_threshold_pk_challenge(payload: Vec) -> Field { + compute_commitment(payload, DS_CLG_PK_GENERATION) } pub fn compute_share_encryption_challenge(payload: Vec) -> Vec {