Skip to content

Commit d1aad6c

Browse files
committed
fix(tests): more testing of linear relations
1 parent 469794c commit d1aad6c

File tree

6 files changed

+108
-128
lines changed

6 files changed

+108
-128
lines changed

src/linear_relation/mod.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -160,9 +160,15 @@ impl<G: PrimeGroup> GroupMap<G> {
160160
///
161161
/// Returns [`Error::UnassignedGroupVar`] if a value is not assigned.
162162
pub fn get(&self, var: GroupVar<G>) -> Result<G, Error> {
163-
self.0[var.0].ok_or(Error::UnassignedGroupVar {
164-
var_debug: format!("{var:?}"),
165-
})
163+
match self.0.get(var.0) {
164+
Some(Some(elem)) => Ok(*elem),
165+
Some(None) => Err(Error::UnassignedGroupVar {
166+
var_debug: format!("{var:?}"),
167+
}),
168+
None => Err(Error::UnassignedGroupVar {
169+
var_debug: format!("{var:?}"),
170+
}),
171+
}
166172
}
167173

168174
/// Iterate over the assigned variable and group element pairs in this mapping.

src/tests/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
mod composition;
2-
mod relations;
31
mod spec;
4-
pub mod test_utils;
2+
3+
mod test_composition;
4+
mod test_relations;
55
mod test_validation_criteria;

src/tests/relations.rs

Lines changed: 0 additions & 104 deletions
This file was deleted.

src/tests/composition.rs renamed to src/tests/test_composition.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
use curve25519_dalek::ristretto::RistrettoPoint;
22
use rand::rngs::OsRng;
33

4-
use super::test_utils::{
5-
bbs_blind_commitment, discrete_logarithm, dleq, pedersen_commitment, pedersen_commitment_dleq,
6-
};
4+
use super::test_relations::*;
75
use crate::codec::Shake128DuplexSponge;
86
use crate::composition::{ComposedRelation, ProtocolWitness};
97
use crate::fiat_shamir::Nizk;

src/tests/test_utils.rs renamed to src/tests/test_relations.rs

Lines changed: 71 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,17 @@
1-
//! Definitions used in tests for this crate.
1+
use std::collections::HashMap;
22

33
use ff::Field;
44
use group::prime::PrimeGroup;
5+
use rand::rngs::OsRng;
56
use rand::RngCore;
67

7-
use crate::linear_relation::{msm_pr, CanonicalLinearRelation, LinearRelation};
8+
use crate::fiat_shamir::Nizk;
9+
use crate::{
10+
codec::Shake128DuplexSponge, linear_relation::CanonicalLinearRelation,
11+
schnorr_protocol::SchnorrProof,
12+
};
13+
14+
use crate::linear_relation::{msm_pr, LinearRelation};
815

916
/// LinearMap for knowledge of a discrete logarithm relative to a fixed basepoint.
1017
#[allow(non_snake_case)]
@@ -227,22 +234,10 @@ pub fn bbs_blind_commitment<G: PrimeGroup, R: RngCore>(
227234
(instance, witness)
228235
}
229236

230-
/// Test function with the requested LinearRelation code
231-
#[allow(non_snake_case)]
232-
pub fn test_linear_relation_example<G: PrimeGroup>() -> LinearRelation<G> {
233-
use ff::Field;
234-
235-
let mut sigma__lr = LinearRelation::<G>::new();
236-
let x = sigma__lr.allocate_scalar();
237-
let B = sigma__lr.allocate_element();
238-
let _sigma__eq1 = sigma__lr.allocate_eq((x + (-<G::Scalar as Field>::ONE)) * B + (-B));
239-
240-
sigma__lr
241-
}
242237

243238
/// LinearMap for the user's specific relation: A * 1 + gen__disj1_x_r * B
244239
#[allow(non_snake_case)]
245-
pub fn user_specific_linear_combination<G: PrimeGroup, R: RngCore>(
240+
pub fn weird_linear_combination<G: PrimeGroup, R: RngCore>(
246241
rng: &mut R,
247242
) -> (CanonicalLinearRelation<G>, Vec<G::Scalar>) {
248243
let B = G::random(&mut *rng);
@@ -270,3 +265,64 @@ pub fn user_specific_linear_combination<G: PrimeGroup, R: RngCore>(
270265
let instance = (&sigma__lr).try_into().unwrap();
271266
(instance, witness)
272267
}
268+
269+
/// Generic helper function to test both relation correctness and NIZK functionality
270+
#[test]
271+
fn test_common_relations() {
272+
use group::Group;
273+
type G = bls12_381::G1Projective;
274+
275+
let mut instance_generators = HashMap::<
276+
&str,
277+
Box<dyn Fn(&mut OsRng) -> (CanonicalLinearRelation<G>, Vec<<G as Group>::Scalar>)>,
278+
>::new();
279+
280+
instance_generators.insert("dlog", Box::new(discrete_logarithm));
281+
instance_generators.insert("shifted_dlog", Box::new(shifted_discrete_logarithm));
282+
instance_generators.insert("dleq", Box::new(dleq));
283+
instance_generators.insert("shifted_dleq", Box::new(shifted_dleq));
284+
instance_generators.insert("pedersen_commitment", Box::new(pedersen_commitment));
285+
instance_generators.insert(
286+
"pedersen_commitment_dleq",
287+
Box::new(pedersen_commitment_dleq),
288+
);
289+
instance_generators.insert("bbs_blind_commitment", Box::new(bbs_blind_commitment));
290+
instance_generators.insert(
291+
"weird_linear_combination",
292+
Box::new(weird_linear_combination),
293+
);
294+
295+
for (relation_name, relation_sampler) in instance_generators.iter() {
296+
let mut rng = OsRng;
297+
let (canonical_relation, witness) = relation_sampler(&mut rng);
298+
299+
// Test the NIZK protocol
300+
let protocol = SchnorrProof(canonical_relation);
301+
let domain_sep = format!("test-fiat-shamir-{}", relation_name)
302+
.as_bytes()
303+
.to_vec();
304+
let nizk = Nizk::<SchnorrProof<G>, Shake128DuplexSponge<G>>::new(&domain_sep, protocol);
305+
306+
// Test both proof types
307+
let proof_batchable = nizk.prove_batchable(&witness, &mut OsRng).expect(&format!(
308+
"Failed to create batchable proof for {}",
309+
relation_name
310+
));
311+
let proof_compact = nizk.prove_compact(&witness, &mut OsRng).expect(&format!(
312+
"Failed to create compact proof for {}",
313+
relation_name
314+
));
315+
316+
// Verify both proof types
317+
assert!(
318+
nizk.verify_batchable(&proof_batchable).is_ok(),
319+
"Batchable proof verification failed for {}",
320+
relation_name
321+
);
322+
assert!(
323+
nizk.verify_compact(&proof_compact).is_ok(),
324+
"Compact proof verification failed for {}",
325+
relation_name
326+
);
327+
}
328+
}

src/tests/test_validation_criteria.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,30 @@ mod instance_validation {
7979
assert!(result.is_err());
8080
}
8181

82+
/// Test function with the requested LinearRelation code
83+
#[test]
84+
#[allow(non_snake_case)]
85+
pub fn test_degenerate_equation() {
86+
use ff::Field;
87+
88+
// This relation should fail for two reasons:
89+
// 1. because B is not assigned
90+
let mut relation = LinearRelation::<G>::new();
91+
let x = relation.allocate_scalar();
92+
let B = relation.allocate_element();
93+
let _eq = relation.allocate_eq((x + (-Scalar::ONE)) * B + (-B));
94+
95+
assert!(CanonicalLinearRelation::try_from(&relation).is_err());
96+
97+
// 2. because the equation is void
98+
let mut relation = LinearRelation::<G>::new();
99+
let x = relation.allocate_scalar();
100+
let B = relation.allocate_element();
101+
let _eq = relation.allocate_eq((x + (-Scalar::ONE)) * B + (-B));
102+
relation.set_element(B, G::generator());
103+
assert!(CanonicalLinearRelation::try_from(&relation).is_err());
104+
}
105+
82106
#[test]
83107
fn test_inconsistent_equation_count() {
84108
// Create a relation with mismatched equations and image elements

0 commit comments

Comments
 (0)