|
@ -52,10 +52,7 @@ pub fn nat_to_limbs( |
|
|
.collect(),
|
|
|
.collect(),
|
|
|
)
|
|
|
)
|
|
|
} else {
|
|
|
} else {
|
|
|
eprintln!(
|
|
|
|
|
|
"nat {} does not fit in {} limbs of width {}",
|
|
|
|
|
|
nat, n_limbs, limb_width
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
eprintln!("nat {nat} does not fit in {n_limbs} limbs of width {limb_width}");
|
|
|
Err(SynthesisError::Unsatisfiable)
|
|
|
Err(SynthesisError::Unsatisfiable)
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@ -131,7 +128,7 @@ impl BigNat { |
|
|
let limbs = (0..n_limbs)
|
|
|
let limbs = (0..n_limbs)
|
|
|
.map(|limb_i| {
|
|
|
.map(|limb_i| {
|
|
|
cs.alloc(
|
|
|
cs.alloc(
|
|
|
|| format!("limb {}", limb_i),
|
|
|
|
|
|
|
|
|
|| format!("limb {limb_i}"),
|
|
|
|| match values_cell {
|
|
|
|| match values_cell {
|
|
|
Ok(ref vs) => {
|
|
|
Ok(ref vs) => {
|
|
|
if vs.len() != n_limbs {
|
|
|
if vs.len() != n_limbs {
|
|
@ -149,7 +146,7 @@ impl BigNat { |
|
|
// Hack b/c SynthesisError and io::Error don't implement Clone
|
|
|
// Hack b/c SynthesisError and io::Error don't implement Clone
|
|
|
Err(ref e) => Err(SynthesisError::from(std::io::Error::new(
|
|
|
Err(ref e) => Err(SynthesisError::from(std::io::Error::new(
|
|
|
std::io::ErrorKind::Other,
|
|
|
std::io::ErrorKind::Other,
|
|
|
format!("{}", e),
|
|
|
|
|
|
|
|
|
format!("{e}"),
|
|
|
))),
|
|
|
))),
|
|
|
},
|
|
|
},
|
|
|
)
|
|
|
)
|
|
@ -189,7 +186,7 @@ impl BigNat { |
|
|
let limbs = (0..n_limbs)
|
|
|
let limbs = (0..n_limbs)
|
|
|
.map(|limb_i| {
|
|
|
.map(|limb_i| {
|
|
|
cs.alloc(
|
|
|
cs.alloc(
|
|
|
|| format!("limb {}", limb_i),
|
|
|
|
|
|
|
|
|
|| format!("limb {limb_i}"),
|
|
|
|| match all_values_cell {
|
|
|
|| match all_values_cell {
|
|
|
Ok((ref vs, ref v)) => {
|
|
|
Ok((ref vs, ref v)) => {
|
|
|
if value.is_none() {
|
|
|
if value.is_none() {
|
|
@ -201,7 +198,7 @@ impl BigNat { |
|
|
// Hack b/c SynthesisError and io::Error don't implement Clone
|
|
|
// Hack b/c SynthesisError and io::Error don't implement Clone
|
|
|
Err(ref e) => Err(SynthesisError::from(std::io::Error::new(
|
|
|
Err(ref e) => Err(SynthesisError::from(std::io::Error::new(
|
|
|
std::io::ErrorKind::Other,
|
|
|
std::io::ErrorKind::Other,
|
|
|
format!("{}", e),
|
|
|
|
|
|
|
|
|
format!("{e}"),
|
|
|
))),
|
|
|
))),
|
|
|
},
|
|
|
},
|
|
|
)
|
|
|
)
|
|
@ -272,7 +269,7 @@ impl BigNat { |
|
|
(0..self.limbs.len()).map(|i| self.limb_values.as_ref().map(|vs| vs[i]));
|
|
|
(0..self.limbs.len()).map(|i| self.limb_values.as_ref().map(|vs| vs[i]));
|
|
|
for (i, (limb, limb_value)) in self.limbs.iter().zip(limb_values_split).enumerate() {
|
|
|
for (i, (limb, limb_value)) in self.limbs.iter().zip(limb_values_split).enumerate() {
|
|
|
Num::new(limb_value, limb.clone())
|
|
|
Num::new(limb_value, limb.clone())
|
|
|
.fits_in_bits(cs.namespace(|| format!("{}", i)), self.params.limb_width)?;
|
|
|
|
|
|
|
|
|
.fits_in_bits(cs.namespace(|| format!("{i}")), self.params.limb_width)?;
|
|
|
}
|
|
|
}
|
|
|
Ok(())
|
|
|
Ok(())
|
|
|
}
|
|
|
}
|
|
@ -291,7 +288,7 @@ impl BigNat { |
|
|
.enumerate()
|
|
|
.enumerate()
|
|
|
.map(|(i, (limb, limb_value))| {
|
|
|
.map(|(i, (limb, limb_value))| {
|
|
|
Num::new(limb_value, limb.clone()).decompose(
|
|
|
Num::new(limb_value, limb.clone()).decompose(
|
|
|
cs.namespace(|| format!("subdecmop {}", i)),
|
|
|
|
|
|
|
|
|
cs.namespace(|| format!("subdecmop {i}")),
|
|
|
self.params.limb_width,
|
|
|
self.params.limb_width,
|
|
|
)
|
|
|
)
|
|
|
})
|
|
|
})
|
|
@ -370,7 +367,7 @@ impl BigNat { |
|
|
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}")), || {
|
|
|
Ok(
|
|
|
Ok(
|
|
|
nat_to_f(
|
|
|
nat_to_f(
|
|
|
&((f_to_nat(&self.limb_values.grab()?[i])
|
|
|
&((f_to_nat(&self.limb_values.grab()?[i])
|
|
@ -385,7 +382,7 @@ impl BigNat { |
|
|
accumulated_extra += max_word;
|
|
|
accumulated_extra += max_word;
|
|
|
|
|
|
|
|
|
cs.enforce(
|
|
|
cs.enforce(
|
|
|
|| format!("carry {}", i),
|
|
|
|
|
|
|
|
|
|| format!("carry {i}"),
|
|
|
|lc| lc,
|
|
|
|lc| lc,
|
|
|
|lc| lc,
|
|
|
|lc| lc,
|
|
|
|lc| {
|
|
|
|lc| {
|
|
@ -402,10 +399,10 @@ impl BigNat { |
|
|
accumulated_extra /= &target_base;
|
|
|
accumulated_extra /= &target_base;
|
|
|
|
|
|
|
|
|
if i < n - 1 {
|
|
|
if i < n - 1 {
|
|
|
carry.fits_in_bits(cs.namespace(|| format!("carry {} decomp", i)), carry_bits)?;
|
|
|
|
|
|
|
|
|
carry.fits_in_bits(cs.namespace(|| format!("carry {i} decomp")), carry_bits)?;
|
|
|
} else {
|
|
|
} else {
|
|
|
cs.enforce(
|
|
|
cs.enforce(
|
|
|
|| format!("carry {} is out", i),
|
|
|
|
|
|
|
|
|
|| format!("carry {i} is out"),
|
|
|
|lc| lc,
|
|
|
|lc| lc,
|
|
|
|lc| lc,
|
|
|
|lc| lc,
|
|
|
|lc| lc + &carry.num - (nat_to_f(&accumulated_extra).unwrap(), CS::one()),
|
|
|
|lc| lc + &carry.num - (nat_to_f(&accumulated_extra).unwrap(), CS::one()),
|
|
@ -416,7 +413,7 @@ impl BigNat { |
|
|
|
|
|
|
|
|
for (i, zero_limb) in self.limbs.iter().enumerate().skip(n) {
|
|
|
for (i, zero_limb) in self.limbs.iter().enumerate().skip(n) {
|
|
|
cs.enforce(
|
|
|
cs.enforce(
|
|
|
|| format!("zero self {}", i),
|
|
|
|
|
|
|
|
|
|| format!("zero self {i}"),
|
|
|
|lc| lc,
|
|
|
|lc| lc,
|
|
|
|lc| lc,
|
|
|
|lc| lc,
|
|
|
|lc| lc + zero_limb,
|
|
|
|lc| lc + zero_limb,
|
|
@ -424,7 +421,7 @@ impl BigNat { |
|
|
}
|
|
|
}
|
|
|
for (i, zero_limb) in other.limbs.iter().enumerate().skip(n) {
|
|
|
for (i, zero_limb) in other.limbs.iter().enumerate().skip(n) {
|
|
|
cs.enforce(
|
|
|
cs.enforce(
|
|
|
|| format!("zero other {}", i),
|
|
|
|
|
|
|
|
|
|| format!("zero other {i}"),
|
|
|
|lc| lc,
|
|
|
|lc| lc,
|
|
|
|lc| lc,
|
|
|
|lc| lc,
|
|
|
|lc| lc + zero_limb,
|
|
|
|lc| lc + zero_limb,
|
|
@ -707,10 +704,7 @@ impl Polynomial { |
|
|
});
|
|
|
});
|
|
|
let coefficients = (0..n_product_coeffs)
|
|
|
let coefficients = (0..n_product_coeffs)
|
|
|
.map(|i| {
|
|
|
.map(|i| {
|
|
|
Ok(
|
|
|
|
|
|
LinearCombination::zero()
|
|
|
|
|
|
+ cs.alloc(|| format!("prod {}", i), || Ok(values.grab()?[i]))?,
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
Ok(LinearCombination::zero() + cs.alloc(|| format!("prod {i}"), || Ok(values.grab()?[i]))?)
|
|
|
})
|
|
|
})
|
|
|
.collect::<Result<Vec<LinearCombination<Scalar>>, SynthesisError>>()?;
|
|
|
.collect::<Result<Vec<LinearCombination<Scalar>>, SynthesisError>>()?;
|
|
|
let product = Polynomial {
|
|
|
let product = Polynomial {
|
|
@ -722,7 +716,7 @@ impl Polynomial { |
|
|
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| {
|
|
@ -807,7 +801,7 @@ mod tests { |
|
|
.iter()
|
|
|
.iter()
|
|
|
.enumerate()
|
|
|
.enumerate()
|
|
|
.map(|(i, x)| {
|
|
|
.map(|(i, x)| {
|
|
|
Ok(LinearCombination::zero() + cs.alloc(|| format!("coeff_a {}", i), || Ok(*x))?)
|
|
|
|
|
|
|
|
|
Ok(LinearCombination::zero() + cs.alloc(|| format!("coeff_a {i}"), || Ok(*x))?)
|
|
|
})
|
|
|
})
|
|
|
.collect::<Result<Vec<LinearCombination<Scalar>>, SynthesisError>>()?,
|
|
|
.collect::<Result<Vec<LinearCombination<Scalar>>, SynthesisError>>()?,
|
|
|
values: Some(self.a),
|
|
|
values: Some(self.a),
|
|
@ -818,7 +812,7 @@ mod tests { |
|
|
.iter()
|
|
|
.iter()
|
|
|
.enumerate()
|
|
|
.enumerate()
|
|
|
.map(|(i, x)| {
|
|
|
.map(|(i, x)| {
|
|
|
Ok(LinearCombination::zero() + cs.alloc(|| format!("coeff_b {}", i), || Ok(*x))?)
|
|
|
|
|
|
|
|
|
Ok(LinearCombination::zero() + cs.alloc(|| format!("coeff_b {i}"), || Ok(*x))?)
|
|
|
})
|
|
|
})
|
|
|
.collect::<Result<Vec<LinearCombination<Scalar>>, SynthesisError>>()?,
|
|
|
.collect::<Result<Vec<LinearCombination<Scalar>>, SynthesisError>>()?,
|
|
|
values: Some(self.b),
|
|
|
values: Some(self.b),
|
|
|