mirror of
https://github.com/arnaucube/Nova.git
synced 2026-01-11 08:31:29 +01:00
chore: update to ff/group 0.13 (#166)
* chore: update to ff/group 0.13 and associated dependencies Updates: - zkcrypto/ff, zkcrypto/group to 0.13, - bellperson to 0.25, - pasta_curves to 0.5.1, and removes the fil_pasta_curves fork - pasta-msm should no longer need a fork (WIP) Adapts source in function, mostly for const usage and API updates. * expose the portable feature of pasta-MSM * update pointer to pasta-msm * Clippy --------- Co-authored-by: François Garillot <francois@garillot.net>
This commit is contained in:
12
Cargo.toml
12
Cargo.toml
@@ -11,8 +11,8 @@ license-file = "LICENSE"
|
|||||||
keywords = ["zkSNARKs", "cryptography", "proofs"]
|
keywords = ["zkSNARKs", "cryptography", "proofs"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bellperson = { version = "0.24", default-features = false }
|
bellperson = { version = "0.25", default-features = false }
|
||||||
ff = { version = "0.12.0", features = ["derive"] }
|
ff = { version = "0.13.0", features = ["derive"] }
|
||||||
digest = "0.8.1"
|
digest = "0.8.1"
|
||||||
sha3 = "0.8.2"
|
sha3 = "0.8.2"
|
||||||
rayon = "1.3.0"
|
rayon = "1.3.0"
|
||||||
@@ -20,8 +20,8 @@ rand_core = { version = "0.6.0", default-features = false }
|
|||||||
rand_chacha = "0.3"
|
rand_chacha = "0.3"
|
||||||
itertools = "0.9.0"
|
itertools = "0.9.0"
|
||||||
subtle = "2.4"
|
subtle = "2.4"
|
||||||
pasta_curves = { version = "0.5.2", features = ["repr-c", "serde"], package = "fil_pasta_curves" }
|
pasta_curves = { version = "0.5", features = ["repr-c", "serde"] }
|
||||||
neptune = { version = "8.1.0", default-features = false }
|
neptune = { version = "9.0.0", default-features = false }
|
||||||
generic-array = "0.14.4"
|
generic-array = "0.14.4"
|
||||||
num-bigint = { version = "0.4", features = ["serde", "rand"] }
|
num-bigint = { version = "0.4", features = ["serde", "rand"] }
|
||||||
num-traits = "0.2"
|
num-traits = "0.2"
|
||||||
@@ -34,7 +34,7 @@ byteorder = "1.4.3"
|
|||||||
thiserror = "1.0"
|
thiserror = "1.0"
|
||||||
|
|
||||||
[target.'cfg(any(target_arch = "x86_64", target_arch = "aarch64"))'.dependencies]
|
[target.'cfg(any(target_arch = "x86_64", target_arch = "aarch64"))'.dependencies]
|
||||||
pasta-msm = { version = "0.1.0", package = "lurk-pasta-msm" }
|
pasta-msm = { version = "0.1.4" }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
criterion = "0.3.1"
|
criterion = "0.3.1"
|
||||||
@@ -51,5 +51,7 @@ harness = false
|
|||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = []
|
default = []
|
||||||
|
# Compiles in portable mode, w/o ISA extensions => binary can be executed on all systems.
|
||||||
|
portable = ["pasta-msm/portable"]
|
||||||
cuda = ["neptune/cuda", "neptune/pasta", "neptune/arity24"]
|
cuda = ["neptune/cuda", "neptune/pasta", "neptune/arity24"]
|
||||||
opencl = ["neptune/opencl", "neptune/pasta", "neptune/arity24"]
|
opencl = ["neptune/opencl", "neptune/pasta", "neptune/arity24"]
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn mul_bits<B: AsRef<[u64]>>(s: &G::Scalar, bits: BitIterator<B>) -> G::Scalar {
|
fn mul_bits<B: AsRef<[u64]>>(s: &G::Scalar, bits: BitIterator<B>) -> G::Scalar {
|
||||||
let mut x = G::Scalar::zero();
|
let mut x = G::Scalar::ZERO;
|
||||||
for bit in bits {
|
for bit in bits {
|
||||||
x = x.double();
|
x = x.double();
|
||||||
|
|
||||||
@@ -88,14 +88,14 @@ where
|
|||||||
assert_eq!(digest.len(), 64);
|
assert_eq!(digest.len(), 64);
|
||||||
let mut bits: [u64; 8] = [0; 8];
|
let mut bits: [u64; 8] = [0; 8];
|
||||||
LittleEndian::read_u64_into(digest, &mut bits);
|
LittleEndian::read_u64_into(digest, &mut bits);
|
||||||
Self::mul_bits(&G::Scalar::one(), BitIterator::new(bits))
|
Self::mul_bits(&G::Scalar::ONE, BitIterator::new(bits))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_uniform_32(digest: &[u8]) -> G::Scalar {
|
pub fn to_uniform_32(digest: &[u8]) -> G::Scalar {
|
||||||
assert_eq!(digest.len(), 32);
|
assert_eq!(digest.len(), 32);
|
||||||
let mut bits: [u64; 4] = [0; 4];
|
let mut bits: [u64; 4] = [0; 4];
|
||||||
LittleEndian::read_u64_into(digest, &mut bits);
|
LittleEndian::read_u64_into(digest, &mut bits);
|
||||||
Self::mul_bits(&G::Scalar::one(), BitIterator::new(bits))
|
Self::mul_bits(&G::Scalar::ONE, BitIterator::new(bits))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn hash_to_scalar(persona: &[u8], a: &[u8], b: &[u8]) -> G::Scalar {
|
pub fn hash_to_scalar(persona: &[u8], a: &[u8], b: &[u8]) -> G::Scalar {
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ mod tests {
|
|||||||
cs: &mut CS,
|
cs: &mut CS,
|
||||||
) -> Result<(), SynthesisError> {
|
) -> Result<(), SynthesisError> {
|
||||||
// get two bits as input and check that they are indeed bits
|
// get two bits as input and check that they are indeed bits
|
||||||
let a = AllocatedNum::alloc(cs.namespace(|| "a"), || Ok(Fr::one()))?;
|
let a = AllocatedNum::alloc(cs.namespace(|| "a"), || Ok(Fr::ONE))?;
|
||||||
let _ = a.inputize(cs.namespace(|| "a is input"));
|
let _ = a.inputize(cs.namespace(|| "a is input"));
|
||||||
cs.enforce(
|
cs.enforce(
|
||||||
|| "check a is 0 or 1",
|
|| "check a is 0 or 1",
|
||||||
@@ -28,7 +28,7 @@ mod tests {
|
|||||||
|lc| lc + a.get_variable(),
|
|lc| lc + a.get_variable(),
|
||||||
|lc| lc,
|
|lc| lc,
|
||||||
);
|
);
|
||||||
let b = AllocatedNum::alloc(cs.namespace(|| "b"), || Ok(Fr::one()))?;
|
let b = AllocatedNum::alloc(cs.namespace(|| "b"), || Ok(Fr::ONE))?;
|
||||||
let _ = b.inputize(cs.namespace(|| "b is input"));
|
let _ = b.inputize(cs.namespace(|| "b is input"));
|
||||||
cs.enforce(
|
cs.enforce(
|
||||||
|| "check b is 0 or 1",
|
|| "check b is 0 or 1",
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ fn add_constraint<S: PrimeField>(
|
|||||||
) {
|
) {
|
||||||
let (A, B, C, nn) = X;
|
let (A, B, C, nn) = X;
|
||||||
let n = **nn;
|
let n = **nn;
|
||||||
let one = S::one();
|
let one = S::ONE;
|
||||||
|
|
||||||
let add_constraint_component = |index: Index, coeff, V: &mut Vec<_>| {
|
let add_constraint_component = |index: Index, coeff, V: &mut Vec<_>| {
|
||||||
match index {
|
match index {
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ fn proc_lc<Scalar: PrimeField>(
|
|||||||
for (var, &coeff) in terms.iter() {
|
for (var, &coeff) in terms.iter() {
|
||||||
map
|
map
|
||||||
.entry(OrderedVariable(var))
|
.entry(OrderedVariable(var))
|
||||||
.or_insert_with(Scalar::zero)
|
.or_insert_with(|| Scalar::ZERO)
|
||||||
.add_assign(&coeff);
|
.add_assign(&coeff);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,7 +144,7 @@ where
|
|||||||
writeln!(s, "INPUT {}", &input).unwrap()
|
writeln!(s, "INPUT {}", &input).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
let negone = -<G::Scalar>::one();
|
let negone = -<G::Scalar>::ONE;
|
||||||
|
|
||||||
let powers_of_two = (0..G::Scalar::NUM_BITS)
|
let powers_of_two = (0..G::Scalar::NUM_BITS)
|
||||||
.map(|i| G::Scalar::from(2u64).pow_vartime([u64::from(i)]))
|
.map(|i| G::Scalar::from(2u64).pow_vartime([u64::from(i)]))
|
||||||
@@ -161,7 +161,7 @@ where
|
|||||||
}
|
}
|
||||||
is_first = false;
|
is_first = false;
|
||||||
|
|
||||||
if coeff != <G::Scalar>::one() && coeff != negone {
|
if coeff != <G::Scalar>::ONE && coeff != negone {
|
||||||
for (i, x) in powers_of_two.iter().enumerate() {
|
for (i, x) in powers_of_two.iter().enumerate() {
|
||||||
if x == &coeff {
|
if x == &coeff {
|
||||||
write!(s, "2^{i} . ").unwrap();
|
write!(s, "2^{i} . ").unwrap();
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ where
|
|||||||
type Root = Self;
|
type Root = Self;
|
||||||
|
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
let input_assignment = vec![G::Scalar::one()];
|
let input_assignment = vec![G::Scalar::ONE];
|
||||||
let mut d = DensityTracker::new();
|
let mut d = DensityTracker::new();
|
||||||
d.add_element();
|
d.add_element();
|
||||||
|
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ impl<G: Group, SC: StepCircuit<G::Base>> NovaAugmentedCircuit<G, SC> {
|
|||||||
.collect::<Result<Vec<AllocatedNum<G::Base>>, _>>()?;
|
.collect::<Result<Vec<AllocatedNum<G::Base>>, _>>()?;
|
||||||
|
|
||||||
// Allocate zi. If inputs.zi is not provided (base case) allocate default value 0
|
// Allocate zi. If inputs.zi is not provided (base case) allocate default value 0
|
||||||
let zero = vec![G::Base::zero(); arity];
|
let zero = vec![G::Base::ZERO; arity];
|
||||||
let z_i = (0..arity)
|
let z_i = (0..arity)
|
||||||
.map(|i| {
|
.map(|i| {
|
||||||
AllocatedNum::alloc(cs.namespace(|| format!("zi_{i}")), || {
|
AllocatedNum::alloc(cs.namespace(|| format!("zi_{i}")), || {
|
||||||
@@ -318,7 +318,7 @@ impl<G: Group, SC: StepCircuit<G::Base>> Circuit<<G as Group>::Base>
|
|||||||
|
|
||||||
// Compute i + 1
|
// Compute i + 1
|
||||||
let i_new = AllocatedNum::alloc(cs.namespace(|| "i + 1"), || {
|
let i_new = AllocatedNum::alloc(cs.namespace(|| "i + 1"), || {
|
||||||
Ok(*i.get_value().get()? + G::Base::one())
|
Ok(*i.get_value().get()? + G::Base::ONE)
|
||||||
})?;
|
})?;
|
||||||
cs.enforce(
|
cs.enforce(
|
||||||
|| "check i + 1",
|
|| "check i + 1",
|
||||||
@@ -417,7 +417,7 @@ mod tests {
|
|||||||
assert_eq!(cs.num_constraints(), 10347);
|
assert_eq!(cs.num_constraints(), 10347);
|
||||||
|
|
||||||
// Execute the base case for the primary
|
// Execute the base case for the primary
|
||||||
let zero1 = <<G2 as Group>::Base as Field>::zero();
|
let zero1 = <<G2 as Group>::Base as Field>::ZERO;
|
||||||
let mut cs1: SatisfyingAssignment<G1> = SatisfyingAssignment::new();
|
let mut cs1: SatisfyingAssignment<G1> = SatisfyingAssignment::new();
|
||||||
let inputs1: NovaAugmentedCircuitInputs<G2> = NovaAugmentedCircuitInputs::new(
|
let inputs1: NovaAugmentedCircuitInputs<G2> = NovaAugmentedCircuitInputs::new(
|
||||||
shape2.get_digest(),
|
shape2.get_digest(),
|
||||||
@@ -441,7 +441,7 @@ mod tests {
|
|||||||
assert!(shape1.is_sat(&ck1, &inst1, &witness1).is_ok());
|
assert!(shape1.is_sat(&ck1, &inst1, &witness1).is_ok());
|
||||||
|
|
||||||
// Execute the base case for the secondary
|
// Execute the base case for the secondary
|
||||||
let zero2 = <<G1 as Group>::Base as Field>::zero();
|
let zero2 = <<G1 as Group>::Base as Field>::ZERO;
|
||||||
let mut cs2: SatisfyingAssignment<G2> = SatisfyingAssignment::new();
|
let mut cs2: SatisfyingAssignment<G2> = SatisfyingAssignment::new();
|
||||||
let inputs2: NovaAugmentedCircuitInputs<G1> = NovaAugmentedCircuitInputs::new(
|
let inputs2: NovaAugmentedCircuitInputs<G1> = NovaAugmentedCircuitInputs::new(
|
||||||
shape1.get_digest(),
|
shape1.get_digest(),
|
||||||
|
|||||||
@@ -43,16 +43,16 @@ where
|
|||||||
CS: ConstraintSystem<G::Base>,
|
CS: ConstraintSystem<G::Base>,
|
||||||
{
|
{
|
||||||
let x = AllocatedNum::alloc(cs.namespace(|| "x"), || {
|
let x = AllocatedNum::alloc(cs.namespace(|| "x"), || {
|
||||||
Ok(coords.map_or(G::Base::zero(), |c| c.0))
|
Ok(coords.map_or(G::Base::ZERO, |c| c.0))
|
||||||
})?;
|
})?;
|
||||||
let y = AllocatedNum::alloc(cs.namespace(|| "y"), || {
|
let y = AllocatedNum::alloc(cs.namespace(|| "y"), || {
|
||||||
Ok(coords.map_or(G::Base::zero(), |c| c.1))
|
Ok(coords.map_or(G::Base::ZERO, |c| c.1))
|
||||||
})?;
|
})?;
|
||||||
let is_infinity = AllocatedNum::alloc(cs.namespace(|| "is_infinity"), || {
|
let is_infinity = AllocatedNum::alloc(cs.namespace(|| "is_infinity"), || {
|
||||||
Ok(if coords.map_or(true, |c| c.2) {
|
Ok(if coords.map_or(true, |c| c.2) {
|
||||||
G::Base::one()
|
G::Base::ONE
|
||||||
} else {
|
} else {
|
||||||
G::Base::zero()
|
G::Base::ZERO
|
||||||
})
|
})
|
||||||
})?;
|
})?;
|
||||||
cs.enforce(
|
cs.enforce(
|
||||||
@@ -177,9 +177,9 @@ where
|
|||||||
// NOT(NOT(self.is_ifninity) AND NOT(other.is_infinity))
|
// NOT(NOT(self.is_ifninity) AND NOT(other.is_infinity))
|
||||||
let at_least_one_inf = AllocatedNum::alloc(cs.namespace(|| "at least one inf"), || {
|
let at_least_one_inf = AllocatedNum::alloc(cs.namespace(|| "at least one inf"), || {
|
||||||
Ok(
|
Ok(
|
||||||
G::Base::one()
|
G::Base::ONE
|
||||||
- (G::Base::one() - *self.is_infinity.get_value().get()?)
|
- (G::Base::ONE - *self.is_infinity.get_value().get()?)
|
||||||
* (G::Base::one() - *other.is_infinity.get_value().get()?),
|
* (G::Base::ONE - *other.is_infinity.get_value().get()?),
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
cs.enforce(
|
cs.enforce(
|
||||||
@@ -193,7 +193,7 @@ where
|
|||||||
let x_diff_is_actual =
|
let x_diff_is_actual =
|
||||||
AllocatedNum::alloc(cs.namespace(|| "allocate x_diff_is_actual"), || {
|
AllocatedNum::alloc(cs.namespace(|| "allocate x_diff_is_actual"), || {
|
||||||
Ok(if *equal_x.get_value().get()? {
|
Ok(if *equal_x.get_value().get()? {
|
||||||
G::Base::one()
|
G::Base::ONE
|
||||||
} else {
|
} else {
|
||||||
*at_least_one_inf.get_value().get()?
|
*at_least_one_inf.get_value().get()?
|
||||||
})
|
})
|
||||||
@@ -215,9 +215,9 @@ where
|
|||||||
)?;
|
)?;
|
||||||
|
|
||||||
let lambda = AllocatedNum::alloc(cs.namespace(|| "lambda"), || {
|
let lambda = AllocatedNum::alloc(cs.namespace(|| "lambda"), || {
|
||||||
let x_diff_inv = if *x_diff_is_actual.get_value().get()? == G::Base::one() {
|
let x_diff_inv = if *x_diff_is_actual.get_value().get()? == G::Base::ONE {
|
||||||
// Set to default
|
// Set to default
|
||||||
G::Base::one()
|
G::Base::ONE
|
||||||
} else {
|
} else {
|
||||||
// Set to the actual inverse
|
// Set to the actual inverse
|
||||||
(*other.x.get_value().get()? - *self.x.get_value().get()?)
|
(*other.x.get_value().get()? - *self.x.get_value().get()?)
|
||||||
@@ -328,7 +328,7 @@ where
|
|||||||
// * (G::Base::from(2)) * self.y).invert().unwrap();
|
// * (G::Base::from(2)) * self.y).invert().unwrap();
|
||||||
/*************************************************************/
|
/*************************************************************/
|
||||||
|
|
||||||
// Compute tmp = (G::Base::one() + G::Base::one())* self.y ? self != inf : 1
|
// Compute tmp = (G::Base::ONE + G::Base::ONE)* self.y ? self != inf : 1
|
||||||
let tmp_actual = AllocatedNum::alloc(cs.namespace(|| "tmp_actual"), || {
|
let tmp_actual = AllocatedNum::alloc(cs.namespace(|| "tmp_actual"), || {
|
||||||
Ok(*self.y.get_value().get()? + *self.y.get_value().get()?)
|
Ok(*self.y.get_value().get()? + *self.y.get_value().get()?)
|
||||||
})?;
|
})?;
|
||||||
@@ -354,9 +354,9 @@ where
|
|||||||
);
|
);
|
||||||
|
|
||||||
let lambda = AllocatedNum::alloc(cs.namespace(|| "alloc lambda"), || {
|
let lambda = AllocatedNum::alloc(cs.namespace(|| "alloc lambda"), || {
|
||||||
let tmp_inv = if *self.is_infinity.get_value().get()? == G::Base::one() {
|
let tmp_inv = if *self.is_infinity.get_value().get()? == G::Base::ONE {
|
||||||
// Return default value 1
|
// Return default value 1
|
||||||
G::Base::one()
|
G::Base::ONE
|
||||||
} else {
|
} else {
|
||||||
// Return the actual inverse
|
// Return the actual inverse
|
||||||
(*tmp.get_value().get()?).invert().unwrap()
|
(*tmp.get_value().get()?).invert().unwrap()
|
||||||
@@ -622,7 +622,7 @@ where
|
|||||||
// allocate a free variable that an honest prover sets to lambda = (y2-y1)/(x2-x1)
|
// allocate a free variable that an honest prover sets to lambda = (y2-y1)/(x2-x1)
|
||||||
let lambda = AllocatedNum::alloc(cs.namespace(|| "lambda"), || {
|
let lambda = AllocatedNum::alloc(cs.namespace(|| "lambda"), || {
|
||||||
if *other.x.get_value().get()? == *self.x.get_value().get()? {
|
if *other.x.get_value().get()? == *self.x.get_value().get()? {
|
||||||
Ok(G::Base::one())
|
Ok(G::Base::ONE)
|
||||||
} else {
|
} else {
|
||||||
Ok(
|
Ok(
|
||||||
(*other.y.get_value().get()? - *self.y.get_value().get()?)
|
(*other.y.get_value().get()? - *self.y.get_value().get()?)
|
||||||
@@ -688,8 +688,8 @@ where
|
|||||||
let lambda = AllocatedNum::alloc(cs.namespace(|| "lambda"), || {
|
let lambda = AllocatedNum::alloc(cs.namespace(|| "lambda"), || {
|
||||||
let n = G::Base::from(3) * x_sq.get_value().get()? + G::get_curve_params().0;
|
let n = G::Base::from(3) * x_sq.get_value().get()? + G::get_curve_params().0;
|
||||||
let d = G::Base::from(2) * *self.y.get_value().get()?;
|
let d = G::Base::from(2) * *self.y.get_value().get()?;
|
||||||
if d == G::Base::zero() {
|
if d == G::Base::ZERO {
|
||||||
Ok(G::Base::one())
|
Ok(G::Base::ONE)
|
||||||
} else {
|
} else {
|
||||||
Ok(n * d.invert().unwrap())
|
Ok(n * d.invert().unwrap())
|
||||||
}
|
}
|
||||||
@@ -803,8 +803,8 @@ mod tests {
|
|||||||
} else {
|
} else {
|
||||||
// if self.x == other.x and self.y != other.y then return infinity
|
// if self.x == other.x and self.y != other.y then return infinity
|
||||||
Self {
|
Self {
|
||||||
x: G::Base::zero(),
|
x: G::Base::ZERO,
|
||||||
y: G::Base::zero(),
|
y: G::Base::ZERO,
|
||||||
is_infinity: true,
|
is_infinity: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -836,8 +836,8 @@ mod tests {
|
|||||||
pub fn double(&self) -> Self {
|
pub fn double(&self) -> Self {
|
||||||
if self.is_infinity {
|
if self.is_infinity {
|
||||||
return Self {
|
return Self {
|
||||||
x: G::Base::zero(),
|
x: G::Base::ZERO,
|
||||||
y: G::Base::zero(),
|
y: G::Base::ZERO,
|
||||||
is_infinity: true,
|
is_infinity: true,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -845,9 +845,7 @@ mod tests {
|
|||||||
let lambda = G::Base::from(3)
|
let lambda = G::Base::from(3)
|
||||||
* self.x
|
* self.x
|
||||||
* self.x
|
* self.x
|
||||||
* ((G::Base::one() + G::Base::one()) * self.y)
|
* ((G::Base::ONE + G::Base::ONE) * self.y).invert().unwrap();
|
||||||
.invert()
|
|
||||||
.unwrap();
|
|
||||||
let x = lambda * lambda - self.x - self.x;
|
let x = lambda * lambda - self.x - self.x;
|
||||||
let y = lambda * (self.x - x) - self.y;
|
let y = lambda * (self.x - x) - self.y;
|
||||||
Self {
|
Self {
|
||||||
@@ -859,8 +857,8 @@ mod tests {
|
|||||||
|
|
||||||
pub fn scalar_mul(&self, scalar: &G::Scalar) -> Self {
|
pub fn scalar_mul(&self, scalar: &G::Scalar) -> Self {
|
||||||
let mut res = Self {
|
let mut res = Self {
|
||||||
x: G::Base::zero(),
|
x: G::Base::ZERO,
|
||||||
y: G::Base::zero(),
|
y: G::Base::ZERO,
|
||||||
is_infinity: true,
|
is_infinity: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -985,12 +983,12 @@ mod tests {
|
|||||||
let a_p: Point<G1> = Point::new(
|
let a_p: Point<G1> = Point::new(
|
||||||
a.x.get_value().unwrap(),
|
a.x.get_value().unwrap(),
|
||||||
a.y.get_value().unwrap(),
|
a.y.get_value().unwrap(),
|
||||||
a.is_infinity.get_value().unwrap() == <G1 as Group>::Base::one(),
|
a.is_infinity.get_value().unwrap() == <G1 as Group>::Base::ONE,
|
||||||
);
|
);
|
||||||
let e_p: Point<G1> = Point::new(
|
let e_p: Point<G1> = Point::new(
|
||||||
e.x.get_value().unwrap(),
|
e.x.get_value().unwrap(),
|
||||||
e.y.get_value().unwrap(),
|
e.y.get_value().unwrap(),
|
||||||
e.is_infinity.get_value().unwrap() == <G1 as Group>::Base::one(),
|
e.is_infinity.get_value().unwrap() == <G1 as Group>::Base::ONE,
|
||||||
);
|
);
|
||||||
let e_new = a_p.scalar_mul(&s);
|
let e_new = a_p.scalar_mul(&s);
|
||||||
assert!(e_p.x == e_new.x && e_p.y == e_new.y);
|
assert!(e_p.x == e_new.x && e_p.y == e_new.y);
|
||||||
@@ -1025,12 +1023,12 @@ mod tests {
|
|||||||
let a_p: Point<G1> = Point::new(
|
let a_p: Point<G1> = Point::new(
|
||||||
a.x.get_value().unwrap(),
|
a.x.get_value().unwrap(),
|
||||||
a.y.get_value().unwrap(),
|
a.y.get_value().unwrap(),
|
||||||
a.is_infinity.get_value().unwrap() == <G1 as Group>::Base::one(),
|
a.is_infinity.get_value().unwrap() == <G1 as Group>::Base::ONE,
|
||||||
);
|
);
|
||||||
let e_p: Point<G1> = Point::new(
|
let e_p: Point<G1> = Point::new(
|
||||||
e.x.get_value().unwrap(),
|
e.x.get_value().unwrap(),
|
||||||
e.y.get_value().unwrap(),
|
e.y.get_value().unwrap(),
|
||||||
e.is_infinity.get_value().unwrap() == <G1 as Group>::Base::one(),
|
e.is_infinity.get_value().unwrap() == <G1 as Group>::Base::ONE,
|
||||||
);
|
);
|
||||||
let e_new = a_p.add(&a_p);
|
let e_new = a_p.add(&a_p);
|
||||||
assert!(e_p.x == e_new.x && e_p.y == e_new.y);
|
assert!(e_p.x == e_new.x && e_p.y == e_new.y);
|
||||||
@@ -1047,7 +1045,7 @@ mod tests {
|
|||||||
inputize_allocted_point(&a, cs.namespace(|| "inputize a")).unwrap();
|
inputize_allocted_point(&a, cs.namespace(|| "inputize a")).unwrap();
|
||||||
let mut b = a.clone();
|
let mut b = a.clone();
|
||||||
b.y = AllocatedNum::alloc(cs.namespace(|| "allocate negation of a"), || {
|
b.y = AllocatedNum::alloc(cs.namespace(|| "allocate negation of a"), || {
|
||||||
Ok(G::Base::zero())
|
Ok(G::Base::ZERO)
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
inputize_allocted_point(&b, cs.namespace(|| "inputize b")).unwrap();
|
inputize_allocted_point(&b, cs.namespace(|| "inputize b")).unwrap();
|
||||||
@@ -1070,7 +1068,7 @@ mod tests {
|
|||||||
let e_p: Point<G1> = Point::new(
|
let e_p: Point<G1> = Point::new(
|
||||||
e.x.get_value().unwrap(),
|
e.x.get_value().unwrap(),
|
||||||
e.y.get_value().unwrap(),
|
e.y.get_value().unwrap(),
|
||||||
e.is_infinity.get_value().unwrap() == <G1 as Group>::Base::one(),
|
e.is_infinity.get_value().unwrap() == <G1 as Group>::Base::ONE,
|
||||||
);
|
);
|
||||||
assert!(e_p.is_infinity);
|
assert!(e_p.is_infinity);
|
||||||
// Make sure that it is satisfiable
|
// Make sure that it is satisfiable
|
||||||
|
|||||||
@@ -249,7 +249,7 @@ impl<Scalar: PrimeField> BigNat<Scalar> {
|
|||||||
Ok(bignat)
|
Ok(bignat)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_limbs<CS: ConstraintSystem<Scalar>>(&self) -> Vec<Num<Scalar>> {
|
pub fn as_limbs(&self) -> Vec<Num<Scalar>> {
|
||||||
let mut limbs = Vec::new();
|
let mut limbs = Vec::new();
|
||||||
for (i, lc) in self.limbs.iter().enumerate() {
|
for (i, lc) in self.limbs.iter().enumerate() {
|
||||||
limbs.push(Num::new(
|
limbs.push(Num::new(
|
||||||
@@ -364,7 +364,7 @@ impl<Scalar: PrimeField> BigNat<Scalar> {
|
|||||||
let carry_bits = (((max_word.to_f64().unwrap() * 2.0).log2() - self.params.limb_width as f64)
|
let carry_bits = (((max_word.to_f64().unwrap() * 2.0).log2() - self.params.limb_width as f64)
|
||||||
.ceil()
|
.ceil()
|
||||||
+ 0.1) as usize;
|
+ 0.1) as usize;
|
||||||
let mut carry_in = Num::new(Some(Scalar::zero()), LinearCombination::zero());
|
let mut carry_in = Num::new(Some(Scalar::ZERO), LinearCombination::zero());
|
||||||
|
|
||||||
for i in 0..n {
|
for i in 0..n {
|
||||||
let carry = Num::alloc(cs.namespace(|| format!("carry value {i}")), || {
|
let carry = Num::alloc(cs.namespace(|| format!("carry value {i}")), || {
|
||||||
@@ -449,10 +449,7 @@ impl<Scalar: PrimeField> BigNat<Scalar> {
|
|||||||
self_grouped.equal_when_carried(cs.namespace(|| "grouped"), &other_grouped)
|
self_grouped.equal_when_carried(cs.namespace(|| "grouped"), &other_grouped)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add<CS: ConstraintSystem<Scalar>>(
|
pub fn add(&self, other: &Self) -> Result<BigNat<Scalar>, SynthesisError> {
|
||||||
&self,
|
|
||||||
other: &Self,
|
|
||||||
) -> Result<BigNat<Scalar>, SynthesisError> {
|
|
||||||
self.enforce_limb_width_agreement(other, "add")?;
|
self.enforce_limb_width_agreement(other, "add")?;
|
||||||
let n_limbs = max(self.params.n_limbs, other.params.n_limbs);
|
let n_limbs = max(self.params.n_limbs, other.params.n_limbs);
|
||||||
let max_word = &self.params.max_word + &other.params.max_word;
|
let max_word = &self.params.max_word + &other.params.max_word;
|
||||||
@@ -617,15 +614,15 @@ impl<Scalar: PrimeField> BigNat<Scalar> {
|
|||||||
pub fn group_limbs(&self, limbs_per_group: usize) -> BigNat<Scalar> {
|
pub fn group_limbs(&self, limbs_per_group: usize) -> BigNat<Scalar> {
|
||||||
let n_groups = (self.limbs.len() - 1) / limbs_per_group + 1;
|
let n_groups = (self.limbs.len() - 1) / limbs_per_group + 1;
|
||||||
let limb_values = self.limb_values.as_ref().map(|vs| {
|
let limb_values = self.limb_values.as_ref().map(|vs| {
|
||||||
let mut values: Vec<Scalar> = vec![Scalar::zero(); n_groups];
|
let mut values: Vec<Scalar> = vec![Scalar::ZERO; n_groups];
|
||||||
let mut shift = Scalar::one();
|
let mut shift = Scalar::ONE;
|
||||||
let limb_block = (0..self.params.limb_width).fold(Scalar::one(), |mut l, _| {
|
let limb_block = (0..self.params.limb_width).fold(Scalar::ONE, |mut l, _| {
|
||||||
l = l.double();
|
l = l.double();
|
||||||
l
|
l
|
||||||
});
|
});
|
||||||
for (i, v) in vs.iter().enumerate() {
|
for (i, v) in vs.iter().enumerate() {
|
||||||
if i % limbs_per_group == 0 {
|
if i % limbs_per_group == 0 {
|
||||||
shift = Scalar::one();
|
shift = Scalar::ONE;
|
||||||
}
|
}
|
||||||
let mut a = shift;
|
let mut a = shift;
|
||||||
a *= v;
|
a *= v;
|
||||||
@@ -636,14 +633,14 @@ impl<Scalar: PrimeField> BigNat<Scalar> {
|
|||||||
});
|
});
|
||||||
let limbs = {
|
let limbs = {
|
||||||
let mut limbs: Vec<LinearCombination<Scalar>> = vec![LinearCombination::zero(); n_groups];
|
let mut limbs: Vec<LinearCombination<Scalar>> = vec![LinearCombination::zero(); n_groups];
|
||||||
let mut shift = Scalar::one();
|
let mut shift = Scalar::ONE;
|
||||||
let limb_block = (0..self.params.limb_width).fold(Scalar::one(), |mut l, _| {
|
let limb_block = (0..self.params.limb_width).fold(Scalar::ONE, |mut l, _| {
|
||||||
l = l.double();
|
l = l.double();
|
||||||
l
|
l
|
||||||
});
|
});
|
||||||
for (i, limb) in self.limbs.iter().enumerate() {
|
for (i, limb) in self.limbs.iter().enumerate() {
|
||||||
if i % limbs_per_group == 0 {
|
if i % limbs_per_group == 0 {
|
||||||
shift = Scalar::one();
|
shift = Scalar::ONE;
|
||||||
}
|
}
|
||||||
limbs[i / limbs_per_group] =
|
limbs[i / limbs_per_group] =
|
||||||
std::mem::replace(&mut limbs[i / limbs_per_group], LinearCombination::zero())
|
std::mem::replace(&mut limbs[i / limbs_per_group], LinearCombination::zero())
|
||||||
@@ -689,7 +686,7 @@ impl<Scalar: PrimeField> Polynomial<Scalar> {
|
|||||||
let n_product_coeffs = self.coefficients.len() + other.coefficients.len() - 1;
|
let n_product_coeffs = self.coefficients.len() + other.coefficients.len() - 1;
|
||||||
let values = self.values.as_ref().and_then(|self_vs| {
|
let values = self.values.as_ref().and_then(|self_vs| {
|
||||||
other.values.as_ref().map(|other_vs| {
|
other.values.as_ref().map(|other_vs| {
|
||||||
let mut values: Vec<Scalar> = std::iter::repeat_with(Scalar::zero)
|
let mut values: Vec<Scalar> = std::iter::repeat_with(|| Scalar::ZERO)
|
||||||
.take(n_product_coeffs)
|
.take(n_product_coeffs)
|
||||||
.collect();
|
.collect();
|
||||||
for (self_i, self_v) in self_vs.iter().enumerate() {
|
for (self_i, self_v) in self_vs.iter().enumerate() {
|
||||||
@@ -711,14 +708,14 @@ impl<Scalar: PrimeField> Polynomial<Scalar> {
|
|||||||
coefficients,
|
coefficients,
|
||||||
values,
|
values,
|
||||||
};
|
};
|
||||||
let one = Scalar::one();
|
let one = Scalar::ONE;
|
||||||
let mut x = Scalar::zero();
|
let mut x = Scalar::ZERO;
|
||||||
for _ in 1..(n_product_coeffs + 1) {
|
for _ in 1..(n_product_coeffs + 1) {
|
||||||
x.add_assign(&one);
|
x.add_assign(&one);
|
||||||
cs.enforce(
|
cs.enforce(
|
||||||
|| format!("pointwise product @ {x:?}"),
|
|| format!("pointwise product @ {x:?}"),
|
||||||
|lc| {
|
|lc| {
|
||||||
let mut i = Scalar::one();
|
let mut i = Scalar::ONE;
|
||||||
self.coefficients.iter().fold(lc, |lc, c| {
|
self.coefficients.iter().fold(lc, |lc, c| {
|
||||||
let r = lc + (i, c);
|
let r = lc + (i, c);
|
||||||
i.mul_assign(&x);
|
i.mul_assign(&x);
|
||||||
@@ -726,7 +723,7 @@ impl<Scalar: PrimeField> Polynomial<Scalar> {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
|lc| {
|
|lc| {
|
||||||
let mut i = Scalar::one();
|
let mut i = Scalar::ONE;
|
||||||
other.coefficients.iter().fold(lc, |lc, c| {
|
other.coefficients.iter().fold(lc, |lc, c| {
|
||||||
let r = lc + (i, c);
|
let r = lc + (i, c);
|
||||||
i.mul_assign(&x);
|
i.mul_assign(&x);
|
||||||
@@ -734,7 +731,7 @@ impl<Scalar: PrimeField> Polynomial<Scalar> {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
|lc| {
|
|lc| {
|
||||||
let mut i = Scalar::one();
|
let mut i = Scalar::ONE;
|
||||||
product.coefficients.iter().fold(lc, |lc, c| {
|
product.coefficients.iter().fold(lc, |lc, c| {
|
||||||
let r = lc + (i, c);
|
let r = lc + (i, c);
|
||||||
i.mul_assign(&x);
|
i.mul_assign(&x);
|
||||||
@@ -752,7 +749,7 @@ impl<Scalar: PrimeField> Polynomial<Scalar> {
|
|||||||
other.values.as_ref().map(|other_vs| {
|
other.values.as_ref().map(|other_vs| {
|
||||||
(0..n_coeffs)
|
(0..n_coeffs)
|
||||||
.map(|i| {
|
.map(|i| {
|
||||||
let mut s = Scalar::zero();
|
let mut s = Scalar::ZERO;
|
||||||
if i < self_vs.len() {
|
if i < self_vs.len() {
|
||||||
s.add_assign(&self_vs[i]);
|
s.add_assign(&self_vs[i]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,9 +40,9 @@ impl<Scalar: PrimeField> Bit<Scalar> {
|
|||||||
|| "boolean",
|
|| "boolean",
|
||||||
|| {
|
|| {
|
||||||
if *value.grab()? {
|
if *value.grab()? {
|
||||||
Ok(Scalar::one())
|
Ok(Scalar::ONE)
|
||||||
} else {
|
} else {
|
||||||
Ok(Scalar::zero())
|
Ok(Scalar::ZERO)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
)?;
|
)?;
|
||||||
@@ -109,9 +109,9 @@ impl<Scalar: PrimeField> Num<Scalar> {
|
|||||||
|| format!("bit {i}"),
|
|| format!("bit {i}"),
|
||||||
|| {
|
|| {
|
||||||
let r = if *v.grab()?.get_bit(i).grab()? {
|
let r = if *v.grab()?.get_bit(i).grab()? {
|
||||||
Scalar::one()
|
Scalar::ONE
|
||||||
} else {
|
} else {
|
||||||
Scalar::zero()
|
Scalar::ZERO
|
||||||
};
|
};
|
||||||
Ok(r)
|
Ok(r)
|
||||||
},
|
},
|
||||||
@@ -132,7 +132,7 @@ impl<Scalar: PrimeField> Num<Scalar> {
|
|||||||
cs.enforce(
|
cs.enforce(
|
||||||
|| "last bit",
|
|| "last bit",
|
||||||
|mut lc| {
|
|mut lc| {
|
||||||
let mut f = Scalar::one();
|
let mut f = Scalar::ONE;
|
||||||
lc = lc + &self.num;
|
lc = lc + &self.num;
|
||||||
for v in bits.iter() {
|
for v in bits.iter() {
|
||||||
f = f.double();
|
f = f.double();
|
||||||
@@ -142,7 +142,7 @@ impl<Scalar: PrimeField> Num<Scalar> {
|
|||||||
},
|
},
|
||||||
|mut lc| {
|
|mut lc| {
|
||||||
lc = lc + CS::one();
|
lc = lc + CS::one();
|
||||||
let mut f = Scalar::one();
|
let mut f = Scalar::ONE;
|
||||||
lc = lc - &self.num;
|
lc = lc - &self.num;
|
||||||
for v in bits.iter() {
|
for v in bits.iter() {
|
||||||
f = f.double();
|
f = f.double();
|
||||||
@@ -163,7 +163,7 @@ impl<Scalar: PrimeField> Num<Scalar> {
|
|||||||
other: &Bitvector<Scalar>,
|
other: &Bitvector<Scalar>,
|
||||||
) -> Result<(), SynthesisError> {
|
) -> Result<(), SynthesisError> {
|
||||||
let allocations = other.allocations.clone();
|
let allocations = other.allocations.clone();
|
||||||
let mut f = Scalar::one();
|
let mut f = Scalar::ONE;
|
||||||
let sum = allocations
|
let sum = allocations
|
||||||
.iter()
|
.iter()
|
||||||
.fold(LinearCombination::zero(), |lc, bit| {
|
.fold(LinearCombination::zero(), |lc, bit| {
|
||||||
@@ -196,7 +196,7 @@ impl<Scalar: PrimeField> Num<Scalar> {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
.collect::<Result<Vec<_>, _>>()?;
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
let mut f = Scalar::one();
|
let mut f = Scalar::ONE;
|
||||||
let sum = allocations
|
let sum = allocations
|
||||||
.iter()
|
.iter()
|
||||||
.fold(LinearCombination::zero(), |lc, bit| {
|
.fold(LinearCombination::zero(), |lc, bit| {
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ impl<G: Group> AllocatedRelaxedR1CSInstance<G> {
|
|||||||
cs.namespace(|| "allocate X[0]"),
|
cs.namespace(|| "allocate X[0]"),
|
||||||
|| {
|
|| {
|
||||||
Ok(f_to_nat(
|
Ok(f_to_nat(
|
||||||
&inst.clone().map_or(G::Scalar::zero(), |inst| inst.X[0]),
|
&inst.clone().map_or(G::Scalar::ZERO, |inst| inst.X[0]),
|
||||||
))
|
))
|
||||||
},
|
},
|
||||||
limb_width,
|
limb_width,
|
||||||
@@ -117,7 +117,7 @@ impl<G: Group> AllocatedRelaxedR1CSInstance<G> {
|
|||||||
cs.namespace(|| "allocate X[1]"),
|
cs.namespace(|| "allocate X[1]"),
|
||||||
|| {
|
|| {
|
||||||
Ok(f_to_nat(
|
Ok(f_to_nat(
|
||||||
&inst.clone().map_or(G::Scalar::zero(), |inst| inst.X[1]),
|
&inst.clone().map_or(G::Scalar::ZERO, |inst| inst.X[1]),
|
||||||
))
|
))
|
||||||
},
|
},
|
||||||
limb_width,
|
limb_width,
|
||||||
@@ -141,14 +141,14 @@ impl<G: Group> AllocatedRelaxedR1CSInstance<G> {
|
|||||||
|
|
||||||
let X0 = BigNat::alloc_from_nat(
|
let X0 = BigNat::alloc_from_nat(
|
||||||
cs.namespace(|| "allocate x_default[0]"),
|
cs.namespace(|| "allocate x_default[0]"),
|
||||||
|| Ok(f_to_nat(&G::Scalar::zero())),
|
|| Ok(f_to_nat(&G::Scalar::ZERO)),
|
||||||
limb_width,
|
limb_width,
|
||||||
n_limbs,
|
n_limbs,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let X1 = BigNat::alloc_from_nat(
|
let X1 = BigNat::alloc_from_nat(
|
||||||
cs.namespace(|| "allocate x_default[1]"),
|
cs.namespace(|| "allocate x_default[1]"),
|
||||||
|| Ok(f_to_nat(&G::Scalar::zero())),
|
|| Ok(f_to_nat(&G::Scalar::ZERO)),
|
||||||
limb_width,
|
limb_width,
|
||||||
n_limbs,
|
n_limbs,
|
||||||
)?;
|
)?;
|
||||||
@@ -208,7 +208,7 @@ impl<G: Group> AllocatedRelaxedR1CSInstance<G> {
|
|||||||
// Analyze X0 as limbs
|
// Analyze X0 as limbs
|
||||||
let X0_bn = self
|
let X0_bn = self
|
||||||
.X0
|
.X0
|
||||||
.as_limbs::<CS>()
|
.as_limbs()
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|(i, limb)| {
|
.map(|(i, limb)| {
|
||||||
@@ -224,7 +224,7 @@ impl<G: Group> AllocatedRelaxedR1CSInstance<G> {
|
|||||||
// Analyze X1 as limbs
|
// Analyze X1 as limbs
|
||||||
let X1_bn = self
|
let X1_bn = self
|
||||||
.X1
|
.X1
|
||||||
.as_limbs::<CS>()
|
.as_limbs()
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|(i, limb)| {
|
.map(|(i, limb)| {
|
||||||
@@ -310,7 +310,7 @@ impl<G: Group> AllocatedRelaxedR1CSInstance<G> {
|
|||||||
// Fold self.X[0] + r * X[0]
|
// Fold self.X[0] + r * X[0]
|
||||||
let (_, r_0) = X0_bn.mult_mod(cs.namespace(|| "r*X[0]"), &r_bn, &m_bn)?;
|
let (_, r_0) = X0_bn.mult_mod(cs.namespace(|| "r*X[0]"), &r_bn, &m_bn)?;
|
||||||
// add X_r[0]
|
// add X_r[0]
|
||||||
let r_new_0 = self.X0.add::<CS>(&r_0)?;
|
let r_new_0 = self.X0.add(&r_0)?;
|
||||||
// Now reduce
|
// Now reduce
|
||||||
let X0_fold = r_new_0.red_mod(cs.namespace(|| "reduce folded X[0]"), &m_bn)?;
|
let X0_fold = r_new_0.red_mod(cs.namespace(|| "reduce folded X[0]"), &m_bn)?;
|
||||||
|
|
||||||
@@ -325,7 +325,7 @@ impl<G: Group> AllocatedRelaxedR1CSInstance<G> {
|
|||||||
// Fold self.X[1] + r * X[1]
|
// Fold self.X[1] + r * X[1]
|
||||||
let (_, r_1) = X1_bn.mult_mod(cs.namespace(|| "r*X[1]"), &r_bn, &m_bn)?;
|
let (_, r_1) = X1_bn.mult_mod(cs.namespace(|| "r*X[1]"), &r_bn, &m_bn)?;
|
||||||
// add X_r[1]
|
// add X_r[1]
|
||||||
let r_new_1 = self.X1.add::<CS>(&r_1)?;
|
let r_new_1 = self.X1.add(&r_1)?;
|
||||||
// Now reduce
|
// Now reduce
|
||||||
let X1_fold = r_new_1.red_mod(cs.namespace(|| "reduce folded X[1]"), &m_bn)?;
|
let X1_fold = r_new_1.red_mod(cs.namespace(|| "reduce folded X[1]"), &m_bn)?;
|
||||||
|
|
||||||
|
|||||||
@@ -24,8 +24,8 @@ where
|
|||||||
// We loop over the input bits and construct the constraint
|
// We loop over the input bits and construct the constraint
|
||||||
// and the field element that corresponds to the result
|
// and the field element that corresponds to the result
|
||||||
let mut lc = LinearCombination::zero();
|
let mut lc = LinearCombination::zero();
|
||||||
let mut coeff = Scalar::one();
|
let mut coeff = Scalar::ONE;
|
||||||
let mut fe = Some(Scalar::zero());
|
let mut fe = Some(Scalar::ZERO);
|
||||||
for bit in bits.iter() {
|
for bit in bits.iter() {
|
||||||
lc = lc + (coeff, bit.get_variable());
|
lc = lc + (coeff, bit.get_variable());
|
||||||
fe = bit.get_value().map(|val| {
|
fe = bit.get_value().map(|val| {
|
||||||
@@ -49,7 +49,7 @@ where
|
|||||||
pub fn alloc_zero<F: PrimeField, CS: ConstraintSystem<F>>(
|
pub fn alloc_zero<F: PrimeField, CS: ConstraintSystem<F>>(
|
||||||
mut cs: CS,
|
mut cs: CS,
|
||||||
) -> Result<AllocatedNum<F>, SynthesisError> {
|
) -> Result<AllocatedNum<F>, SynthesisError> {
|
||||||
let zero = AllocatedNum::alloc(cs.namespace(|| "alloc"), || Ok(F::zero()))?;
|
let zero = AllocatedNum::alloc(cs.namespace(|| "alloc"), || Ok(F::ZERO))?;
|
||||||
cs.enforce(
|
cs.enforce(
|
||||||
|| "check zero is valid",
|
|| "check zero is valid",
|
||||||
|lc| lc,
|
|lc| lc,
|
||||||
@@ -63,7 +63,7 @@ pub fn alloc_zero<F: PrimeField, CS: ConstraintSystem<F>>(
|
|||||||
pub fn alloc_one<F: PrimeField, CS: ConstraintSystem<F>>(
|
pub fn alloc_one<F: PrimeField, CS: ConstraintSystem<F>>(
|
||||||
mut cs: CS,
|
mut cs: CS,
|
||||||
) -> Result<AllocatedNum<F>, SynthesisError> {
|
) -> Result<AllocatedNum<F>, SynthesisError> {
|
||||||
let one = AllocatedNum::alloc(cs.namespace(|| "alloc"), || Ok(F::one()))?;
|
let one = AllocatedNum::alloc(cs.namespace(|| "alloc"), || Ok(F::ONE))?;
|
||||||
cs.enforce(
|
cs.enforce(
|
||||||
|| "check one is valid",
|
|| "check one is valid",
|
||||||
|lc| lc + CS::one(),
|
|lc| lc + CS::one(),
|
||||||
@@ -85,9 +85,9 @@ where
|
|||||||
CS: ConstraintSystem<<G as Group>::Base>,
|
CS: ConstraintSystem<<G as Group>::Base>,
|
||||||
{
|
{
|
||||||
AllocatedNum::alloc(cs.namespace(|| "allocate scalar as base"), || {
|
AllocatedNum::alloc(cs.namespace(|| "allocate scalar as base"), || {
|
||||||
let input_bits = input.unwrap_or_else(G::Scalar::zero).clone().to_le_bits();
|
let input_bits = input.unwrap_or(G::Scalar::ZERO).clone().to_le_bits();
|
||||||
let mut mult = G::Base::one();
|
let mut mult = G::Base::ONE;
|
||||||
let mut val = G::Base::zero();
|
let mut val = G::Base::ZERO;
|
||||||
for bit in input_bits {
|
for bit in input_bits {
|
||||||
if bit {
|
if bit {
|
||||||
val += mult;
|
val += mult;
|
||||||
@@ -101,8 +101,8 @@ where
|
|||||||
/// interepret scalar as base
|
/// interepret scalar as base
|
||||||
pub fn scalar_as_base<G: Group>(input: G::Scalar) -> G::Base {
|
pub fn scalar_as_base<G: Group>(input: G::Scalar) -> G::Base {
|
||||||
let input_bits = input.to_le_bits();
|
let input_bits = input.to_le_bits();
|
||||||
let mut mult = G::Base::one();
|
let mut mult = G::Base::ONE;
|
||||||
let mut val = G::Base::zero();
|
let mut val = G::Base::ZERO;
|
||||||
for bit in input_bits {
|
for bit in input_bits {
|
||||||
if bit {
|
if bit {
|
||||||
val += mult;
|
val += mult;
|
||||||
@@ -159,7 +159,7 @@ pub fn alloc_num_equals<F: PrimeField, CS: ConstraintSystem<F>>(
|
|||||||
|
|
||||||
let t = AllocatedNum::alloc(cs.namespace(|| "t"), || {
|
let t = AllocatedNum::alloc(cs.namespace(|| "t"), || {
|
||||||
Ok(if *a.get_value().get()? == *b.get_value().get()? {
|
Ok(if *a.get_value().get()? == *b.get_value().get()? {
|
||||||
F::one()
|
F::ONE
|
||||||
} else {
|
} else {
|
||||||
(*a.get_value().get()? - *b.get_value().get()?)
|
(*a.get_value().get()? - *b.get_value().get()?)
|
||||||
.invert()
|
.invert()
|
||||||
@@ -204,7 +204,7 @@ pub fn conditionally_select<F: PrimeField, CS: ConstraintSystem<F>>(
|
|||||||
cs.enforce(
|
cs.enforce(
|
||||||
|| "conditional select constraint",
|
|| "conditional select constraint",
|
||||||
|lc| lc + a.get_variable() - b.get_variable(),
|
|lc| lc + a.get_variable() - b.get_variable(),
|
||||||
|_| condition.lc(CS::one(), F::one()),
|
|_| condition.lc(CS::one(), F::ONE),
|
||||||
|lc| lc + c.get_variable() - b.get_variable(),
|
|lc| lc + c.get_variable() - b.get_variable(),
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -254,7 +254,7 @@ pub fn conditionally_select_bignat<F: PrimeField, CS: ConstraintSystem<F>>(
|
|||||||
cs.enforce(
|
cs.enforce(
|
||||||
|| format!("conditional select constraint {i}"),
|
|| format!("conditional select constraint {i}"),
|
||||||
|lc| lc + &a.limbs[i] - &b.limbs[i],
|
|lc| lc + &a.limbs[i] - &b.limbs[i],
|
||||||
|_| condition.lc(CS::one(), F::one()),
|
|_| condition.lc(CS::one(), F::ONE),
|
||||||
|lc| lc + &c.limbs[i] - &b.limbs[i],
|
|lc| lc + &c.limbs[i] - &b.limbs[i],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -270,7 +270,7 @@ pub fn conditionally_select2<F: PrimeField, CS: ConstraintSystem<F>>(
|
|||||||
condition: &AllocatedNum<F>,
|
condition: &AllocatedNum<F>,
|
||||||
) -> Result<AllocatedNum<F>, SynthesisError> {
|
) -> Result<AllocatedNum<F>, SynthesisError> {
|
||||||
let c = AllocatedNum::alloc(cs.namespace(|| "conditional select result"), || {
|
let c = AllocatedNum::alloc(cs.namespace(|| "conditional select result"), || {
|
||||||
if *condition.get_value().get()? == F::one() {
|
if *condition.get_value().get()? == F::ONE {
|
||||||
Ok(*a.get_value().get()?)
|
Ok(*a.get_value().get()?)
|
||||||
} else {
|
} else {
|
||||||
Ok(*b.get_value().get()?)
|
Ok(*b.get_value().get()?)
|
||||||
@@ -296,8 +296,8 @@ pub fn select_zero_or_num2<F: PrimeField, CS: ConstraintSystem<F>>(
|
|||||||
condition: &AllocatedNum<F>,
|
condition: &AllocatedNum<F>,
|
||||||
) -> Result<AllocatedNum<F>, SynthesisError> {
|
) -> Result<AllocatedNum<F>, SynthesisError> {
|
||||||
let c = AllocatedNum::alloc(cs.namespace(|| "conditional select result"), || {
|
let c = AllocatedNum::alloc(cs.namespace(|| "conditional select result"), || {
|
||||||
if *condition.get_value().get()? == F::one() {
|
if *condition.get_value().get()? == F::ONE {
|
||||||
Ok(F::zero())
|
Ok(F::ZERO)
|
||||||
} else {
|
} else {
|
||||||
Ok(*a.get_value().get()?)
|
Ok(*a.get_value().get()?)
|
||||||
}
|
}
|
||||||
@@ -321,10 +321,10 @@ pub fn select_num_or_zero2<F: PrimeField, CS: ConstraintSystem<F>>(
|
|||||||
condition: &AllocatedNum<F>,
|
condition: &AllocatedNum<F>,
|
||||||
) -> Result<AllocatedNum<F>, SynthesisError> {
|
) -> Result<AllocatedNum<F>, SynthesisError> {
|
||||||
let c = AllocatedNum::alloc(cs.namespace(|| "conditional select result"), || {
|
let c = AllocatedNum::alloc(cs.namespace(|| "conditional select result"), || {
|
||||||
if *condition.get_value().get()? == F::one() {
|
if *condition.get_value().get()? == F::ONE {
|
||||||
Ok(*a.get_value().get()?)
|
Ok(*a.get_value().get()?)
|
||||||
} else {
|
} else {
|
||||||
Ok(F::zero())
|
Ok(F::ZERO)
|
||||||
}
|
}
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
@@ -348,14 +348,14 @@ pub fn select_num_or_zero<F: PrimeField, CS: ConstraintSystem<F>>(
|
|||||||
if *condition.get_value().get()? {
|
if *condition.get_value().get()? {
|
||||||
Ok(*a.get_value().get()?)
|
Ok(*a.get_value().get()?)
|
||||||
} else {
|
} else {
|
||||||
Ok(F::zero())
|
Ok(F::ZERO)
|
||||||
}
|
}
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
cs.enforce(
|
cs.enforce(
|
||||||
|| "conditional select constraint",
|
|| "conditional select constraint",
|
||||||
|lc| lc + a.get_variable(),
|
|lc| lc + a.get_variable(),
|
||||||
|_| condition.lc(CS::one(), F::one()),
|
|_| condition.lc(CS::one(), F::ONE),
|
||||||
|lc| lc + c.get_variable(),
|
|lc| lc + c.get_variable(),
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -369,8 +369,8 @@ pub fn select_one_or_num2<F: PrimeField, CS: ConstraintSystem<F>>(
|
|||||||
condition: &AllocatedNum<F>,
|
condition: &AllocatedNum<F>,
|
||||||
) -> Result<AllocatedNum<F>, SynthesisError> {
|
) -> Result<AllocatedNum<F>, SynthesisError> {
|
||||||
let c = AllocatedNum::alloc(cs.namespace(|| "conditional select result"), || {
|
let c = AllocatedNum::alloc(cs.namespace(|| "conditional select result"), || {
|
||||||
if *condition.get_value().get()? == F::one() {
|
if *condition.get_value().get()? == F::ONE {
|
||||||
Ok(F::one())
|
Ok(F::ONE)
|
||||||
} else {
|
} else {
|
||||||
Ok(*a.get_value().get()?)
|
Ok(*a.get_value().get()?)
|
||||||
}
|
}
|
||||||
@@ -393,8 +393,8 @@ pub fn select_one_or_diff2<F: PrimeField, CS: ConstraintSystem<F>>(
|
|||||||
condition: &AllocatedNum<F>,
|
condition: &AllocatedNum<F>,
|
||||||
) -> Result<AllocatedNum<F>, SynthesisError> {
|
) -> Result<AllocatedNum<F>, SynthesisError> {
|
||||||
let c = AllocatedNum::alloc(cs.namespace(|| "conditional select result"), || {
|
let c = AllocatedNum::alloc(cs.namespace(|| "conditional select result"), || {
|
||||||
if *condition.get_value().get()? == F::one() {
|
if *condition.get_value().get()? == F::ONE {
|
||||||
Ok(F::one())
|
Ok(F::ONE)
|
||||||
} else {
|
} else {
|
||||||
Ok(*a.get_value().get()? - *b.get_value().get()?)
|
Ok(*a.get_value().get()? - *b.get_value().get()?)
|
||||||
}
|
}
|
||||||
@@ -419,14 +419,14 @@ pub fn select_num_or_one<F: PrimeField, CS: ConstraintSystem<F>>(
|
|||||||
if *condition.get_value().get()? {
|
if *condition.get_value().get()? {
|
||||||
Ok(*a.get_value().get()?)
|
Ok(*a.get_value().get()?)
|
||||||
} else {
|
} else {
|
||||||
Ok(F::one())
|
Ok(F::ONE)
|
||||||
}
|
}
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
cs.enforce(
|
cs.enforce(
|
||||||
|| "conditional select constraint",
|
|| "conditional select constraint",
|
||||||
|lc| lc + a.get_variable() - CS::one(),
|
|lc| lc + a.get_variable() - CS::one(),
|
||||||
|_| condition.lc(CS::one(), F::one()),
|
|_| condition.lc(CS::one(), F::ONE),
|
||||||
|lc| lc + c.get_variable() - CS::one(),
|
|lc| lc + c.get_variable() - CS::one(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
74
src/lib.rs
74
src/lib.rs
@@ -206,7 +206,7 @@ where
|
|||||||
let mut cs_primary: SatisfyingAssignment<G1> = SatisfyingAssignment::new();
|
let mut cs_primary: SatisfyingAssignment<G1> = SatisfyingAssignment::new();
|
||||||
let inputs_primary: NovaAugmentedCircuitInputs<G2> = NovaAugmentedCircuitInputs::new(
|
let inputs_primary: NovaAugmentedCircuitInputs<G2> = NovaAugmentedCircuitInputs::new(
|
||||||
pp.r1cs_shape_secondary.get_digest(),
|
pp.r1cs_shape_secondary.get_digest(),
|
||||||
G1::Scalar::zero(),
|
G1::Scalar::ZERO,
|
||||||
z0_primary.clone(),
|
z0_primary.clone(),
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
@@ -229,7 +229,7 @@ where
|
|||||||
let mut cs_secondary: SatisfyingAssignment<G2> = SatisfyingAssignment::new();
|
let mut cs_secondary: SatisfyingAssignment<G2> = SatisfyingAssignment::new();
|
||||||
let inputs_secondary: NovaAugmentedCircuitInputs<G1> = NovaAugmentedCircuitInputs::new(
|
let inputs_secondary: NovaAugmentedCircuitInputs<G1> = NovaAugmentedCircuitInputs::new(
|
||||||
pp.r1cs_shape_primary.get_digest(),
|
pp.r1cs_shape_primary.get_digest(),
|
||||||
G2::Scalar::zero(),
|
G2::Scalar::ZERO,
|
||||||
z0_secondary.clone(),
|
z0_secondary.clone(),
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
@@ -862,8 +862,8 @@ mod tests {
|
|||||||
None,
|
None,
|
||||||
TrivialTestCircuit::default(),
|
TrivialTestCircuit::default(),
|
||||||
TrivialTestCircuit::default(),
|
TrivialTestCircuit::default(),
|
||||||
vec![<G1 as Group>::Scalar::zero()],
|
vec![<G1 as Group>::Scalar::ZERO],
|
||||||
vec![<G2 as Group>::Scalar::zero()],
|
vec![<G2 as Group>::Scalar::ZERO],
|
||||||
);
|
);
|
||||||
assert!(res.is_ok());
|
assert!(res.is_ok());
|
||||||
let recursive_snark = res.unwrap();
|
let recursive_snark = res.unwrap();
|
||||||
@@ -872,8 +872,8 @@ mod tests {
|
|||||||
let res = recursive_snark.verify(
|
let res = recursive_snark.verify(
|
||||||
&pp,
|
&pp,
|
||||||
num_steps,
|
num_steps,
|
||||||
vec![<G1 as Group>::Scalar::zero()],
|
vec![<G1 as Group>::Scalar::ZERO],
|
||||||
vec![<G2 as Group>::Scalar::zero()],
|
vec![<G2 as Group>::Scalar::ZERO],
|
||||||
);
|
);
|
||||||
assert!(res.is_ok());
|
assert!(res.is_ok());
|
||||||
}
|
}
|
||||||
@@ -909,8 +909,8 @@ mod tests {
|
|||||||
recursive_snark,
|
recursive_snark,
|
||||||
circuit_primary.clone(),
|
circuit_primary.clone(),
|
||||||
circuit_secondary.clone(),
|
circuit_secondary.clone(),
|
||||||
vec![<G1 as Group>::Scalar::one()],
|
vec![<G1 as Group>::Scalar::ONE],
|
||||||
vec![<G2 as Group>::Scalar::zero()],
|
vec![<G2 as Group>::Scalar::ZERO],
|
||||||
);
|
);
|
||||||
assert!(res.is_ok());
|
assert!(res.is_ok());
|
||||||
let recursive_snark_unwrapped = res.unwrap();
|
let recursive_snark_unwrapped = res.unwrap();
|
||||||
@@ -919,8 +919,8 @@ mod tests {
|
|||||||
let res = recursive_snark_unwrapped.verify(
|
let res = recursive_snark_unwrapped.verify(
|
||||||
&pp,
|
&pp,
|
||||||
i + 1,
|
i + 1,
|
||||||
vec![<G1 as Group>::Scalar::one()],
|
vec![<G1 as Group>::Scalar::ONE],
|
||||||
vec![<G2 as Group>::Scalar::zero()],
|
vec![<G2 as Group>::Scalar::ZERO],
|
||||||
);
|
);
|
||||||
assert!(res.is_ok());
|
assert!(res.is_ok());
|
||||||
|
|
||||||
@@ -935,16 +935,16 @@ mod tests {
|
|||||||
let res = recursive_snark.verify(
|
let res = recursive_snark.verify(
|
||||||
&pp,
|
&pp,
|
||||||
num_steps,
|
num_steps,
|
||||||
vec![<G1 as Group>::Scalar::one()],
|
vec![<G1 as Group>::Scalar::ONE],
|
||||||
vec![<G2 as Group>::Scalar::zero()],
|
vec![<G2 as Group>::Scalar::ZERO],
|
||||||
);
|
);
|
||||||
assert!(res.is_ok());
|
assert!(res.is_ok());
|
||||||
|
|
||||||
let (zn_primary, zn_secondary) = res.unwrap();
|
let (zn_primary, zn_secondary) = res.unwrap();
|
||||||
|
|
||||||
// sanity: check the claimed output with a direct computation of the same
|
// sanity: check the claimed output with a direct computation of the same
|
||||||
assert_eq!(zn_primary, vec![<G1 as Group>::Scalar::one()]);
|
assert_eq!(zn_primary, vec![<G1 as Group>::Scalar::ONE]);
|
||||||
let mut zn_secondary_direct = vec![<G2 as Group>::Scalar::zero()];
|
let mut zn_secondary_direct = vec![<G2 as Group>::Scalar::ZERO];
|
||||||
for _i in 0..num_steps {
|
for _i in 0..num_steps {
|
||||||
zn_secondary_direct = CubicCircuit::default().output(&zn_secondary_direct);
|
zn_secondary_direct = CubicCircuit::default().output(&zn_secondary_direct);
|
||||||
}
|
}
|
||||||
@@ -983,8 +983,8 @@ mod tests {
|
|||||||
recursive_snark,
|
recursive_snark,
|
||||||
circuit_primary.clone(),
|
circuit_primary.clone(),
|
||||||
circuit_secondary.clone(),
|
circuit_secondary.clone(),
|
||||||
vec![<G1 as Group>::Scalar::one()],
|
vec![<G1 as Group>::Scalar::ONE],
|
||||||
vec![<G2 as Group>::Scalar::zero()],
|
vec![<G2 as Group>::Scalar::ZERO],
|
||||||
);
|
);
|
||||||
assert!(res.is_ok());
|
assert!(res.is_ok());
|
||||||
recursive_snark = Some(res.unwrap());
|
recursive_snark = Some(res.unwrap());
|
||||||
@@ -997,16 +997,16 @@ mod tests {
|
|||||||
let res = recursive_snark.verify(
|
let res = recursive_snark.verify(
|
||||||
&pp,
|
&pp,
|
||||||
num_steps,
|
num_steps,
|
||||||
vec![<G1 as Group>::Scalar::one()],
|
vec![<G1 as Group>::Scalar::ONE],
|
||||||
vec![<G2 as Group>::Scalar::zero()],
|
vec![<G2 as Group>::Scalar::ZERO],
|
||||||
);
|
);
|
||||||
assert!(res.is_ok());
|
assert!(res.is_ok());
|
||||||
|
|
||||||
let (zn_primary, zn_secondary) = res.unwrap();
|
let (zn_primary, zn_secondary) = res.unwrap();
|
||||||
|
|
||||||
// sanity: check the claimed output with a direct computation of the same
|
// sanity: check the claimed output with a direct computation of the same
|
||||||
assert_eq!(zn_primary, vec![<G1 as Group>::Scalar::one()]);
|
assert_eq!(zn_primary, vec![<G1 as Group>::Scalar::ONE]);
|
||||||
let mut zn_secondary_direct = vec![<G2 as Group>::Scalar::zero()];
|
let mut zn_secondary_direct = vec![<G2 as Group>::Scalar::ZERO];
|
||||||
for _i in 0..num_steps {
|
for _i in 0..num_steps {
|
||||||
zn_secondary_direct = CubicCircuit::default().output(&zn_secondary_direct);
|
zn_secondary_direct = CubicCircuit::default().output(&zn_secondary_direct);
|
||||||
}
|
}
|
||||||
@@ -1025,8 +1025,8 @@ mod tests {
|
|||||||
let res = compressed_snark.verify(
|
let res = compressed_snark.verify(
|
||||||
&vk,
|
&vk,
|
||||||
num_steps,
|
num_steps,
|
||||||
vec![<G1 as Group>::Scalar::one()],
|
vec![<G1 as Group>::Scalar::ONE],
|
||||||
vec![<G2 as Group>::Scalar::zero()],
|
vec![<G2 as Group>::Scalar::ZERO],
|
||||||
);
|
);
|
||||||
assert!(res.is_ok());
|
assert!(res.is_ok());
|
||||||
}
|
}
|
||||||
@@ -1062,8 +1062,8 @@ mod tests {
|
|||||||
recursive_snark,
|
recursive_snark,
|
||||||
circuit_primary.clone(),
|
circuit_primary.clone(),
|
||||||
circuit_secondary.clone(),
|
circuit_secondary.clone(),
|
||||||
vec![<G1 as Group>::Scalar::one()],
|
vec![<G1 as Group>::Scalar::ONE],
|
||||||
vec![<G2 as Group>::Scalar::zero()],
|
vec![<G2 as Group>::Scalar::ZERO],
|
||||||
);
|
);
|
||||||
assert!(res.is_ok());
|
assert!(res.is_ok());
|
||||||
recursive_snark = Some(res.unwrap());
|
recursive_snark = Some(res.unwrap());
|
||||||
@@ -1076,16 +1076,16 @@ mod tests {
|
|||||||
let res = recursive_snark.verify(
|
let res = recursive_snark.verify(
|
||||||
&pp,
|
&pp,
|
||||||
num_steps,
|
num_steps,
|
||||||
vec![<G1 as Group>::Scalar::one()],
|
vec![<G1 as Group>::Scalar::ONE],
|
||||||
vec![<G2 as Group>::Scalar::zero()],
|
vec![<G2 as Group>::Scalar::ZERO],
|
||||||
);
|
);
|
||||||
assert!(res.is_ok());
|
assert!(res.is_ok());
|
||||||
|
|
||||||
let (zn_primary, zn_secondary) = res.unwrap();
|
let (zn_primary, zn_secondary) = res.unwrap();
|
||||||
|
|
||||||
// sanity: check the claimed output with a direct computation of the same
|
// sanity: check the claimed output with a direct computation of the same
|
||||||
assert_eq!(zn_primary, vec![<G1 as Group>::Scalar::one()]);
|
assert_eq!(zn_primary, vec![<G1 as Group>::Scalar::ONE]);
|
||||||
let mut zn_secondary_direct = vec![<G2 as Group>::Scalar::zero()];
|
let mut zn_secondary_direct = vec![<G2 as Group>::Scalar::ZERO];
|
||||||
for _i in 0..num_steps {
|
for _i in 0..num_steps {
|
||||||
zn_secondary_direct = CubicCircuit::default().output(&zn_secondary_direct);
|
zn_secondary_direct = CubicCircuit::default().output(&zn_secondary_direct);
|
||||||
}
|
}
|
||||||
@@ -1108,8 +1108,8 @@ mod tests {
|
|||||||
let res = compressed_snark.verify(
|
let res = compressed_snark.verify(
|
||||||
&vk,
|
&vk,
|
||||||
num_steps,
|
num_steps,
|
||||||
vec![<G1 as Group>::Scalar::one()],
|
vec![<G1 as Group>::Scalar::ONE],
|
||||||
vec![<G2 as Group>::Scalar::zero()],
|
vec![<G2 as Group>::Scalar::ZERO],
|
||||||
);
|
);
|
||||||
assert!(res.is_ok());
|
assert!(res.is_ok());
|
||||||
}
|
}
|
||||||
@@ -1198,7 +1198,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let circuit_primary = FifthRootCheckingCircuit {
|
let circuit_primary = FifthRootCheckingCircuit {
|
||||||
y: <G1 as Group>::Scalar::zero(),
|
y: <G1 as Group>::Scalar::ZERO,
|
||||||
};
|
};
|
||||||
|
|
||||||
let circuit_secondary = TrivialTestCircuit::default();
|
let circuit_secondary = TrivialTestCircuit::default();
|
||||||
@@ -1215,7 +1215,7 @@ mod tests {
|
|||||||
|
|
||||||
// produce non-deterministic advice
|
// produce non-deterministic advice
|
||||||
let (z0_primary, roots) = FifthRootCheckingCircuit::new(num_steps);
|
let (z0_primary, roots) = FifthRootCheckingCircuit::new(num_steps);
|
||||||
let z0_secondary = vec![<G2 as Group>::Scalar::zero()];
|
let z0_secondary = vec![<G2 as Group>::Scalar::ZERO];
|
||||||
|
|
||||||
// produce a recursive SNARK
|
// produce a recursive SNARK
|
||||||
let mut recursive_snark: Option<
|
let mut recursive_snark: Option<
|
||||||
@@ -1278,8 +1278,8 @@ mod tests {
|
|||||||
None,
|
None,
|
||||||
TrivialTestCircuit::default(),
|
TrivialTestCircuit::default(),
|
||||||
CubicCircuit::default(),
|
CubicCircuit::default(),
|
||||||
vec![<G1 as Group>::Scalar::one()],
|
vec![<G1 as Group>::Scalar::ONE],
|
||||||
vec![<G2 as Group>::Scalar::zero()],
|
vec![<G2 as Group>::Scalar::ZERO],
|
||||||
);
|
);
|
||||||
assert!(res.is_ok());
|
assert!(res.is_ok());
|
||||||
let recursive_snark = res.unwrap();
|
let recursive_snark = res.unwrap();
|
||||||
@@ -1288,14 +1288,14 @@ mod tests {
|
|||||||
let res = recursive_snark.verify(
|
let res = recursive_snark.verify(
|
||||||
&pp,
|
&pp,
|
||||||
num_steps,
|
num_steps,
|
||||||
vec![<G1 as Group>::Scalar::one()],
|
vec![<G1 as Group>::Scalar::ONE],
|
||||||
vec![<G2 as Group>::Scalar::zero()],
|
vec![<G2 as Group>::Scalar::ZERO],
|
||||||
);
|
);
|
||||||
assert!(res.is_ok());
|
assert!(res.is_ok());
|
||||||
|
|
||||||
let (zn_primary, zn_secondary) = res.unwrap();
|
let (zn_primary, zn_secondary) = res.unwrap();
|
||||||
|
|
||||||
assert_eq!(zn_primary, vec![<G1 as Group>::Scalar::one()]);
|
assert_eq!(zn_primary, vec![<G1 as Group>::Scalar::ONE]);
|
||||||
assert_eq!(zn_secondary, vec![<G2 as Group>::Scalar::from(5u64)]);
|
assert_eq!(zn_secondary, vec![<G2 as Group>::Scalar::from(5u64)]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ where
|
|||||||
(0..a.len())
|
(0..a.len())
|
||||||
.into_par_iter()
|
.into_par_iter()
|
||||||
.map(|i| a[i] * b[i])
|
.map(|i| a[i] * b[i])
|
||||||
.reduce(T::zero, |x, y| x + y)
|
.reduce(|| T::ZERO, |x, y| x + y)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An inner product instance consists of a commitment to a vector `a` and another vector `b`
|
/// An inner product instance consists of a commitment to a vector `a` and another vector `b`
|
||||||
@@ -323,8 +323,8 @@ where
|
|||||||
let P = U.comm_a_vec + CE::<G>::commit(&ck_c, &[U.c]);
|
let P = U.comm_a_vec + CE::<G>::commit(&ck_c, &[U.c]);
|
||||||
|
|
||||||
let batch_invert = |v: &[G::Scalar]| -> Result<Vec<G::Scalar>, NovaError> {
|
let batch_invert = |v: &[G::Scalar]| -> Result<Vec<G::Scalar>, NovaError> {
|
||||||
let mut products = vec![G::Scalar::zero(); v.len()];
|
let mut products = vec![G::Scalar::ZERO; v.len()];
|
||||||
let mut acc = G::Scalar::one();
|
let mut acc = G::Scalar::ONE;
|
||||||
|
|
||||||
for i in 0..v.len() {
|
for i in 0..v.len() {
|
||||||
products[i] = acc;
|
products[i] = acc;
|
||||||
@@ -332,14 +332,14 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
// we can compute an inversion only if acc is non-zero
|
// we can compute an inversion only if acc is non-zero
|
||||||
if acc == G::Scalar::zero() {
|
if acc == G::Scalar::ZERO {
|
||||||
return Err(NovaError::InvalidInputLength);
|
return Err(NovaError::InvalidInputLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
// compute the inverse once for all entries
|
// compute the inverse once for all entries
|
||||||
acc = acc.invert().unwrap();
|
acc = acc.invert().unwrap();
|
||||||
|
|
||||||
let mut inv = vec![G::Scalar::zero(); v.len()];
|
let mut inv = vec![G::Scalar::ZERO; v.len()];
|
||||||
for i in 0..v.len() {
|
for i in 0..v.len() {
|
||||||
let tmp = acc * v[v.len() - 1 - i];
|
let tmp = acc * v[v.len() - 1 - i];
|
||||||
inv[v.len() - 1 - i] = products[v.len() - 1 - i] * acc;
|
inv[v.len() - 1 - i] = products[v.len() - 1 - i] * acc;
|
||||||
@@ -371,9 +371,9 @@ where
|
|||||||
|
|
||||||
// compute the vector with the tensor structure
|
// compute the vector with the tensor structure
|
||||||
let s = {
|
let s = {
|
||||||
let mut s = vec![G::Scalar::zero(); n];
|
let mut s = vec![G::Scalar::ZERO; n];
|
||||||
s[0] = {
|
s[0] = {
|
||||||
let mut v = G::Scalar::one();
|
let mut v = G::Scalar::ONE;
|
||||||
for r_inverse_i in &r_inverse {
|
for r_inverse_i in &r_inverse {
|
||||||
v *= r_inverse_i;
|
v *= r_inverse_i;
|
||||||
}
|
}
|
||||||
@@ -406,7 +406,7 @@ where
|
|||||||
&r_square
|
&r_square
|
||||||
.iter()
|
.iter()
|
||||||
.chain(r_inverse_square.iter())
|
.chain(r_inverse_square.iter())
|
||||||
.chain(iter::once(&G::Scalar::one()))
|
.chain(iter::once(&G::Scalar::ONE))
|
||||||
.copied()
|
.copied()
|
||||||
.collect::<Vec<G::Scalar>>(),
|
.collect::<Vec<G::Scalar>>(),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -8,12 +8,12 @@ use crate::{
|
|||||||
traits::{CompressedGroup, Group, PrimeFieldExt, TranscriptReprTrait},
|
traits::{CompressedGroup, Group, PrimeFieldExt, TranscriptReprTrait},
|
||||||
};
|
};
|
||||||
use digest::{ExtendableOutput, Input};
|
use digest::{ExtendableOutput, Input};
|
||||||
use ff::PrimeField;
|
use ff::{FromUniformBytes, PrimeField};
|
||||||
use num_bigint::BigInt;
|
use num_bigint::BigInt;
|
||||||
use num_traits::Num;
|
use num_traits::Num;
|
||||||
use pasta_curves::{
|
use pasta_curves::{
|
||||||
self,
|
self,
|
||||||
arithmetic::{CurveAffine, CurveExt, FieldExt, Group as OtherGroup},
|
arithmetic::{CurveAffine, CurveExt},
|
||||||
group::{cofactor::CofactorCurveAffine, Curve, Group as AnotherGroup, GroupEncoding},
|
group::{cofactor::CofactorCurveAffine, Curve, Group as AnotherGroup, GroupEncoding},
|
||||||
pallas, vesta, Ep, EpAffine, Eq, EqAffine,
|
pallas, vesta, Ep, EpAffine, Eq, EqAffine,
|
||||||
};
|
};
|
||||||
@@ -163,7 +163,7 @@ macro_rules! impl_traits {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn zero() -> Self {
|
fn zero() -> Self {
|
||||||
$name::Point::group_zero()
|
$name::Point::identity()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_generator() -> Self {
|
fn get_generator() -> Self {
|
||||||
@@ -174,7 +174,7 @@ macro_rules! impl_traits {
|
|||||||
impl PrimeFieldExt for $name::Scalar {
|
impl PrimeFieldExt for $name::Scalar {
|
||||||
fn from_uniform(bytes: &[u8]) -> Self {
|
fn from_uniform(bytes: &[u8]) -> Self {
|
||||||
let bytes_arr: [u8; 64] = bytes.try_into().unwrap();
|
let bytes_arr: [u8; 64] = bytes.try_into().unwrap();
|
||||||
$name::Scalar::from_bytes_wide(&bytes_arr)
|
$name::Scalar::from_uniform_bytes(&bytes_arr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -85,9 +85,9 @@ impl<G: Group> AbsorbInROTrait<G> for Commitment<G> {
|
|||||||
ro.absorb(x);
|
ro.absorb(x);
|
||||||
ro.absorb(y);
|
ro.absorb(y);
|
||||||
ro.absorb(if is_infinity {
|
ro.absorb(if is_infinity {
|
||||||
G::Base::one()
|
G::Base::ONE
|
||||||
} else {
|
} else {
|
||||||
G::Base::zero()
|
G::Base::ZERO
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -96,8 +96,8 @@ where
|
|||||||
|
|
||||||
// Only return `num_bits`
|
// Only return `num_bits`
|
||||||
let bits = hash[0].to_le_bits();
|
let bits = hash[0].to_le_bits();
|
||||||
let mut res = Scalar::zero();
|
let mut res = Scalar::ZERO;
|
||||||
let mut coeff = Scalar::one();
|
let mut coeff = Scalar::ONE;
|
||||||
for bit in bits[0..num_bits].into_iter() {
|
for bit in bits[0..num_bits].into_iter() {
|
||||||
if *bit {
|
if *bit {
|
||||||
res += coeff;
|
res += coeff;
|
||||||
|
|||||||
42
src/r1cs.rs
42
src/r1cs.rs
@@ -159,7 +159,7 @@ impl<G: Group> R1CSShape<G> {
|
|||||||
let (row, col, val) = M[i];
|
let (row, col, val) = M[i];
|
||||||
(row, val * z[col])
|
(row, val * z[col])
|
||||||
})
|
})
|
||||||
.fold(vec![G::Scalar::zero(); num_rows], |mut Mz, (r, v)| {
|
.fold(vec![G::Scalar::ZERO; num_rows], |mut Mz, (r, v)| {
|
||||||
Mz[r] += v;
|
Mz[r] += v;
|
||||||
Mz
|
Mz
|
||||||
})
|
})
|
||||||
@@ -230,7 +230,7 @@ impl<G: Group> R1CSShape<G> {
|
|||||||
|
|
||||||
// verify if Az * Bz = u*Cz
|
// verify if Az * Bz = u*Cz
|
||||||
let res_eq: bool = {
|
let res_eq: bool = {
|
||||||
let z = concat(vec![W.W.clone(), vec![G::Scalar::one()], U.X.clone()]);
|
let z = concat(vec![W.W.clone(), vec![G::Scalar::ONE], U.X.clone()]);
|
||||||
let (Az, Bz, Cz) = self.multiply_vec(&z)?;
|
let (Az, Bz, Cz) = self.multiply_vec(&z)?;
|
||||||
assert_eq!(Az.len(), self.num_cons);
|
assert_eq!(Az.len(), self.num_cons);
|
||||||
assert_eq!(Bz.len(), self.num_cons);
|
assert_eq!(Bz.len(), self.num_cons);
|
||||||
@@ -269,7 +269,7 @@ impl<G: Group> R1CSShape<G> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let (AZ_2, BZ_2, CZ_2) = {
|
let (AZ_2, BZ_2, CZ_2) = {
|
||||||
let Z2 = concat(vec![W2.W.clone(), vec![G::Scalar::one()], U2.X.clone()]);
|
let Z2 = concat(vec![W2.W.clone(), vec![G::Scalar::ONE], U2.X.clone()]);
|
||||||
self.multiply_vec(&Z2)?
|
self.multiply_vec(&Z2)?
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -353,8 +353,8 @@ impl<G: Group> R1CSShape<G> {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// turn the bit vector into a scalar
|
// turn the bit vector into a scalar
|
||||||
let mut res = G::Scalar::zero();
|
let mut res = G::Scalar::ZERO;
|
||||||
let mut coeff = G::Scalar::one();
|
let mut coeff = G::Scalar::ONE;
|
||||||
for bit in bv {
|
for bit in bv {
|
||||||
if bit {
|
if bit {
|
||||||
res += coeff;
|
res += coeff;
|
||||||
@@ -397,11 +397,15 @@ impl<G: Group> R1CSShape<G> {
|
|||||||
let apply_pad = |M: &[(usize, usize, G::Scalar)]| -> Vec<(usize, usize, G::Scalar)> {
|
let apply_pad = |M: &[(usize, usize, G::Scalar)]| -> Vec<(usize, usize, G::Scalar)> {
|
||||||
M.par_iter()
|
M.par_iter()
|
||||||
.map(|(r, c, v)| {
|
.map(|(r, c, v)| {
|
||||||
if c >= &self.num_vars {
|
(
|
||||||
(*r, c + num_vars_padded - self.num_vars, *v)
|
*r,
|
||||||
} else {
|
if c >= &self.num_vars {
|
||||||
(*r, *c, *v)
|
c + num_vars_padded - self.num_vars
|
||||||
}
|
} else {
|
||||||
|
*c
|
||||||
|
},
|
||||||
|
*v,
|
||||||
|
)
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
};
|
};
|
||||||
@@ -490,8 +494,8 @@ impl<G: Group> RelaxedR1CSWitness<G> {
|
|||||||
/// Produces a default RelaxedR1CSWitness given an R1CSShape
|
/// Produces a default RelaxedR1CSWitness given an R1CSShape
|
||||||
pub fn default(S: &R1CSShape<G>) -> RelaxedR1CSWitness<G> {
|
pub fn default(S: &R1CSShape<G>) -> RelaxedR1CSWitness<G> {
|
||||||
RelaxedR1CSWitness {
|
RelaxedR1CSWitness {
|
||||||
W: vec![G::Scalar::zero(); S.num_vars],
|
W: vec![G::Scalar::ZERO; S.num_vars],
|
||||||
E: vec![G::Scalar::zero(); S.num_cons],
|
E: vec![G::Scalar::ZERO; S.num_cons],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -499,7 +503,7 @@ impl<G: Group> RelaxedR1CSWitness<G> {
|
|||||||
pub fn from_r1cs_witness(S: &R1CSShape<G>, witness: &R1CSWitness<G>) -> RelaxedR1CSWitness<G> {
|
pub fn from_r1cs_witness(S: &R1CSShape<G>, witness: &R1CSWitness<G>) -> RelaxedR1CSWitness<G> {
|
||||||
RelaxedR1CSWitness {
|
RelaxedR1CSWitness {
|
||||||
W: witness.W.clone(),
|
W: witness.W.clone(),
|
||||||
E: vec![G::Scalar::zero(); S.num_cons],
|
E: vec![G::Scalar::ZERO; S.num_cons],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -539,13 +543,13 @@ impl<G: Group> RelaxedR1CSWitness<G> {
|
|||||||
pub fn pad(&self, S: &R1CSShape<G>) -> RelaxedR1CSWitness<G> {
|
pub fn pad(&self, S: &R1CSShape<G>) -> RelaxedR1CSWitness<G> {
|
||||||
let W = {
|
let W = {
|
||||||
let mut W = self.W.clone();
|
let mut W = self.W.clone();
|
||||||
W.extend(vec![G::Scalar::zero(); S.num_vars - W.len()]);
|
W.extend(vec![G::Scalar::ZERO; S.num_vars - W.len()]);
|
||||||
W
|
W
|
||||||
};
|
};
|
||||||
|
|
||||||
let E = {
|
let E = {
|
||||||
let mut E = self.E.clone();
|
let mut E = self.E.clone();
|
||||||
E.extend(vec![G::Scalar::zero(); S.num_cons - E.len()]);
|
E.extend(vec![G::Scalar::ZERO; S.num_cons - E.len()]);
|
||||||
E
|
E
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -560,8 +564,8 @@ impl<G: Group> RelaxedR1CSInstance<G> {
|
|||||||
RelaxedR1CSInstance {
|
RelaxedR1CSInstance {
|
||||||
comm_W,
|
comm_W,
|
||||||
comm_E,
|
comm_E,
|
||||||
u: G::Scalar::zero(),
|
u: G::Scalar::ZERO,
|
||||||
X: vec![G::Scalar::zero(); S.num_io],
|
X: vec![G::Scalar::ZERO; S.num_io],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -573,7 +577,7 @@ impl<G: Group> RelaxedR1CSInstance<G> {
|
|||||||
) -> RelaxedR1CSInstance<G> {
|
) -> RelaxedR1CSInstance<G> {
|
||||||
let mut r_instance = RelaxedR1CSInstance::default(ck, S);
|
let mut r_instance = RelaxedR1CSInstance::default(ck, S);
|
||||||
r_instance.comm_W = instance.comm_W;
|
r_instance.comm_W = instance.comm_W;
|
||||||
r_instance.u = G::Scalar::one();
|
r_instance.u = G::Scalar::ONE;
|
||||||
r_instance.X = instance.X.clone();
|
r_instance.X = instance.X.clone();
|
||||||
r_instance
|
r_instance
|
||||||
}
|
}
|
||||||
@@ -586,7 +590,7 @@ impl<G: Group> RelaxedR1CSInstance<G> {
|
|||||||
RelaxedR1CSInstance {
|
RelaxedR1CSInstance {
|
||||||
comm_W: *comm_W,
|
comm_W: *comm_W,
|
||||||
comm_E: Commitment::<G>::default(),
|
comm_E: Commitment::<G>::default(),
|
||||||
u: G::Scalar::one(),
|
u: G::Scalar::ONE,
|
||||||
X: X.to_vec(),
|
X: X.to_vec(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ use sumcheck::SumcheckProof;
|
|||||||
fn powers<G: Group>(s: &G::Scalar, n: usize) -> Vec<G::Scalar> {
|
fn powers<G: Group>(s: &G::Scalar, n: usize) -> Vec<G::Scalar> {
|
||||||
assert!(n >= 1);
|
assert!(n >= 1);
|
||||||
let mut powers = Vec::new();
|
let mut powers = Vec::new();
|
||||||
powers.push(G::Scalar::one());
|
powers.push(G::Scalar::ONE);
|
||||||
for i in 1..n {
|
for i in 1..n {
|
||||||
powers.push(powers[i - 1] * s);
|
powers.push(powers[i - 1] * s);
|
||||||
}
|
}
|
||||||
@@ -42,7 +42,7 @@ impl<G: Group> PolyEvalWitness<G> {
|
|||||||
W.iter()
|
W.iter()
|
||||||
.map(|w| {
|
.map(|w| {
|
||||||
let mut p = w.p.clone();
|
let mut p = w.p.clone();
|
||||||
p.resize(n, G::Scalar::zero());
|
p.resize(n, G::Scalar::ZERO);
|
||||||
PolyEvalWitness { p }
|
PolyEvalWitness { p }
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
@@ -53,7 +53,7 @@ impl<G: Group> PolyEvalWitness<G> {
|
|||||||
|
|
||||||
fn weighted_sum(W: &[PolyEvalWitness<G>], s: &[G::Scalar]) -> PolyEvalWitness<G> {
|
fn weighted_sum(W: &[PolyEvalWitness<G>], s: &[G::Scalar]) -> PolyEvalWitness<G> {
|
||||||
assert_eq!(W.len(), s.len());
|
assert_eq!(W.len(), s.len());
|
||||||
let mut p = vec![G::Scalar::zero(); W[0].p.len()];
|
let mut p = vec![G::Scalar::ZERO; W[0].p.len()];
|
||||||
for i in 0..W.len() {
|
for i in 0..W.len() {
|
||||||
for j in 0..W[i].p.len() {
|
for j in 0..W[i].p.len() {
|
||||||
p[j] += W[i].p[j] * s[i]
|
p[j] += W[i].p[j] * s[i]
|
||||||
@@ -64,7 +64,7 @@ impl<G: Group> PolyEvalWitness<G> {
|
|||||||
|
|
||||||
fn batch(p_vec: &[&Vec<G::Scalar>], s: &G::Scalar) -> PolyEvalWitness<G> {
|
fn batch(p_vec: &[&Vec<G::Scalar>], s: &G::Scalar) -> PolyEvalWitness<G> {
|
||||||
let powers_of_s = powers::<G>(s, p_vec.len());
|
let powers_of_s = powers::<G>(s, p_vec.len());
|
||||||
let mut p = vec![G::Scalar::zero(); p_vec[0].len()];
|
let mut p = vec![G::Scalar::ZERO; p_vec[0].len()];
|
||||||
for i in 0..p_vec.len() {
|
for i in 0..p_vec.len() {
|
||||||
for (j, item) in p.iter_mut().enumerate().take(p_vec[i].len()) {
|
for (j, item) in p.iter_mut().enumerate().take(p_vec[i].len()) {
|
||||||
*item += p_vec[i][j] * powers_of_s[i]
|
*item += p_vec[i][j] * powers_of_s[i]
|
||||||
@@ -87,7 +87,7 @@ impl<G: Group> PolyEvalInstance<G> {
|
|||||||
if let Some(ell) = U.iter().map(|u| u.x.len()).max() {
|
if let Some(ell) = U.iter().map(|u| u.x.len()).max() {
|
||||||
U.iter()
|
U.iter()
|
||||||
.map(|u| {
|
.map(|u| {
|
||||||
let mut x = vec![G::Scalar::zero(); ell - u.x.len()];
|
let mut x = vec![G::Scalar::ZERO; ell - u.x.len()];
|
||||||
x.extend(u.x.clone());
|
x.extend(u.x.clone());
|
||||||
PolyEvalInstance { c: u.c, x, e: u.e }
|
PolyEvalInstance { c: u.c, x, e: u.e }
|
||||||
})
|
})
|
||||||
@@ -108,7 +108,7 @@ impl<G: Group> PolyEvalInstance<G> {
|
|||||||
.iter()
|
.iter()
|
||||||
.zip(powers_of_s.iter())
|
.zip(powers_of_s.iter())
|
||||||
.map(|(e, p)| *e * p)
|
.map(|(e, p)| *e * p)
|
||||||
.fold(G::Scalar::zero(), |acc, item| acc + item);
|
.fold(G::Scalar::ZERO, |acc, item| acc + item);
|
||||||
let c = c_vec
|
let c = c_vec
|
||||||
.iter()
|
.iter()
|
||||||
.zip(powers_of_s.iter())
|
.zip(powers_of_s.iter())
|
||||||
@@ -233,7 +233,7 @@ impl<G: Group, EE: EvaluationEngineTrait<G, CE = G::CE>> RelaxedR1CSSNARKTrait<G
|
|||||||
poly_D_comp: &G::Scalar|
|
poly_D_comp: &G::Scalar|
|
||||||
-> G::Scalar { *poly_A_comp * (*poly_B_comp * *poly_C_comp - *poly_D_comp) };
|
-> G::Scalar { *poly_A_comp * (*poly_B_comp * *poly_C_comp - *poly_D_comp) };
|
||||||
let (sc_proof_outer, r_x, claims_outer) = SumcheckProof::prove_cubic_with_additive_term(
|
let (sc_proof_outer, r_x, claims_outer) = SumcheckProof::prove_cubic_with_additive_term(
|
||||||
&G::Scalar::zero(), // claim is zero
|
&G::Scalar::ZERO, // claim is zero
|
||||||
num_rounds_x,
|
num_rounds_x,
|
||||||
&mut poly_tau,
|
&mut poly_tau,
|
||||||
&mut poly_Az,
|
&mut poly_Az,
|
||||||
@@ -273,19 +273,19 @@ impl<G: Group, EE: EvaluationEngineTrait<G, CE = G::CE>> RelaxedR1CSSNARKTrait<G
|
|||||||
|
|
||||||
let (A_evals, (B_evals, C_evals)) = rayon::join(
|
let (A_evals, (B_evals, C_evals)) = rayon::join(
|
||||||
|| {
|
|| {
|
||||||
let mut A_evals: Vec<G::Scalar> = vec![G::Scalar::zero(); 2 * S.num_vars];
|
let mut A_evals: Vec<G::Scalar> = vec![G::Scalar::ZERO; 2 * S.num_vars];
|
||||||
inner(&S.A, &mut A_evals);
|
inner(&S.A, &mut A_evals);
|
||||||
A_evals
|
A_evals
|
||||||
},
|
},
|
||||||
|| {
|
|| {
|
||||||
rayon::join(
|
rayon::join(
|
||||||
|| {
|
|| {
|
||||||
let mut B_evals: Vec<G::Scalar> = vec![G::Scalar::zero(); 2 * S.num_vars];
|
let mut B_evals: Vec<G::Scalar> = vec![G::Scalar::ZERO; 2 * S.num_vars];
|
||||||
inner(&S.B, &mut B_evals);
|
inner(&S.B, &mut B_evals);
|
||||||
B_evals
|
B_evals
|
||||||
},
|
},
|
||||||
|| {
|
|| {
|
||||||
let mut C_evals: Vec<G::Scalar> = vec![G::Scalar::zero(); 2 * S.num_vars];
|
let mut C_evals: Vec<G::Scalar> = vec![G::Scalar::ZERO; 2 * S.num_vars];
|
||||||
inner(&S.C, &mut C_evals);
|
inner(&S.C, &mut C_evals);
|
||||||
C_evals
|
C_evals
|
||||||
},
|
},
|
||||||
@@ -307,7 +307,7 @@ impl<G: Group, EE: EvaluationEngineTrait<G, CE = G::CE>> RelaxedR1CSSNARKTrait<G
|
|||||||
};
|
};
|
||||||
|
|
||||||
let poly_z = {
|
let poly_z = {
|
||||||
z.resize(pk.S.num_vars * 2, G::Scalar::zero());
|
z.resize(pk.S.num_vars * 2, G::Scalar::ZERO);
|
||||||
z
|
z
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -366,7 +366,7 @@ impl<G: Group, EE: EvaluationEngineTrait<G, CE = G::CE>> RelaxedR1CSSNARKTrait<G
|
|||||||
.iter()
|
.iter()
|
||||||
.zip(powers_of_rho.iter())
|
.zip(powers_of_rho.iter())
|
||||||
.map(|(u, p)| u.e * p)
|
.map(|(u, p)| u.e * p)
|
||||||
.fold(G::Scalar::zero(), |acc, item| acc + item);
|
.fold(G::Scalar::ZERO, |acc, item| acc + item);
|
||||||
|
|
||||||
let mut polys_left: Vec<MultilinearPolynomial<G::Scalar>> = w_vec_padded
|
let mut polys_left: Vec<MultilinearPolynomial<G::Scalar>> = w_vec_padded
|
||||||
.iter()
|
.iter()
|
||||||
@@ -408,7 +408,7 @@ impl<G: Group, EE: EvaluationEngineTrait<G, CE = G::CE>> RelaxedR1CSSNARKTrait<G
|
|||||||
.iter()
|
.iter()
|
||||||
.zip(powers_of_gamma.iter())
|
.zip(powers_of_gamma.iter())
|
||||||
.map(|(e, g_i)| *e * *g_i)
|
.map(|(e, g_i)| *e * *g_i)
|
||||||
.fold(G::Scalar::zero(), |acc, item| acc + item);
|
.fold(G::Scalar::ZERO, |acc, item| acc + item);
|
||||||
|
|
||||||
let eval_arg = EE::prove(
|
let eval_arg = EE::prove(
|
||||||
ck,
|
ck,
|
||||||
@@ -453,7 +453,7 @@ impl<G: Group, EE: EvaluationEngineTrait<G, CE = G::CE>> RelaxedR1CSSNARKTrait<G
|
|||||||
let (claim_outer_final, r_x) =
|
let (claim_outer_final, r_x) =
|
||||||
self
|
self
|
||||||
.sc_proof_outer
|
.sc_proof_outer
|
||||||
.verify(G::Scalar::zero(), num_rounds_x, 3, &mut transcript)?;
|
.verify(G::Scalar::ZERO, num_rounds_x, 3, &mut transcript)?;
|
||||||
|
|
||||||
// verify claim_outer_final
|
// verify claim_outer_final
|
||||||
let (claim_Az, claim_Bz, claim_Cz) = self.claims_outer;
|
let (claim_Az, claim_Bz, claim_Cz) = self.claims_outer;
|
||||||
@@ -498,7 +498,7 @@ impl<G: Group, EE: EvaluationEngineTrait<G, CE = G::CE>> RelaxedR1CSSNARKTrait<G
|
|||||||
);
|
);
|
||||||
SparsePolynomial::new((vk.S.num_vars as f64).log2() as usize, poly_X).evaluate(&r_y[1..])
|
SparsePolynomial::new((vk.S.num_vars as f64).log2() as usize, poly_X).evaluate(&r_y[1..])
|
||||||
};
|
};
|
||||||
(G::Scalar::one() - r_y[0]) * self.eval_W + r_y[0] * eval_X
|
(G::Scalar::ONE - r_y[0]) * self.eval_W + r_y[0] * eval_X
|
||||||
};
|
};
|
||||||
|
|
||||||
// compute evaluations of R1CS matrices
|
// compute evaluations of R1CS matrices
|
||||||
@@ -515,7 +515,7 @@ impl<G: Group, EE: EvaluationEngineTrait<G, CE = G::CE>> RelaxedR1CSSNARKTrait<G
|
|||||||
let (row, col, val) = M[i];
|
let (row, col, val) = M[i];
|
||||||
T_x[row] * T_y[col] * val
|
T_x[row] * T_y[col] * val
|
||||||
})
|
})
|
||||||
.reduce(G::Scalar::zero, |acc, x| acc + x)
|
.reduce(|| G::Scalar::ZERO, |acc, x| acc + x)
|
||||||
};
|
};
|
||||||
|
|
||||||
let (T_x, T_y) = rayon::join(
|
let (T_x, T_y) = rayon::join(
|
||||||
@@ -561,7 +561,7 @@ impl<G: Group, EE: EvaluationEngineTrait<G, CE = G::CE>> RelaxedR1CSSNARKTrait<G
|
|||||||
.iter()
|
.iter()
|
||||||
.zip(powers_of_rho.iter())
|
.zip(powers_of_rho.iter())
|
||||||
.map(|(u, p)| u.e * p)
|
.map(|(u, p)| u.e * p)
|
||||||
.fold(G::Scalar::zero(), |acc, item| acc + item);
|
.fold(G::Scalar::ZERO, |acc, item| acc + item);
|
||||||
|
|
||||||
let num_rounds_z = u_vec_padded[0].x.len();
|
let num_rounds_z = u_vec_padded[0].x.len();
|
||||||
let (claim_batch_final, r_z) =
|
let (claim_batch_final, r_z) =
|
||||||
@@ -581,7 +581,7 @@ impl<G: Group, EE: EvaluationEngineTrait<G, CE = G::CE>> RelaxedR1CSSNARKTrait<G
|
|||||||
.zip(self.evals_batch.iter())
|
.zip(self.evals_batch.iter())
|
||||||
.zip(powers_of_rho.iter())
|
.zip(powers_of_rho.iter())
|
||||||
.map(|((e_i, p_i), rho_i)| *e_i * *p_i * rho_i)
|
.map(|((e_i, p_i), rho_i)| *e_i * *p_i * rho_i)
|
||||||
.fold(G::Scalar::zero(), |acc, item| acc + item)
|
.fold(G::Scalar::ZERO, |acc, item| acc + item)
|
||||||
};
|
};
|
||||||
|
|
||||||
if claim_batch_final != claim_batch_final_expected {
|
if claim_batch_final != claim_batch_final_expected {
|
||||||
@@ -603,7 +603,7 @@ impl<G: Group, EE: EvaluationEngineTrait<G, CE = G::CE>> RelaxedR1CSSNARKTrait<G
|
|||||||
.iter()
|
.iter()
|
||||||
.zip(powers_of_gamma.iter())
|
.zip(powers_of_gamma.iter())
|
||||||
.map(|(e, g_i)| *e * *g_i)
|
.map(|(e, g_i)| *e * *g_i)
|
||||||
.fold(G::Scalar::zero(), |acc, item| acc + item);
|
.fold(G::Scalar::ZERO, |acc, item| acc + item);
|
||||||
|
|
||||||
// verify
|
// verify
|
||||||
EE::verify(
|
EE::verify(
|
||||||
|
|||||||
@@ -18,15 +18,15 @@ impl<Scalar: PrimeField> EqPolynomial<Scalar> {
|
|||||||
pub fn evaluate(&self, rx: &[Scalar]) -> Scalar {
|
pub fn evaluate(&self, rx: &[Scalar]) -> Scalar {
|
||||||
assert_eq!(self.r.len(), rx.len());
|
assert_eq!(self.r.len(), rx.len());
|
||||||
(0..rx.len())
|
(0..rx.len())
|
||||||
.map(|i| rx[i] * self.r[i] + (Scalar::one() - rx[i]) * (Scalar::one() - self.r[i]))
|
.map(|i| rx[i] * self.r[i] + (Scalar::ONE - rx[i]) * (Scalar::ONE - self.r[i]))
|
||||||
.fold(Scalar::one(), |acc, item| acc * item)
|
.fold(Scalar::ONE, |acc, item| acc * item)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn evals(&self) -> Vec<Scalar> {
|
pub fn evals(&self) -> Vec<Scalar> {
|
||||||
let ell = self.r.len();
|
let ell = self.r.len();
|
||||||
let mut evals: Vec<Scalar> = vec![Scalar::zero(); (2_usize).pow(ell as u32)];
|
let mut evals: Vec<Scalar> = vec![Scalar::ZERO; (2_usize).pow(ell as u32)];
|
||||||
let mut size = 1;
|
let mut size = 1;
|
||||||
evals[0] = Scalar::one();
|
evals[0] = Scalar::ONE;
|
||||||
|
|
||||||
for r in self.r.iter().rev() {
|
for r in self.r.iter().rev() {
|
||||||
let (evals_left, evals_right) = evals.split_at_mut(size);
|
let (evals_left, evals_right) = evals.split_at_mut(size);
|
||||||
@@ -82,7 +82,7 @@ impl<Scalar: PrimeField> MultilinearPolynomial<Scalar> {
|
|||||||
*a += *r * (*b - *a);
|
*a += *r * (*b - *a);
|
||||||
});
|
});
|
||||||
|
|
||||||
self.Z.resize(n, Scalar::zero());
|
self.Z.resize(n, Scalar::ZERO);
|
||||||
self.num_vars -= 1;
|
self.num_vars -= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,7 +96,7 @@ impl<Scalar: PrimeField> MultilinearPolynomial<Scalar> {
|
|||||||
(0..chis.len())
|
(0..chis.len())
|
||||||
.into_par_iter()
|
.into_par_iter()
|
||||||
.map(|i| chis[i] * self.Z[i])
|
.map(|i| chis[i] * self.Z[i])
|
||||||
.reduce(Scalar::zero, |x, y| x + y)
|
.reduce(|| Scalar::ZERO, |x, y| x + y)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn evaluate_with(Z: &[Scalar], r: &[Scalar]) -> Scalar {
|
pub fn evaluate_with(Z: &[Scalar], r: &[Scalar]) -> Scalar {
|
||||||
@@ -105,7 +105,7 @@ impl<Scalar: PrimeField> MultilinearPolynomial<Scalar> {
|
|||||||
.into_par_iter()
|
.into_par_iter()
|
||||||
.zip(Z.into_par_iter())
|
.zip(Z.into_par_iter())
|
||||||
.map(|(a, b)| a * b)
|
.map(|(a, b)| a * b)
|
||||||
.reduce(Scalar::zero, |x, y| x + y)
|
.reduce(|| Scalar::ZERO, |x, y| x + y)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,12 +130,12 @@ impl<Scalar: PrimeField> SparsePolynomial<Scalar> {
|
|||||||
|
|
||||||
fn compute_chi(a: &[bool], r: &[Scalar]) -> Scalar {
|
fn compute_chi(a: &[bool], r: &[Scalar]) -> Scalar {
|
||||||
assert_eq!(a.len(), r.len());
|
assert_eq!(a.len(), r.len());
|
||||||
let mut chi_i = Scalar::one();
|
let mut chi_i = Scalar::ONE;
|
||||||
for j in 0..r.len() {
|
for j in 0..r.len() {
|
||||||
if a[j] {
|
if a[j] {
|
||||||
chi_i *= r[j];
|
chi_i *= r[j];
|
||||||
} else {
|
} else {
|
||||||
chi_i *= Scalar::one() - r[j];
|
chi_i *= Scalar::ONE - r[j];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
chi_i
|
chi_i
|
||||||
@@ -158,6 +158,6 @@ impl<Scalar: PrimeField> SparsePolynomial<Scalar> {
|
|||||||
let bits = get_bits(self.Z[i].0, r.len());
|
let bits = get_bits(self.Z[i].0, r.len());
|
||||||
SparsePolynomial::compute_chi(&bits, r) * self.Z[i].1
|
SparsePolynomial::compute_chi(&bits, r) * self.Z[i].1
|
||||||
})
|
})
|
||||||
.reduce(Scalar::zero, |x, y| x + y)
|
.reduce(|| Scalar::ZERO, |x, y| x + y)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ impl<Scalar: PrimeField> IdentityPolynomial<Scalar> {
|
|||||||
assert_eq!(self.ell, r.len());
|
assert_eq!(self.ell, r.len());
|
||||||
(0..self.ell)
|
(0..self.ell)
|
||||||
.map(|i| Scalar::from(2_usize.pow((self.ell - i - 1) as u32) as u64) * r[i])
|
.map(|i| Scalar::from(2_usize.pow((self.ell - i - 1) as u32) as u64) * r[i])
|
||||||
.fold(Scalar::zero(), |acc, item| acc + item)
|
.fold(Scalar::ZERO, |acc, item| acc + item)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -149,25 +149,25 @@ impl<G: Group> R1CSShapeSparkRepr<G> {
|
|||||||
|
|
||||||
let val_A = {
|
let val_A = {
|
||||||
let mut val = S.A.iter().map(|(_, _, v)| *v).collect::<Vec<G::Scalar>>();
|
let mut val = S.A.iter().map(|(_, _, v)| *v).collect::<Vec<G::Scalar>>();
|
||||||
val.resize(N, G::Scalar::zero());
|
val.resize(N, G::Scalar::ZERO);
|
||||||
val
|
val
|
||||||
};
|
};
|
||||||
|
|
||||||
let val_B = {
|
let val_B = {
|
||||||
// prepend zeros
|
// prepend zeros
|
||||||
let mut val = vec![G::Scalar::zero(); S.A.len()];
|
let mut val = vec![G::Scalar::ZERO; S.A.len()];
|
||||||
val.extend(S.B.iter().map(|(_, _, v)| *v).collect::<Vec<G::Scalar>>());
|
val.extend(S.B.iter().map(|(_, _, v)| *v).collect::<Vec<G::Scalar>>());
|
||||||
// append zeros
|
// append zeros
|
||||||
val.resize(N, G::Scalar::zero());
|
val.resize(N, G::Scalar::ZERO);
|
||||||
val
|
val
|
||||||
};
|
};
|
||||||
|
|
||||||
let val_C = {
|
let val_C = {
|
||||||
// prepend zeros
|
// prepend zeros
|
||||||
let mut val = vec![G::Scalar::zero(); S.A.len() + S.B.len()];
|
let mut val = vec![G::Scalar::ZERO; S.A.len() + S.B.len()];
|
||||||
val.extend(S.C.iter().map(|(_, _, v)| *v).collect::<Vec<G::Scalar>>());
|
val.extend(S.C.iter().map(|(_, _, v)| *v).collect::<Vec<G::Scalar>>());
|
||||||
// append zeros
|
// append zeros
|
||||||
val.resize(N, G::Scalar::zero());
|
val.resize(N, G::Scalar::ZERO);
|
||||||
val
|
val
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -262,7 +262,7 @@ impl<G: Group> R1CSShapeSparkRepr<G> {
|
|||||||
Vec<G::Scalar>,
|
Vec<G::Scalar>,
|
||||||
) {
|
) {
|
||||||
let r_x_padded = {
|
let r_x_padded = {
|
||||||
let mut x = vec![G::Scalar::zero(); self.N.log_2() - r_x.len()];
|
let mut x = vec![G::Scalar::ZERO; self.N.log_2() - r_x.len()];
|
||||||
x.extend(r_x);
|
x.extend(r_x);
|
||||||
x
|
x
|
||||||
};
|
};
|
||||||
@@ -270,7 +270,7 @@ impl<G: Group> R1CSShapeSparkRepr<G> {
|
|||||||
let mem_row = EqPolynomial::new(r_x_padded).evals();
|
let mem_row = EqPolynomial::new(r_x_padded).evals();
|
||||||
let mem_col = {
|
let mem_col = {
|
||||||
let mut z = z.to_vec();
|
let mut z = z.to_vec();
|
||||||
z.resize(self.N, G::Scalar::zero());
|
z.resize(self.N, G::Scalar::ZERO);
|
||||||
z
|
z
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -374,8 +374,8 @@ impl<G: Group> ProductSumcheckInstance<G> {
|
|||||||
|
|
||||||
// add a dummy product operation to make the left.len() == right.len() == output.len() == input.len()
|
// add a dummy product operation to make the left.len() == right.len() == output.len() == input.len()
|
||||||
left.push(output[output.len() - 1]);
|
left.push(output[output.len() - 1]);
|
||||||
right.push(G::Scalar::zero());
|
right.push(G::Scalar::ZERO);
|
||||||
output.push(G::Scalar::zero());
|
output.push(G::Scalar::ZERO);
|
||||||
|
|
||||||
// output is stored at the last but one position
|
// output is stored at the last but one position
|
||||||
let product = output[output.len() - 2];
|
let product = output[output.len() - 2];
|
||||||
@@ -445,7 +445,7 @@ impl<G: Group> ProductSumcheckInstance<G> {
|
|||||||
|
|
||||||
impl<G: Group> SumcheckEngine<G> for ProductSumcheckInstance<G> {
|
impl<G: Group> SumcheckEngine<G> for ProductSumcheckInstance<G> {
|
||||||
fn initial_claims(&self) -> Vec<G::Scalar> {
|
fn initial_claims(&self) -> Vec<G::Scalar> {
|
||||||
vec![G::Scalar::zero(); 8]
|
vec![G::Scalar::ZERO; 8]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn degree(&self) -> usize {
|
fn degree(&self) -> usize {
|
||||||
@@ -515,7 +515,7 @@ impl<G: Group> SumcheckEngine<G> for ProductSumcheckInstance<G> {
|
|||||||
(eval_point_0, eval_point_2, eval_point_3)
|
(eval_point_0, eval_point_2, eval_point_3)
|
||||||
})
|
})
|
||||||
.reduce(
|
.reduce(
|
||||||
|| (G::Scalar::zero(), G::Scalar::zero(), G::Scalar::zero()),
|
|| (G::Scalar::ZERO, G::Scalar::ZERO, G::Scalar::ZERO),
|
||||||
|a, b| (a.0 + b.0, a.1 + b.1, a.2 + b.2),
|
|a, b| (a.0 + b.0, a.1 + b.1, a.2 + b.2),
|
||||||
);
|
);
|
||||||
vec![eval_point_0, eval_point_2, eval_point_3]
|
vec![eval_point_0, eval_point_2, eval_point_3]
|
||||||
@@ -561,7 +561,7 @@ struct OuterSumcheckInstance<G: Group> {
|
|||||||
|
|
||||||
impl<G: Group> SumcheckEngine<G> for OuterSumcheckInstance<G> {
|
impl<G: Group> SumcheckEngine<G> for OuterSumcheckInstance<G> {
|
||||||
fn initial_claims(&self) -> Vec<G::Scalar> {
|
fn initial_claims(&self) -> Vec<G::Scalar> {
|
||||||
vec![G::Scalar::zero()]
|
vec![G::Scalar::ZERO]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn degree(&self) -> usize {
|
fn degree(&self) -> usize {
|
||||||
@@ -623,7 +623,7 @@ impl<G: Group> SumcheckEngine<G> for OuterSumcheckInstance<G> {
|
|||||||
(eval_point_0, eval_point_2, eval_point_3)
|
(eval_point_0, eval_point_2, eval_point_3)
|
||||||
})
|
})
|
||||||
.reduce(
|
.reduce(
|
||||||
|| (G::Scalar::zero(), G::Scalar::zero(), G::Scalar::zero()),
|
|| (G::Scalar::ZERO, G::Scalar::ZERO, G::Scalar::ZERO),
|
||||||
|a, b| (a.0 + b.0, a.1 + b.1, a.2 + b.2),
|
|a, b| (a.0 + b.0, a.1 + b.1, a.2 + b.2),
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -706,7 +706,7 @@ impl<G: Group> SumcheckEngine<G> for InnerSumcheckInstance<G> {
|
|||||||
(eval_point_0, eval_point_2, eval_point_3)
|
(eval_point_0, eval_point_2, eval_point_3)
|
||||||
})
|
})
|
||||||
.reduce(
|
.reduce(
|
||||||
|| (G::Scalar::zero(), G::Scalar::zero(), G::Scalar::zero()),
|
|| (G::Scalar::ZERO, G::Scalar::ZERO, G::Scalar::ZERO),
|
||||||
|a, b| (a.0 + b.0, a.1 + b.1, a.2 + b.2),
|
|a, b| (a.0 + b.0, a.1 + b.1, a.2 + b.2),
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -860,7 +860,7 @@ impl<G: Group, EE: EvaluationEngineTrait<G, CE = G::CE>> RelaxedR1CSSNARK<G, EE>
|
|||||||
.iter()
|
.iter()
|
||||||
.zip(coeffs.iter())
|
.zip(coeffs.iter())
|
||||||
.map(|(c_1, c_2)| *c_1 * c_2)
|
.map(|(c_1, c_2)| *c_1 * c_2)
|
||||||
.fold(G::Scalar::zero(), |acc, item| acc + item);
|
.fold(G::Scalar::ZERO, |acc, item| acc + item);
|
||||||
|
|
||||||
let mut e = claim;
|
let mut e = claim;
|
||||||
let mut r: Vec<G::Scalar> = Vec::new();
|
let mut r: Vec<G::Scalar> = Vec::new();
|
||||||
@@ -875,13 +875,13 @@ impl<G: Group, EE: EvaluationEngineTrait<G, CE = G::CE>> RelaxedR1CSSNARK<G, EE>
|
|||||||
|
|
||||||
let evals_combined_0 = (0..evals.len())
|
let evals_combined_0 = (0..evals.len())
|
||||||
.map(|i| evals[i][0] * coeffs[i])
|
.map(|i| evals[i][0] * coeffs[i])
|
||||||
.fold(G::Scalar::zero(), |acc, item| acc + item);
|
.fold(G::Scalar::ZERO, |acc, item| acc + item);
|
||||||
let evals_combined_2 = (0..evals.len())
|
let evals_combined_2 = (0..evals.len())
|
||||||
.map(|i| evals[i][1] * coeffs[i])
|
.map(|i| evals[i][1] * coeffs[i])
|
||||||
.fold(G::Scalar::zero(), |acc, item| acc + item);
|
.fold(G::Scalar::ZERO, |acc, item| acc + item);
|
||||||
let evals_combined_3 = (0..evals.len())
|
let evals_combined_3 = (0..evals.len())
|
||||||
.map(|i| evals[i][2] * coeffs[i])
|
.map(|i| evals[i][2] * coeffs[i])
|
||||||
.fold(G::Scalar::zero(), |acc, item| acc + item);
|
.fold(G::Scalar::ZERO, |acc, item| acc + item);
|
||||||
|
|
||||||
let evals = vec![
|
let evals = vec![
|
||||||
evals_combined_0,
|
evals_combined_0,
|
||||||
@@ -1000,12 +1000,12 @@ impl<G: Group, EE: EvaluationEngineTrait<G, CE = G::CE>> RelaxedR1CSSNARKTrait<G
|
|||||||
|
|
||||||
// (1) send commitments to Az, Bz, and Cz along with their evaluations at tau
|
// (1) send commitments to Az, Bz, and Cz along with their evaluations at tau
|
||||||
let (Az, Bz, Cz, E) = {
|
let (Az, Bz, Cz, E) = {
|
||||||
Az.resize(pk.S_repr.N, G::Scalar::zero());
|
Az.resize(pk.S_repr.N, G::Scalar::ZERO);
|
||||||
Bz.resize(pk.S_repr.N, G::Scalar::zero());
|
Bz.resize(pk.S_repr.N, G::Scalar::ZERO);
|
||||||
Cz.resize(pk.S_repr.N, G::Scalar::zero());
|
Cz.resize(pk.S_repr.N, G::Scalar::ZERO);
|
||||||
|
|
||||||
let mut E = W.E.clone();
|
let mut E = W.E.clone();
|
||||||
E.resize(pk.S_repr.N, G::Scalar::zero());
|
E.resize(pk.S_repr.N, G::Scalar::ZERO);
|
||||||
|
|
||||||
(Az, Bz, Cz, E)
|
(Az, Bz, Cz, E)
|
||||||
};
|
};
|
||||||
@@ -1092,7 +1092,7 @@ impl<G: Group, EE: EvaluationEngineTrait<G, CE = G::CE>> RelaxedR1CSSNARKTrait<G
|
|||||||
};
|
};
|
||||||
|
|
||||||
let init_row = (0..mem_row.len())
|
let init_row = (0..mem_row.len())
|
||||||
.map(|i| hash_func(&G::Scalar::from(i as u64), &mem_row[i], &G::Scalar::zero()))
|
.map(|i| hash_func(&G::Scalar::from(i as u64), &mem_row[i], &G::Scalar::ZERO))
|
||||||
.collect::<Vec<G::Scalar>>();
|
.collect::<Vec<G::Scalar>>();
|
||||||
let read_row = (0..E_row.len())
|
let read_row = (0..E_row.len())
|
||||||
.map(|i| hash_func(&pk.S_repr.row[i], &E_row[i], &pk.S_repr.row_read_ts[i]))
|
.map(|i| hash_func(&pk.S_repr.row[i], &E_row[i], &pk.S_repr.row_read_ts[i]))
|
||||||
@@ -1102,7 +1102,7 @@ impl<G: Group, EE: EvaluationEngineTrait<G, CE = G::CE>> RelaxedR1CSSNARKTrait<G
|
|||||||
hash_func(
|
hash_func(
|
||||||
&pk.S_repr.row[i],
|
&pk.S_repr.row[i],
|
||||||
&E_row[i],
|
&E_row[i],
|
||||||
&(pk.S_repr.row_read_ts[i] + G::Scalar::one()),
|
&(pk.S_repr.row_read_ts[i] + G::Scalar::ONE),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.collect::<Vec<G::Scalar>>();
|
.collect::<Vec<G::Scalar>>();
|
||||||
@@ -1117,7 +1117,7 @@ impl<G: Group, EE: EvaluationEngineTrait<G, CE = G::CE>> RelaxedR1CSSNARKTrait<G
|
|||||||
.collect::<Vec<G::Scalar>>();
|
.collect::<Vec<G::Scalar>>();
|
||||||
|
|
||||||
let init_col = (0..mem_col.len())
|
let init_col = (0..mem_col.len())
|
||||||
.map(|i| hash_func(&G::Scalar::from(i as u64), &mem_col[i], &G::Scalar::zero()))
|
.map(|i| hash_func(&G::Scalar::from(i as u64), &mem_col[i], &G::Scalar::ZERO))
|
||||||
.collect::<Vec<G::Scalar>>();
|
.collect::<Vec<G::Scalar>>();
|
||||||
let read_col = (0..E_col.len())
|
let read_col = (0..E_col.len())
|
||||||
.map(|i| hash_func(&pk.S_repr.col[i], &E_col[i], &pk.S_repr.col_read_ts[i]))
|
.map(|i| hash_func(&pk.S_repr.col[i], &E_col[i], &pk.S_repr.col_read_ts[i]))
|
||||||
@@ -1127,7 +1127,7 @@ impl<G: Group, EE: EvaluationEngineTrait<G, CE = G::CE>> RelaxedR1CSSNARKTrait<G
|
|||||||
hash_func(
|
hash_func(
|
||||||
&pk.S_repr.col[i],
|
&pk.S_repr.col[i],
|
||||||
&E_col[i],
|
&E_col[i],
|
||||||
&(pk.S_repr.col_read_ts[i] + G::Scalar::one()),
|
&(pk.S_repr.col_read_ts[i] + G::Scalar::ONE),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.collect::<Vec<G::Scalar>>();
|
.collect::<Vec<G::Scalar>>();
|
||||||
@@ -1190,7 +1190,7 @@ impl<G: Group, EE: EvaluationEngineTrait<G, CE = G::CE>> RelaxedR1CSSNARKTrait<G
|
|||||||
// into claims about input and output
|
// into claims about input and output
|
||||||
let c = transcript.squeeze(b"c")?;
|
let c = transcript.squeeze(b"c")?;
|
||||||
|
|
||||||
// eval = (G::Scalar::one() - c) * eval_left + c * eval_right
|
// eval = (G::Scalar::ONE - c) * eval_left + c * eval_right
|
||||||
// eval is claimed evaluation of input||output(r, c), which can be proven by proving input(r[1..], c) and output(r[1..], c)
|
// eval is claimed evaluation of input||output(r, c), which can be proven by proving input(r[1..], c) and output(r[1..], c)
|
||||||
let rand_ext = {
|
let rand_ext = {
|
||||||
let mut r = r_sat.clone();
|
let mut r = r_sat.clone();
|
||||||
@@ -1233,13 +1233,13 @@ impl<G: Group, EE: EvaluationEngineTrait<G, CE = G::CE>> RelaxedR1CSSNARKTrait<G
|
|||||||
.iter()
|
.iter()
|
||||||
.zip(powers_of_rho.iter())
|
.zip(powers_of_rho.iter())
|
||||||
.map(|(e, p)| *e * p)
|
.map(|(e, p)| *e * p)
|
||||||
.fold(G::Scalar::zero(), |acc, item| acc + item);
|
.fold(G::Scalar::ZERO, |acc, item| acc + item);
|
||||||
|
|
||||||
let eval_output = eval_output_vec
|
let eval_output = eval_output_vec
|
||||||
.iter()
|
.iter()
|
||||||
.zip(powers_of_rho.iter())
|
.zip(powers_of_rho.iter())
|
||||||
.map(|(e, p)| *e * p)
|
.map(|(e, p)| *e * p)
|
||||||
.fold(G::Scalar::zero(), |acc, item| acc + item);
|
.fold(G::Scalar::ZERO, |acc, item| acc + item);
|
||||||
|
|
||||||
let comm_output = mem_sc_inst
|
let comm_output = mem_sc_inst
|
||||||
.comm_output_vec
|
.comm_output_vec
|
||||||
@@ -1250,7 +1250,7 @@ impl<G: Group, EE: EvaluationEngineTrait<G, CE = G::CE>> RelaxedR1CSSNARKTrait<G
|
|||||||
|
|
||||||
let weighted_sum = |W: &[Vec<G::Scalar>], s: &[G::Scalar]| -> Vec<G::Scalar> {
|
let weighted_sum = |W: &[Vec<G::Scalar>], s: &[G::Scalar]| -> Vec<G::Scalar> {
|
||||||
assert_eq!(W.len(), s.len());
|
assert_eq!(W.len(), s.len());
|
||||||
let mut p = vec![G::Scalar::zero(); W[0].len()];
|
let mut p = vec![G::Scalar::ZERO; W[0].len()];
|
||||||
for i in 0..W.len() {
|
for i in 0..W.len() {
|
||||||
for (j, item) in W[i].iter().enumerate().take(W[i].len()) {
|
for (j, item) in W[i].iter().enumerate().take(W[i].len()) {
|
||||||
p[j] += *item * s[i]
|
p[j] += *item * s[i]
|
||||||
@@ -1265,7 +1265,7 @@ impl<G: Group, EE: EvaluationEngineTrait<G, CE = G::CE>> RelaxedR1CSSNARKTrait<G
|
|||||||
.iter()
|
.iter()
|
||||||
.zip(powers_of_rho.iter())
|
.zip(powers_of_rho.iter())
|
||||||
.map(|(e, p)| *e * p)
|
.map(|(e, p)| *e * p)
|
||||||
.fold(G::Scalar::zero(), |acc, item| acc + item);
|
.fold(G::Scalar::ZERO, |acc, item| acc + item);
|
||||||
|
|
||||||
// eval_output = output(r_sat)
|
// eval_output = output(r_sat)
|
||||||
w_u_vec.push((
|
w_u_vec.push((
|
||||||
@@ -1281,8 +1281,8 @@ impl<G: Group, EE: EvaluationEngineTrait<G, CE = G::CE>> RelaxedR1CSSNARKTrait<G
|
|||||||
|
|
||||||
// claimed_product = output(1, ..., 1, 0)
|
// claimed_product = output(1, ..., 1, 0)
|
||||||
let x = {
|
let x = {
|
||||||
let mut x = vec![G::Scalar::one(); r_sat.len()];
|
let mut x = vec![G::Scalar::ONE; r_sat.len()];
|
||||||
x[r_sat.len() - 1] = G::Scalar::zero();
|
x[r_sat.len() - 1] = G::Scalar::ZERO;
|
||||||
x
|
x
|
||||||
};
|
};
|
||||||
w_u_vec.push((
|
w_u_vec.push((
|
||||||
@@ -1457,7 +1457,7 @@ impl<G: Group, EE: EvaluationEngineTrait<G, CE = G::CE>> RelaxedR1CSSNARKTrait<G
|
|||||||
.iter()
|
.iter()
|
||||||
.zip(powers_of_rho.iter())
|
.zip(powers_of_rho.iter())
|
||||||
.map(|(u, p)| u.e * p)
|
.map(|(u, p)| u.e * p)
|
||||||
.fold(G::Scalar::zero(), |acc, item| acc + item);
|
.fold(G::Scalar::ZERO, |acc, item| acc + item);
|
||||||
|
|
||||||
let mut polys_left: Vec<MultilinearPolynomial<G::Scalar>> = w_vec_padded
|
let mut polys_left: Vec<MultilinearPolynomial<G::Scalar>> = w_vec_padded
|
||||||
.iter()
|
.iter()
|
||||||
@@ -1499,7 +1499,7 @@ impl<G: Group, EE: EvaluationEngineTrait<G, CE = G::CE>> RelaxedR1CSSNARKTrait<G
|
|||||||
.iter()
|
.iter()
|
||||||
.zip(powers_of_gamma.iter())
|
.zip(powers_of_gamma.iter())
|
||||||
.map(|(e, g_i)| *e * *g_i)
|
.map(|(e, g_i)| *e * *g_i)
|
||||||
.fold(G::Scalar::zero(), |acc, item| acc + item);
|
.fold(G::Scalar::ZERO, |acc, item| acc + item);
|
||||||
|
|
||||||
let eval_arg = EE::prove(
|
let eval_arg = EE::prove(
|
||||||
ck,
|
ck,
|
||||||
@@ -1674,7 +1674,7 @@ impl<G: Group, EE: EvaluationEngineTrait<G, CE = G::CE>> RelaxedR1CSSNARKTrait<G
|
|||||||
* rand_eq_bound_r_sat
|
* rand_eq_bound_r_sat
|
||||||
* (self.eval_left_arr[i] * self.eval_right_arr[i] - self.eval_output_arr[i])
|
* (self.eval_left_arr[i] * self.eval_right_arr[i] - self.eval_output_arr[i])
|
||||||
})
|
})
|
||||||
.fold(G::Scalar::zero(), |acc, item| acc + item);
|
.fold(G::Scalar::ZERO, |acc, item| acc + item);
|
||||||
let claim_outer_final_expected = coeffs[8]
|
let claim_outer_final_expected = coeffs[8]
|
||||||
* taus_bound_r_sat
|
* taus_bound_r_sat
|
||||||
* (self.eval_Az * self.eval_Bz - U.u * self.eval_Cz - self.eval_E);
|
* (self.eval_Az * self.eval_Bz - U.u * self.eval_Cz - self.eval_E);
|
||||||
@@ -1712,7 +1712,7 @@ impl<G: Group, EE: EvaluationEngineTrait<G, CE = G::CE>> RelaxedR1CSSNARKTrait<G
|
|||||||
// into claims about input and output
|
// into claims about input and output
|
||||||
let c = transcript.squeeze(b"c")?;
|
let c = transcript.squeeze(b"c")?;
|
||||||
|
|
||||||
// eval = (G::Scalar::one() - c) * eval_left + c * eval_right
|
// eval = (G::Scalar::ONE - c) * eval_left + c * eval_right
|
||||||
// eval is claimed evaluation of input||output(r, c), which can be proven by proving input(r[1..], c) and output(r[1..], c)
|
// eval is claimed evaluation of input||output(r, c), which can be proven by proving input(r[1..], c) and output(r[1..], c)
|
||||||
let rand_ext = {
|
let rand_ext = {
|
||||||
let mut r = r_sat.clone();
|
let mut r = r_sat.clone();
|
||||||
@@ -1744,14 +1744,14 @@ impl<G: Group, EE: EvaluationEngineTrait<G, CE = G::CE>> RelaxedR1CSSNARKTrait<G
|
|||||||
.iter()
|
.iter()
|
||||||
.zip(powers_of_rho.iter())
|
.zip(powers_of_rho.iter())
|
||||||
.map(|(e, p)| *e * p)
|
.map(|(e, p)| *e * p)
|
||||||
.fold(G::Scalar::zero(), |acc, item| acc + item);
|
.fold(G::Scalar::ZERO, |acc, item| acc + item);
|
||||||
|
|
||||||
let eval_output = self
|
let eval_output = self
|
||||||
.eval_output_arr
|
.eval_output_arr
|
||||||
.iter()
|
.iter()
|
||||||
.zip(powers_of_rho.iter())
|
.zip(powers_of_rho.iter())
|
||||||
.map(|(e, p)| *e * p)
|
.map(|(e, p)| *e * p)
|
||||||
.fold(G::Scalar::zero(), |acc, item| acc + item);
|
.fold(G::Scalar::ZERO, |acc, item| acc + item);
|
||||||
|
|
||||||
let comm_output = comm_output_vec
|
let comm_output = comm_output_vec
|
||||||
.iter()
|
.iter()
|
||||||
@@ -1764,7 +1764,7 @@ impl<G: Group, EE: EvaluationEngineTrait<G, CE = G::CE>> RelaxedR1CSSNARKTrait<G
|
|||||||
.iter()
|
.iter()
|
||||||
.zip(powers_of_rho.iter())
|
.zip(powers_of_rho.iter())
|
||||||
.map(|(e, p)| *e * p)
|
.map(|(e, p)| *e * p)
|
||||||
.fold(G::Scalar::zero(), |acc, item| acc + item);
|
.fold(G::Scalar::ZERO, |acc, item| acc + item);
|
||||||
|
|
||||||
// eval_output = output(r_sat)
|
// eval_output = output(r_sat)
|
||||||
u_vec.push(PolyEvalInstance {
|
u_vec.push(PolyEvalInstance {
|
||||||
@@ -1775,8 +1775,8 @@ impl<G: Group, EE: EvaluationEngineTrait<G, CE = G::CE>> RelaxedR1CSSNARKTrait<G
|
|||||||
|
|
||||||
// claimed_product = output(1, ..., 1, 0)
|
// claimed_product = output(1, ..., 1, 0)
|
||||||
let x = {
|
let x = {
|
||||||
let mut x = vec![G::Scalar::one(); r_sat.len()];
|
let mut x = vec![G::Scalar::ONE; r_sat.len()];
|
||||||
x[r_sat.len() - 1] = G::Scalar::zero();
|
x[r_sat.len() - 1] = G::Scalar::ZERO;
|
||||||
x
|
x
|
||||||
};
|
};
|
||||||
u_vec.push(PolyEvalInstance {
|
u_vec.push(PolyEvalInstance {
|
||||||
@@ -1842,9 +1842,9 @@ impl<G: Group, EE: EvaluationEngineTrait<G, CE = G::CE>> RelaxedR1CSSNARKTrait<G
|
|||||||
let (factor, r_prod_unpad) = {
|
let (factor, r_prod_unpad) = {
|
||||||
let l = vk.S_comm.N.log_2() - (2 * vk.num_vars).log_2();
|
let l = vk.S_comm.N.log_2() - (2 * vk.num_vars).log_2();
|
||||||
|
|
||||||
let mut factor = G::Scalar::one();
|
let mut factor = G::Scalar::ONE;
|
||||||
for r_p in r_prod.iter().take(l) {
|
for r_p in r_prod.iter().take(l) {
|
||||||
factor *= G::Scalar::one() - r_p
|
factor *= G::Scalar::ONE - r_p
|
||||||
}
|
}
|
||||||
|
|
||||||
let r_prod_unpad = {
|
let r_prod_unpad = {
|
||||||
@@ -1868,7 +1868,7 @@ impl<G: Group, EE: EvaluationEngineTrait<G, CE = G::CE>> RelaxedR1CSSNARKTrait<G
|
|||||||
.evaluate(&r_prod_unpad[1..])
|
.evaluate(&r_prod_unpad[1..])
|
||||||
};
|
};
|
||||||
let eval_Z =
|
let eval_Z =
|
||||||
factor * ((G::Scalar::one() - r_prod_unpad[0]) * self.eval_W + r_prod_unpad[0] * eval_X);
|
factor * ((G::Scalar::ONE - r_prod_unpad[0]) * self.eval_W + r_prod_unpad[0] * eval_X);
|
||||||
|
|
||||||
(eval_Z, r_prod_unpad)
|
(eval_Z, r_prod_unpad)
|
||||||
};
|
};
|
||||||
@@ -1884,7 +1884,7 @@ impl<G: Group, EE: EvaluationEngineTrait<G, CE = G::CE>> RelaxedR1CSSNARKTrait<G
|
|||||||
let addr = IdentityPolynomial::new(r_prod.len()).evaluate(&r_prod);
|
let addr = IdentityPolynomial::new(r_prod.len()).evaluate(&r_prod);
|
||||||
let val = EqPolynomial::new(tau.to_vec()).evaluate(&r_prod);
|
let val = EqPolynomial::new(tau.to_vec()).evaluate(&r_prod);
|
||||||
(
|
(
|
||||||
hash_func(&addr, &val, &G::Scalar::zero()),
|
hash_func(&addr, &val, &G::Scalar::ZERO),
|
||||||
hash_func(&addr, &val, &self.eval_row_audit_ts),
|
hash_func(&addr, &val, &self.eval_row_audit_ts),
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
@@ -1899,7 +1899,7 @@ impl<G: Group, EE: EvaluationEngineTrait<G, CE = G::CE>> RelaxedR1CSSNARKTrait<G
|
|||||||
hash_func(
|
hash_func(
|
||||||
&self.eval_row,
|
&self.eval_row,
|
||||||
&self.eval_E_row_at_r_prod,
|
&self.eval_E_row_at_r_prod,
|
||||||
&(self.eval_row_read_ts + G::Scalar::one()),
|
&(self.eval_row_read_ts + G::Scalar::ONE),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
@@ -1917,7 +1917,7 @@ impl<G: Group, EE: EvaluationEngineTrait<G, CE = G::CE>> RelaxedR1CSSNARKTrait<G
|
|||||||
let addr = IdentityPolynomial::new(r_prod.len()).evaluate(&r_prod);
|
let addr = IdentityPolynomial::new(r_prod.len()).evaluate(&r_prod);
|
||||||
let val = eval_Z;
|
let val = eval_Z;
|
||||||
(
|
(
|
||||||
hash_func(&addr, &val, &G::Scalar::zero()),
|
hash_func(&addr, &val, &G::Scalar::ZERO),
|
||||||
hash_func(&addr, &val, &self.eval_col_audit_ts),
|
hash_func(&addr, &val, &self.eval_col_audit_ts),
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
@@ -1932,7 +1932,7 @@ impl<G: Group, EE: EvaluationEngineTrait<G, CE = G::CE>> RelaxedR1CSSNARKTrait<G
|
|||||||
hash_func(
|
hash_func(
|
||||||
&self.eval_col,
|
&self.eval_col,
|
||||||
&self.eval_E_col_at_r_prod,
|
&self.eval_E_col_at_r_prod,
|
||||||
&(self.eval_col_read_ts + G::Scalar::one()),
|
&(self.eval_col_read_ts + G::Scalar::ONE),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
@@ -1985,7 +1985,7 @@ impl<G: Group, EE: EvaluationEngineTrait<G, CE = G::CE>> RelaxedR1CSSNARKTrait<G
|
|||||||
.iter()
|
.iter()
|
||||||
.zip(powers_of_rho.iter())
|
.zip(powers_of_rho.iter())
|
||||||
.map(|(u, p)| u.e * p)
|
.map(|(u, p)| u.e * p)
|
||||||
.fold(G::Scalar::zero(), |acc, item| acc + item);
|
.fold(G::Scalar::ZERO, |acc, item| acc + item);
|
||||||
|
|
||||||
let num_rounds_z = u_vec_padded[0].x.len();
|
let num_rounds_z = u_vec_padded[0].x.len();
|
||||||
let (claim_batch_final, r_z) =
|
let (claim_batch_final, r_z) =
|
||||||
@@ -2005,7 +2005,7 @@ impl<G: Group, EE: EvaluationEngineTrait<G, CE = G::CE>> RelaxedR1CSSNARKTrait<G
|
|||||||
.zip(self.evals_batch_arr.iter())
|
.zip(self.evals_batch_arr.iter())
|
||||||
.zip(powers_of_rho.iter())
|
.zip(powers_of_rho.iter())
|
||||||
.map(|((e_i, p_i), rho_i)| *e_i * *p_i * rho_i)
|
.map(|((e_i, p_i), rho_i)| *e_i * *p_i * rho_i)
|
||||||
.fold(G::Scalar::zero(), |acc, item| acc + item)
|
.fold(G::Scalar::ZERO, |acc, item| acc + item)
|
||||||
};
|
};
|
||||||
|
|
||||||
if claim_batch_final != claim_batch_final_expected {
|
if claim_batch_final != claim_batch_final_expected {
|
||||||
@@ -2027,7 +2027,7 @@ impl<G: Group, EE: EvaluationEngineTrait<G, CE = G::CE>> RelaxedR1CSSNARKTrait<G
|
|||||||
.iter()
|
.iter()
|
||||||
.zip(powers_of_gamma.iter())
|
.zip(powers_of_gamma.iter())
|
||||||
.map(|(e, g_i)| *e * *g_i)
|
.map(|(e, g_i)| *e * *g_i)
|
||||||
.fold(G::Scalar::zero(), |acc, item| acc + item);
|
.fold(G::Scalar::ZERO, |acc, item| acc + item);
|
||||||
|
|
||||||
// verify
|
// verify
|
||||||
EE::verify(
|
EE::verify(
|
||||||
@@ -2055,7 +2055,7 @@ impl<G: Group, SC: StepCircuit<G::Scalar>> Circuit<G::Scalar> for SpartanCircuit
|
|||||||
let arity = self.sc.arity();
|
let arity = self.sc.arity();
|
||||||
|
|
||||||
// Allocate zi. If inputs.zi is not provided, allocate default value 0
|
// Allocate zi. If inputs.zi is not provided, allocate default value 0
|
||||||
let zero = vec![G::Scalar::zero(); arity];
|
let zero = vec![G::Scalar::ZERO; arity];
|
||||||
let z_i = (0..arity)
|
let z_i = (0..arity)
|
||||||
.map(|i| {
|
.map(|i| {
|
||||||
AllocatedNum::alloc(cs.namespace(|| format!("zi_{i}")), || {
|
AllocatedNum::alloc(cs.namespace(|| format!("zi_{i}")), || {
|
||||||
@@ -2248,7 +2248,7 @@ mod tests {
|
|||||||
let num_steps = 3;
|
let num_steps = 3;
|
||||||
|
|
||||||
// setup inputs
|
// setup inputs
|
||||||
let z0 = vec![<G as Group>::Scalar::zero()];
|
let z0 = vec![<G as Group>::Scalar::ZERO];
|
||||||
let mut z_i = z0;
|
let mut z_i = z0;
|
||||||
|
|
||||||
for _i in 0..num_steps {
|
for _i in 0..num_steps {
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ impl<G: Group> SumcheckProof<G> {
|
|||||||
(eval_point_0, eval_point_2)
|
(eval_point_0, eval_point_2)
|
||||||
})
|
})
|
||||||
.reduce(
|
.reduce(
|
||||||
|| (G::Scalar::zero(), G::Scalar::zero()),
|
|| (G::Scalar::ZERO, G::Scalar::ZERO),
|
||||||
|a, b| (a.0 + b.0, a.1 + b.1),
|
|a, b| (a.0 + b.0, a.1 + b.1),
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -146,8 +146,8 @@ impl<G: Group> SumcheckProof<G> {
|
|||||||
let mut evals: Vec<(G::Scalar, G::Scalar)> = Vec::new();
|
let mut evals: Vec<(G::Scalar, G::Scalar)> = Vec::new();
|
||||||
|
|
||||||
for (poly_A, poly_B) in poly_A_vec.iter().zip(poly_B_vec.iter()) {
|
for (poly_A, poly_B) in poly_A_vec.iter().zip(poly_B_vec.iter()) {
|
||||||
let mut eval_point_0 = G::Scalar::zero();
|
let mut eval_point_0 = G::Scalar::ZERO;
|
||||||
let mut eval_point_2 = G::Scalar::zero();
|
let mut eval_point_2 = G::Scalar::ZERO;
|
||||||
|
|
||||||
let len = poly_A.len() / 2;
|
let len = poly_A.len() / 2;
|
||||||
for i in 0..len {
|
for i in 0..len {
|
||||||
@@ -165,10 +165,10 @@ impl<G: Group> SumcheckProof<G> {
|
|||||||
|
|
||||||
let evals_combined_0 = (0..evals.len())
|
let evals_combined_0 = (0..evals.len())
|
||||||
.map(|i| evals[i].0 * coeffs[i])
|
.map(|i| evals[i].0 * coeffs[i])
|
||||||
.fold(G::Scalar::zero(), |acc, item| acc + item);
|
.fold(G::Scalar::ZERO, |acc, item| acc + item);
|
||||||
let evals_combined_2 = (0..evals.len())
|
let evals_combined_2 = (0..evals.len())
|
||||||
.map(|i| evals[i].1 * coeffs[i])
|
.map(|i| evals[i].1 * coeffs[i])
|
||||||
.fold(G::Scalar::zero(), |acc, item| acc + item);
|
.fold(G::Scalar::ZERO, |acc, item| acc + item);
|
||||||
|
|
||||||
let evals = vec![evals_combined_0, e - evals_combined_0, evals_combined_2];
|
let evals = vec![evals_combined_0, e - evals_combined_0, evals_combined_2];
|
||||||
let poly = UniPoly::from_evals(&evals);
|
let poly = UniPoly::from_evals(&evals);
|
||||||
@@ -251,7 +251,7 @@ impl<G: Group> SumcheckProof<G> {
|
|||||||
(eval_point_0, eval_point_2, eval_point_3)
|
(eval_point_0, eval_point_2, eval_point_3)
|
||||||
})
|
})
|
||||||
.reduce(
|
.reduce(
|
||||||
|| (G::Scalar::zero(), G::Scalar::zero(), G::Scalar::zero()),
|
|| (G::Scalar::ZERO, G::Scalar::ZERO, G::Scalar::ZERO),
|
||||||
|a, b| (a.0 + b.0, a.1 + b.1, a.2 + b.2),
|
|a, b| (a.0 + b.0, a.1 + b.1, a.2 + b.2),
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -353,7 +353,7 @@ impl<G: Group> UniPoly<G> {
|
|||||||
(0..self.coeffs.len())
|
(0..self.coeffs.len())
|
||||||
.into_par_iter()
|
.into_par_iter()
|
||||||
.map(|i| self.coeffs[i])
|
.map(|i| self.coeffs[i])
|
||||||
.reduce(G::Scalar::zero, |a, b| a + b)
|
.reduce(|| G::Scalar::ZERO, |a, b| a + b)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn evaluate(&self, r: &G::Scalar) -> G::Scalar {
|
pub fn evaluate(&self, r: &G::Scalar) -> G::Scalar {
|
||||||
|
|||||||
Reference in New Issue
Block a user