Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 61 additions & 43 deletions src/gadgets/ecc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,11 +158,12 @@ impl<C: Curve> CurvePoint<C> {
mut cs: CS,
condition: &Boolean,
) -> Result<Self, SynthesisError> {
let x_ret_val = self
.x
.value()
.and_then(|x| condition.get_value().map(|b| if b { x * &C::Base::BETA } else { x }));

let x_ret_val = self.x.value().and_then(|x| {
condition
.get_value()
.map(|b| if b { x * &C::Base::BETA } else { x })
});
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not my project, but.. I'll note that particular change harms the semantics. And cargo fmt PRs to mathematical code often create problems.. unless manually pruned.

That said, this PR looks overall less damaging than most cargo fmt PRs to mathematical code, so maybe the authors code close to cargo fmt anyways.


// x_self × ((endo - 1).bit + 1) = x_ret
let (x_self_var, endoer, x_ret_var) = cs.multiply(
|| "x_self × ((endo - 1).bit + 1) = x_ret",
Expand All @@ -183,9 +184,9 @@ impl<C: Curve> CurvePoint<C> {
cs.enforce_zero(
LinearCombination::from(endoer)
- CS::ONE
- &condition.lc(CS::ONE, Coeff::Full(C::Base::BETA - &C::Base::one()))
- &condition.lc(CS::ONE, Coeff::Full(C::Base::BETA - &C::Base::one())),
);

let x_ret = AllocatedNum::from_raw_unchecked(x_ret_val, x_ret_var);

Ok(CurvePoint {
Expand Down Expand Up @@ -1634,67 +1635,86 @@ impl<C: Curve> CurvePoint<C> {

let mut acc = self.double(cs.namespace(|| "[2] Acc"))?;
acc = acc.add_incomplete(cs.namespace(|| "[3] Acc"), self)?;

for i in 1..64 {
let should_negate = &other[i * 2];
let should_endo = &other[i * 2 + 1];

let base = self.conditional_neg(
cs.namespace(|| format!("conditional negation {}", i)),
&Boolean::from(should_negate.clone())
&Boolean::from(should_negate.clone()),
)?;

acc = acc.double_and_add_incomplete(cs.namespace(|| format!("double and add {}", i)), &base)?;
acc = acc.double_and_add_incomplete(
cs.namespace(|| format!("double and add {}", i)),
&base,
)?;
acc = acc.conditional_endo(
cs.namespace(|| format!("conditional endo {}", i)),
&Boolean::from(should_endo.clone())
&Boolean::from(should_endo.clone()),
)?;
}

let (x, y) = acc.get_xy();

let mut xfvalue = None;
let (a, b, xf) = cs.multiply(|| "final x coordinate", || {
let x = x.value().ok_or(SynthesisError::AssignmentMissing)?;
let is_identity = self.is_identity.get_value().ok_or(SynthesisError::AssignmentMissing)?;
let is_identity = if is_identity {
Field::zero()
} else {
Field::one()
};
let (a, b, xf) = cs.multiply(
|| "final x coordinate",
|| {
let x = x.value().ok_or(SynthesisError::AssignmentMissing)?;
let is_identity = self
.is_identity
.get_value()
.ok_or(SynthesisError::AssignmentMissing)?;
let is_identity = if is_identity {
Field::zero()
} else {
Field::one()
};

let rhs = x * &is_identity;
xfvalue = Some(rhs);
let rhs = x * &is_identity;
xfvalue = Some(rhs);

Ok((x, is_identity, rhs))
})?;
Ok((x, is_identity, rhs))
},
)?;
let xlc = x.lc(&mut cs);
cs.enforce_zero(LinearCombination::from(a) - &xlc);
cs.enforce_zero(LinearCombination::from(b) - &self.is_identity.not().lc(CS::ONE, Coeff::One));
cs.enforce_zero(
LinearCombination::from(b) - &self.is_identity.not().lc(CS::ONE, Coeff::One),
);

let mut yfvalue = None;
let (a, b, yf) = cs.multiply(|| "final y coordinate", || {
let y = y.value().ok_or(SynthesisError::AssignmentMissing)?;
let is_identity = self.is_identity.get_value().ok_or(SynthesisError::AssignmentMissing)?;
let is_identity = if is_identity {
Field::zero()
} else {
Field::one()
};
let (a, b, yf) = cs.multiply(
|| "final y coordinate",
|| {
let y = y.value().ok_or(SynthesisError::AssignmentMissing)?;
let is_identity = self
.is_identity
.get_value()
.ok_or(SynthesisError::AssignmentMissing)?;
let is_identity = if is_identity {
Field::zero()
} else {
Field::one()
};

let rhs = y * &is_identity;
yfvalue = Some(rhs);
let rhs = y * &is_identity;
yfvalue = Some(rhs);

Ok((y, is_identity, rhs))
})?;
Ok((y, is_identity, rhs))
},
)?;
let ylc = y.lc(&mut cs);
cs.enforce_zero(LinearCombination::from(a) - &ylc);
cs.enforce_zero(LinearCombination::from(b) - &self.is_identity.not().lc(CS::ONE, Coeff::One));
cs.enforce_zero(
LinearCombination::from(b) - &self.is_identity.not().lc(CS::ONE, Coeff::One),
);

Ok(CurvePoint {
x: AllocatedNum::from_raw_unchecked(xfvalue, xf).into(),
y: AllocatedNum::from_raw_unchecked(yfvalue, yf).into(),
is_identity: self.is_identity.clone()
is_identity: self.is_identity.clone(),
})

/*
Expand Down Expand Up @@ -2165,8 +2185,7 @@ mod test {
cs.enforce_zero(ppos_x_lc - (Coeff::Full(two_x), CS::ONE));
cs.enforce_zero(ppos_y_lc - (Coeff::Full(two_y), CS::ONE));

let pneg =
p.conditional_endo(cs.namespace(|| "endo"), &Boolean::constant(true))?;
let pneg = p.conditional_endo(cs.namespace(|| "endo"), &Boolean::constant(true))?;
let (pneg_x, pneg_y) = pneg.get_xy();
let pneg_x_lc = pneg_x.lc(&mut cs);
let pneg_y_lc = pneg_y.lc(&mut cs);
Expand Down Expand Up @@ -2902,9 +2921,8 @@ mod test {
) -> Result<(), SynthesisError> {
let p = CurvePoint::<Ec1>::witness(&mut cs, || Ok(Ec1::one()))?;

let mut scalar5 = vec![
AllocatedBit::alloc(cs.namespace(|| "bit"), || Ok(true))?; 128
];
let mut scalar5 =
vec![AllocatedBit::alloc(cs.namespace(|| "bit"), || Ok(true))?; 128];
scalar5[1] = AllocatedBit::alloc(cs.namespace(|| "bit"), || Ok(false))?;
scalar5[2] = AllocatedBit::alloc(cs.namespace(|| "bit"), || Ok(false))?;
scalar5[3] = AllocatedBit::alloc(cs.namespace(|| "bit"), || Ok(false))?;
Expand Down
2 changes: 1 addition & 1 deletion src/gadgets/num.rs
Original file line number Diff line number Diff line change
Expand Up @@ -545,7 +545,7 @@ impl<F: Field> Combination<F> {
pub fn zero() -> Self {
Combination {
value: Some(F::zero()),
terms: vec![]
terms: vec![],
}
}

Expand Down
1 change: 0 additions & 1 deletion src/proofs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,6 @@ impl<C: Curve> Proof<C> {
_coeff: Coeff<F>,
_y: &Self::LinearConstraintIndex,
) {

}

/// Compute a `LinearConstraintIndex` from `q`.
Expand Down
46 changes: 38 additions & 8 deletions src/recursion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -587,8 +587,16 @@ impl<'a, E1: Curve, E2: Curve<Base = E1::Scalar>, Inner: RecursiveCircuit<E1::Sc

let mut truncate_by = 0;
for (i, (lhs, rhs)) in lhs.iter().zip(rhs.iter()).take(250).enumerate() {
lhs_lc = lhs_lc + (Coeff::Full(coeff), Num::from(AllocatedNum::from(lhs.clone())));
rhs_lc = rhs_lc + (Coeff::Full(coeff), Num::from(AllocatedNum::from(rhs.clone())));
lhs_lc = lhs_lc
+ (
Coeff::Full(coeff),
Num::from(AllocatedNum::from(lhs.clone())),
);
rhs_lc = rhs_lc
+ (
Coeff::Full(coeff),
Num::from(AllocatedNum::from(rhs.clone())),
);

coeff = coeff + &coeff;
truncate_by = i + 1;
Expand All @@ -598,7 +606,7 @@ impl<'a, E1: Curve, E2: Curve<Base = E1::Scalar>, Inner: RecursiveCircuit<E1::Sc
cs.namespace(|| format!("check {}", i)),
base_case.clone(),
&lhs_lc,
&rhs_lc
&rhs_lc,
)?;

lhs = &lhs[truncate_by..];
Expand Down Expand Up @@ -1290,8 +1298,18 @@ impl<'a, E1: Curve, E2: Curve<Base = E1::Scalar>, Inner: RecursiveCircuit<E1::Sc
.get_xy();
{
let mut cs = cs.namespace(|| format!("p_{} == [a_{}] g_new", j, j));
self.num_equal_unless_base_case(cs.namespace(|| "x"), base_case.clone(), &Combination::from(x1), &Combination::from(x2))?;
self.num_equal_unless_base_case(cs.namespace(|| "y"), base_case.clone(), &Combination::from(y1), &Combination::from(y2))?;
self.num_equal_unless_base_case(
cs.namespace(|| "x"),
base_case.clone(),
&Combination::from(x1),
&Combination::from(x2),
)?;
self.num_equal_unless_base_case(
cs.namespace(|| "y"),
base_case.clone(),
&Combination::from(y1),
&Combination::from(y2),
)?;
}

let (x1, y1) = v[j].get_xy();
Expand All @@ -1301,8 +1319,18 @@ impl<'a, E1: Curve, E2: Curve<Base = E1::Scalar>, Inner: RecursiveCircuit<E1::Sc
.get_xy();
{
let mut cs = cs.namespace(|| format!("v_{} == [a_{} b_{}] g", j, j, j));
self.num_equal_unless_base_case(cs.namespace(|| "x"), base_case.clone(), &Combination::from(x1), &Combination::from(x2))?;
self.num_equal_unless_base_case(cs.namespace(|| "y"), base_case.clone(), &Combination::from(y1), &Combination::from(y2))?;
self.num_equal_unless_base_case(
cs.namespace(|| "x"),
base_case.clone(),
&Combination::from(x1),
&Combination::from(x2),
)?;
self.num_equal_unless_base_case(
cs.namespace(|| "y"),
base_case.clone(),
&Combination::from(y1),
&Combination::from(y2),
)?;
}
}

Expand All @@ -1328,7 +1356,9 @@ impl<'a, E1: Curve, E2: Curve<Base = E1::Scalar>, Inner: RecursiveCircuit<E1::Sc
bits: &[AllocatedBit],
) -> Result<AllocatedNum<E1::Scalar>, SynthesisError> {
assert_eq!(bits.len(), 128);
let mut acc = Combination::from(Num::constant(E1::Scalar::one() + &E1::Scalar::one() + &E1::Scalar::one()));
let mut acc = Combination::from(Num::constant(
E1::Scalar::one() + &E1::Scalar::one() + &E1::Scalar::one(),
));

for i in 1..64 {
let should_negate = &bits[i * 2];
Expand Down