Skip to content

Commit 6b1ca1c

Browse files
Merge branch 'snarkeling' into liminal/call-indices
2 parents e73c014 + 97dfa42 commit 6b1ca1c

File tree

4 files changed

+83
-72
lines changed

4 files changed

+83
-72
lines changed

bin/cliain/src/snark_relations/relations.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ use relations::{
55
DepositRelationWithFullInput, DepositRelationWithPublicInput, DepositRelationWithoutInput,
66
FrontendAccount, FrontendLeafIndex, FrontendMerklePath, FrontendMerkleRoot, FrontendNote,
77
FrontendNullifier, FrontendTokenAmount, FrontendTokenId, FrontendTrapdoor, GetPublicInput,
8-
LinearEquationRelation, MerkleTreeRelation, Result as R1CsResult, Root,
9-
WithdrawRelationWithFullInput, WithdrawRelationWithPublicInput, WithdrawRelationWithoutInput,
10-
XorRelationWithFullInput, XorRelationWithPublicInput,
8+
LinearEquationRelationWithFullInput, LinearEquationRelationWithPublicInput, MerkleTreeRelation,
9+
Result as R1CsResult, Root, WithdrawRelationWithFullInput, WithdrawRelationWithPublicInput,
10+
WithdrawRelationWithoutInput, XorRelationWithFullInput, XorRelationWithPublicInput,
1111
};
1212

1313
use crate::snark_relations::parsing::{
@@ -208,7 +208,7 @@ impl ConstraintSynthesizer<CircuitField> for RelationArgs {
208208
.generate_constraints(cs),
209209

210210
RelationArgs::LinearEquation { a, x, b, y } => {
211-
LinearEquationRelation::with_full_input(a, x, b, y).generate_constraints(cs)
211+
LinearEquationRelationWithFullInput::new(a, x, b, y).generate_constraints(cs)
212212
}
213213

214214
RelationArgs::MerkleTree {
@@ -339,7 +339,7 @@ impl GetPublicInput<CircuitField> for RelationArgs {
339339
} => XorRelationWithPublicInput::new(*result, *public_xoree).serialize_public_input(),
340340

341341
RelationArgs::LinearEquation { a, b, y, .. } => {
342-
LinearEquationRelation::without_input(*a, *b, *y).public_input()
342+
LinearEquationRelationWithPublicInput::new(*a, *b, *y).serialize_public_input()
343343
}
344344

345345
RelationArgs::MerkleTree {

relations/src/lib.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@ pub use environment::{
1717
CircuitField, Groth16, Marlin, MarlinPolynomialCommitment, NonUniversalSystem, ProvingSystem,
1818
RawKeys, UniversalSystem, GM17,
1919
};
20-
pub use linear::LinearEquationRelation;
20+
pub use linear::{
21+
LinearEquationRelationWithFullInput, LinearEquationRelationWithPublicInput,
22+
LinearEquationRelationWithoutInput,
23+
};
2124
pub use merkle_tree::{MerkleTreeRelation, Root};
2225
#[cfg(any(feature = "preimage", feature = "preimage-std"))]
2326
pub use preimage::PreimageRelation;

relations/src/linear.rs

Lines changed: 74 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,82 +1,93 @@
1-
use ark_ff::PrimeField;
2-
use ark_r1cs_std::{
3-
prelude::{AllocVar, EqGadget},
4-
uint32::UInt32,
5-
};
6-
use ark_relations::r1cs::{
7-
ConstraintSynthesizer, ConstraintSystemRef, SynthesisError, SynthesisError::AssignmentMissing,
8-
};
9-
use ark_std::{marker::PhantomData, vec::Vec};
10-
11-
use crate::{
12-
relation::{
13-
state::{FullInput, NoInput, State},
14-
GetPublicInput,
15-
},
16-
CircuitField,
17-
};
1+
use snark_relation_proc_macro::snark_relation;
182

193
/// Linear equation relation: a*x + b = y
204
///
215
/// Relation with:
226
/// - 1 private witness (x)
23-
/// - 3 constants (a, b, y)
24-
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
25-
pub struct LinearEquationRelation<S: State> {
26-
/// constant (a slope)
27-
pub a: u32,
28-
/// private witness
29-
pub x: Option<u32>,
30-
/// constant(an intercept)
31-
pub b: u32,
32-
/// constant
33-
pub y: u32,
34-
35-
_phantom: PhantomData<S>,
36-
}
7+
/// - 3 constants (a, b, y)
8+
#[snark_relation]
9+
mod relation {
10+
use ark_r1cs_std::{alloc::AllocVar, eq::EqGadget, uint32::UInt32};
3711

38-
impl LinearEquationRelation<NoInput> {
39-
pub fn without_input(a: u32, b: u32, y: u32) -> Self {
40-
Self {
41-
a,
42-
x: None,
43-
b,
44-
y,
45-
_phantom: PhantomData,
46-
}
12+
#[relation_object_definition]
13+
struct LinearEquationRelation {
14+
/// slope
15+
#[constant]
16+
pub a: u32,
17+
/// private witness
18+
#[private_input]
19+
pub x: u32,
20+
/// an intercept
21+
#[constant]
22+
pub b: u32,
23+
/// constant
24+
#[constant]
25+
pub y: u32,
4726
}
48-
}
4927

50-
impl LinearEquationRelation<FullInput> {
51-
pub fn with_full_input(a: u32, x: u32, b: u32, y: u32) -> Self {
52-
Self {
53-
a,
54-
x: Some(x),
55-
b,
56-
y,
57-
_phantom: PhantomData,
58-
}
59-
}
60-
}
61-
62-
impl<Field: PrimeField, S: State> ConstraintSynthesizer<Field> for LinearEquationRelation<S> {
63-
fn generate_constraints(self, cs: ConstraintSystemRef<Field>) -> Result<(), SynthesisError> {
28+
#[circuit_definition]
29+
fn generate_constraints() {
6430
// TODO: migrate from real values to values in the finite field (see FpVar)
6531
// Watch out for overflows!!!
66-
let x = UInt32::new_witness(ark_relations::ns!(cs, "x"), || {
67-
self.x.ok_or(AssignmentMissing)
68-
})?;
69-
let b = UInt32::new_constant(ark_relations::ns!(cs, "b"), self.b)?;
70-
let y = UInt32::new_constant(ark_relations::ns!(cs, "y"), self.y)?;
32+
let x = UInt32::new_witness(ark_relations::ns!(cs, "x"), || self.x())?;
33+
let b = UInt32::new_constant(ark_relations::ns!(cs, "b"), self.b())?;
34+
let y = UInt32::new_constant(ark_relations::ns!(cs, "y"), self.y())?;
7135

7236
let mut left = ark_std::iter::repeat(x)
73-
.take(self.a as usize)
74-
.collect::<Vec<UInt32<Field>>>();
37+
.take(*self.a() as usize)
38+
.collect::<Vec<UInt32<_>>>();
7539

7640
left.push(b);
7741

7842
UInt32::addmany(&left)?.enforce_equal(&y)
7943
}
8044
}
8145

82-
impl<S: State> GetPublicInput<CircuitField> for LinearEquationRelation<S> {}
46+
#[cfg(test)]
47+
mod tests {
48+
use ark_bls12_381::Bls12_381;
49+
use ark_groth16::Groth16;
50+
use ark_relations::r1cs::{ConstraintSynthesizer, ConstraintSystem, ConstraintSystemRef};
51+
use ark_snark::SNARK;
52+
53+
use super::*;
54+
use crate::CircuitField;
55+
56+
const A: u32 = 2;
57+
const X: u32 = 1;
58+
const B: u32 = 1;
59+
const Y: u32 = 3;
60+
61+
#[test]
62+
fn linear_constraints_correctness() {
63+
let circuit = LinearEquationRelationWithFullInput::new(A, B, Y, X);
64+
65+
let cs: ConstraintSystemRef<CircuitField> = ConstraintSystem::new_ref();
66+
circuit.generate_constraints(cs.clone()).unwrap();
67+
68+
let is_satisfied = cs.is_satisfied().unwrap();
69+
if !is_satisfied {
70+
println!("{:?}", cs.which_is_unsatisfied());
71+
}
72+
73+
assert!(is_satisfied);
74+
}
75+
76+
#[test]
77+
fn linear_proving_procedure() {
78+
let circuit_wo_input = LinearEquationRelationWithoutInput::new(A, B, Y);
79+
80+
let mut rng = ark_std::test_rng();
81+
let (pk, vk) =
82+
Groth16::<Bls12_381>::circuit_specific_setup(circuit_wo_input, &mut rng).unwrap();
83+
84+
let circuit_with_public_input = LinearEquationRelationWithPublicInput::new(A, B, Y);
85+
let input = circuit_with_public_input.serialize_public_input();
86+
87+
let circuit_with_full_input = LinearEquationRelationWithFullInput::new(A, B, Y, X);
88+
89+
let proof = Groth16::prove(&pk, circuit_with_full_input, &mut rng).unwrap();
90+
let valid_proof = Groth16::verify(&vk, &input, &proof).unwrap();
91+
assert!(valid_proof);
92+
}
93+
}

relations/src/xor.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,6 @@ mod relation {
1313

1414
use crate::byte_to_bits;
1515

16-
#[circuit_field]
17-
pub type CircuitField = crate::CircuitField;
18-
1916
#[relation_object_definition]
2017
struct XorRelation {
2118
// ToDo: Especially for Groth16, it is better to provide public input as a field element.

0 commit comments

Comments
 (0)