Skip to content

Commit 48b1dfa

Browse files
authored
Merge pull request #217 from dalek-cryptography/api-fix
Update API
2 parents 776565e + 5fdb18c commit 48b1dfa

File tree

8 files changed

+155
-129
lines changed

8 files changed

+155
-129
lines changed

benches/r1cs.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -79,30 +79,30 @@ impl KShuffleGadget {
7979

8080
let k = x.len();
8181
if k == 1 {
82-
cs.add_auxiliary_constraint([(x[0], -one), (y[0], one)].iter().collect());
82+
cs.constrain([(x[0], -one), (y[0], one)].iter().collect());
8383
return;
8484
}
8585

8686
// Make last x multiplier for i = k-1 and k-2
87-
let (_, _, last_mulx_out) = cs.add_partial_constraint(x[k - 1] - z, x[k - 2] - z);
87+
let (_, _, last_mulx_out) = cs.multiply(x[k - 1] - z, x[k - 2] - z);
8888

8989
// Make multipliers for x from i == [0, k-3]
9090
let first_mulx_out = (0..k - 2).rev().fold(last_mulx_out, |prev_out, i| {
91-
let (_, _, o) = cs.add_partial_constraint(prev_out.into(), x[i] - z);
91+
let (_, _, o) = cs.multiply(prev_out.into(), x[i] - z);
9292
o
9393
});
9494

9595
// Make last y multiplier for i = k-1 and k-2
96-
let (_, _, last_muly_out) = cs.add_partial_constraint(y[k - 1] - z, y[k - 2] - z);
96+
let (_, _, last_muly_out) = cs.multiply(y[k - 1] - z, y[k - 2] - z);
9797

9898
// Make multipliers for y from i == [0, k-3]
9999
let first_muly_out = (0..k - 2).rev().fold(last_muly_out, |prev_out, i| {
100-
let (_, _, o) = cs.add_partial_constraint(prev_out.into(), y[i] - z);
100+
let (_, _, o) = cs.multiply(prev_out.into(), y[i] - z);
101101
o
102102
});
103103

104-
// Check equality between last x mul output and last y mul output
105-
cs.add_auxiliary_constraint(
104+
// Constrain last x mul output and last y mul output to be equal
105+
cs.constrain(
106106
[(first_muly_out, -one), (first_mulx_out, one)]
107107
.iter()
108108
.collect(),

src/errors.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,4 +104,10 @@ pub enum R1CSError {
104104
/// [`R1CSProof`](::r1cs::R1CSProof) fails.
105105
#[fail(display = "R1CSProof did not verify correctly.")]
106106
VerificationError,
107+
108+
/// Occurs when trying to use a missing variable assignment.
109+
/// Used by gadgets that build the constraint system to signal that
110+
/// a variable assignment is not provided when the prover needs it.
111+
#[fail(display = "Variable does not have a value assignment.")]
112+
MissingAssignment,
107113
}

src/r1cs/constraint_system.rs

Lines changed: 15 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! Definition of the constraint system trait.
22
3-
use super::{LinearCombination, Variable};
3+
use super::{LinearCombination, R1CSError, Variable};
44
use curve25519_dalek::scalar::Scalar;
55

66
/// The interface for a constraint system, abstracting over the prover
@@ -16,50 +16,42 @@ use curve25519_dalek::scalar::Scalar;
1616
/// using the `ConstraintSystem` trait, so that the prover and
1717
/// verifier share the logic for specifying constraints.
1818
pub trait ConstraintSystem {
19+
/// Allocate and constrain multiplication variables.
20+
///
1921
/// Allocate variables `left`, `right`, and `out`
2022
/// with the implicit constraint that
2123
/// ```text
2224
/// left * right = out
2325
/// ```
24-
/// and the explicit constraints that
26+
/// and add the explicit constraints that
2527
/// ```text
2628
/// left = left_constraint
2729
/// right = right_constraint
28-
/// out = out_constraint
2930
/// ```
30-
/// This is used when all three multiplier variables can be constrained up-front.
3131
///
3232
/// Returns `(left, right, out)` for use in further constraints.
33-
fn add_constraint(
33+
fn multiply(
3434
&mut self,
35-
left_constraint: LinearCombination,
36-
right_constraint: LinearCombination,
37-
out_constraint: LinearCombination,
35+
left: LinearCombination,
36+
right: LinearCombination,
3837
) -> (Variable, Variable, Variable);
3938

4039
/// Allocate variables `left`, `right`, and `out`
4140
/// with the implicit constraint that
4241
/// ```text
4342
/// left * right = out
4443
/// ```
45-
/// and the explicit constraints that
46-
/// ```text
47-
/// left = left_constraint
48-
/// right = right_constraint
49-
/// ```
50-
/// This is used when the output variable cannot be immediately
51-
/// constrained (for instance, because it should be constrained to
52-
/// match a variable that has not yet been allocated).
5344
///
5445
/// Returns `(left, right, out)` for use in further constraints.
55-
fn add_partial_constraint(
56-
&mut self,
57-
left: LinearCombination,
58-
right: LinearCombination,
59-
) -> (Variable, Variable, Variable);
46+
fn allocate<F>(&mut self, assign_fn: F) -> Result<(Variable, Variable, Variable), R1CSError>
47+
where
48+
F: FnOnce() -> Result<(Scalar, Scalar, Scalar), R1CSError>;
6049

61-
/// Enforce that the given `LinearCombination` is zero.
62-
fn add_auxiliary_constraint(&mut self, lc: LinearCombination);
50+
/// Enforce the explicit constraint that
51+
/// ```text
52+
/// lc = 0
53+
/// ```
54+
fn constrain(&mut self, lc: LinearCombination);
6355

6456
/// Obtain a challenge scalar bound to the assignments of all of
6557
/// the externally committed wires.

src/r1cs/linear_combination.rs

Lines changed: 91 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
//! Definition of linear combinations.
22
33
use curve25519_dalek::scalar::Scalar;
4-
use std::iter::{self, FromIterator};
5-
use std::ops::{Add, Sub};
4+
use std::iter::FromIterator;
5+
use std::ops::{Add, Mul, Neg, Sub};
66

77
/// Represents a variable in a constraint system.
88
#[derive(Copy, Clone, Debug)]
@@ -19,62 +19,86 @@ pub enum Variable {
1919
One(),
2020
}
2121

22-
impl Add<Variable> for Variable {
23-
type Output = LinearCombination;
22+
impl From<Variable> for LinearCombination {
23+
fn from(v: Variable) -> LinearCombination {
24+
LinearCombination {
25+
terms: vec![(v, Scalar::one())],
26+
}
27+
}
28+
}
2429

25-
fn add(self, other: Variable) -> LinearCombination {
30+
impl<S: Into<Scalar>> From<S> for LinearCombination {
31+
fn from(s: S) -> LinearCombination {
2632
LinearCombination {
27-
terms: vec![(self, Scalar::one()), (other, Scalar::one())],
33+
terms: vec![(Variable::One(), s.into())],
2834
}
2935
}
3036
}
3137

32-
impl Sub<Variable> for Variable {
38+
// Arithmetic on variables produces linear combinations
39+
40+
impl Neg for Variable {
3341
type Output = LinearCombination;
3442

35-
fn sub(self, other: Variable) -> LinearCombination {
36-
LinearCombination {
37-
terms: vec![(self, Scalar::one()), (other, -Scalar::one())],
38-
}
43+
fn neg(self) -> Self::Output {
44+
-LinearCombination::from(self)
3945
}
4046
}
4147

42-
impl Add<Variable> for Scalar {
48+
impl<L: Into<LinearCombination>> Add<L> for Variable {
4349
type Output = LinearCombination;
4450

45-
fn add(self, other: Variable) -> LinearCombination {
51+
fn add(self, other: L) -> Self::Output {
52+
LinearCombination::from(self) + other.into()
53+
}
54+
}
55+
56+
impl<L: Into<LinearCombination>> Sub<L> for Variable {
57+
type Output = LinearCombination;
58+
59+
fn sub(self, other: L) -> Self::Output {
60+
LinearCombination::from(self) - other.into()
61+
}
62+
}
63+
64+
impl<S: Into<Scalar>> Mul<S> for Variable {
65+
type Output = LinearCombination;
66+
67+
fn mul(self, other: S) -> Self::Output {
4668
LinearCombination {
47-
terms: vec![(Variable::One(), self), (other, Scalar::one())],
69+
terms: vec![(self, other.into())],
4870
}
4971
}
5072
}
5173

52-
impl Sub<Variable> for Scalar {
74+
// Arithmetic on scalars with variables produces linear combinations
75+
76+
impl Add<Variable> for Scalar {
5377
type Output = LinearCombination;
5478

55-
fn sub(self, other: Variable) -> LinearCombination {
79+
fn add(self, other: Variable) -> Self::Output {
5680
LinearCombination {
57-
terms: vec![(Variable::One(), self), (other, -Scalar::one())],
81+
terms: vec![(Variable::One(), self), (other, Scalar::one())],
5882
}
5983
}
6084
}
6185

62-
impl Add<Scalar> for Variable {
86+
impl Sub<Variable> for Scalar {
6387
type Output = LinearCombination;
6488

65-
fn add(self, other: Scalar) -> LinearCombination {
89+
fn sub(self, other: Variable) -> Self::Output {
6690
LinearCombination {
67-
terms: vec![(self, Scalar::one()), (Variable::One(), other)],
91+
terms: vec![(Variable::One(), self), (other, -Scalar::one())],
6892
}
6993
}
7094
}
7195

72-
impl Sub<Scalar> for Variable {
96+
impl Mul<Variable> for Scalar {
7397
type Output = LinearCombination;
7498

75-
fn sub(self, other: Scalar) -> LinearCombination {
99+
fn mul(self, other: Variable) -> Self::Output {
76100
LinearCombination {
77-
terms: vec![(self, Scalar::one()), (Variable::One(), -other)],
101+
terms: vec![(other, self)],
78102
}
79103
}
80104
}
@@ -93,18 +117,6 @@ impl Default for LinearCombination {
93117
}
94118
}
95119

96-
impl From<Scalar> for LinearCombination {
97-
fn from(s: Scalar) -> Self {
98-
iter::once((Variable::One(), s)).collect()
99-
}
100-
}
101-
102-
impl From<Variable> for LinearCombination {
103-
fn from(v: Variable) -> Self {
104-
iter::once((v, Scalar::one())).collect()
105-
}
106-
}
107-
108120
impl FromIterator<(Variable, Scalar)> for LinearCombination {
109121
fn from_iter<T>(iter: T) -> Self
110122
where
@@ -127,21 +139,59 @@ impl<'a> FromIterator<&'a (Variable, Scalar)> for LinearCombination {
127139
}
128140
}
129141

130-
impl Add<LinearCombination> for LinearCombination {
142+
// Arithmetic on linear combinations
143+
144+
impl<L: Into<LinearCombination>> Add<L> for LinearCombination {
131145
type Output = Self;
132146

133-
fn add(mut self, rhs: LinearCombination) -> Self {
134-
self.terms.extend(rhs.terms.iter().cloned());
147+
fn add(mut self, rhs: L) -> Self::Output {
148+
self.terms.extend(rhs.into().terms.iter().cloned());
135149
LinearCombination { terms: self.terms }
136150
}
137151
}
138152

139-
impl Sub<LinearCombination> for LinearCombination {
153+
impl<L: Into<LinearCombination>> Sub<L> for LinearCombination {
140154
type Output = Self;
141155

142-
fn sub(mut self, rhs: LinearCombination) -> Self {
156+
fn sub(mut self, rhs: L) -> Self::Output {
143157
self.terms
144-
.extend(rhs.terms.iter().map(|(var, coeff)| (*var, -coeff)));
158+
.extend(rhs.into().terms.iter().map(|(var, coeff)| (*var, -coeff)));
145159
LinearCombination { terms: self.terms }
146160
}
147161
}
162+
163+
impl Mul<LinearCombination> for Scalar {
164+
type Output = LinearCombination;
165+
166+
fn mul(self, other: LinearCombination) -> Self::Output {
167+
let out_terms = other
168+
.terms
169+
.into_iter()
170+
.map(|(var, scalar)| (var, scalar * self))
171+
.collect();
172+
LinearCombination { terms: out_terms }
173+
}
174+
}
175+
176+
impl Neg for LinearCombination {
177+
type Output = Self;
178+
179+
fn neg(mut self) -> Self::Output {
180+
for (_, s) in self.terms.iter_mut() {
181+
*s = -*s
182+
}
183+
self
184+
}
185+
}
186+
187+
impl<S: Into<Scalar>> Mul<S> for LinearCombination {
188+
type Output = Self;
189+
190+
fn mul(mut self, other: S) -> Self::Output {
191+
let other = other.into();
192+
for (_, s) in self.terms.iter_mut() {
193+
*s *= other
194+
}
195+
self
196+
}
197+
}

src/r1cs/mod.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -79,30 +79,30 @@
7979
//!
8080
//! let k = x.len();
8181
//! if k == 1 {
82-
//! cs.add_auxiliary_constraint([(x[0], -one), (y[0], one)].iter().collect());
82+
//! cs.constrain([(x[0], -one), (y[0], one)].iter().collect());
8383
//! return;
8484
//! }
8585
//!
8686
//! // Make last x multiplier for i = k-1 and k-2
87-
//! let (_, _, last_mulx_out) = cs.add_partial_constraint(x[k - 1] - z, x[k - 2] - z);
87+
//! let (_, _, last_mulx_out) = cs.multiply(x[k - 1] - z, x[k - 2] - z);
8888
//!
8989
//! // Make multipliers for x from i == [0, k-3]
9090
//! let first_mulx_out = (0..k - 2).rev().fold(last_mulx_out, |prev_out, i| {
91-
//! let (_, _, o) = cs.add_partial_constraint(prev_out.into(), x[i] - z);
91+
//! let (_, _, o) = cs.multiply(prev_out.into(), x[i] - z);
9292
//! o
9393
//! });
9494
//!
9595
//! // Make last y multiplier for i = k-1 and k-2
96-
//! let (_, _, last_muly_out) = cs.add_partial_constraint(y[k - 1] - z, y[k - 2] - z);
96+
//! let (_, _, last_muly_out) = cs.multiply(y[k - 1] - z, y[k - 2] - z);
9797
//!
9898
//! // Make multipliers for y from i == [0, k-3]
9999
//! let first_muly_out = (0..k - 2).rev().fold(last_muly_out, |prev_out, i| {
100-
//! let (_, _, o) = cs.add_partial_constraint(prev_out.into(), y[i] - z);
100+
//! let (_, _, o) = cs.multiply(prev_out.into(), y[i] - z);
101101
//! o
102102
//! });
103103
//!
104-
//! // Check equality between last x mul output and last y mul output
105-
//! cs.add_auxiliary_constraint(
104+
//! // Constrain last x mul output and last y mul output to be equal
105+
//! cs.constrain(
106106
//! [(first_muly_out, -one), (first_mulx_out, one)]
107107
//! .iter()
108108
//! .collect(),

0 commit comments

Comments
 (0)