use crate::constraint_system::ecc::Point;
use crate::constraint_system::StandardComposer;
use dusk_bls12_381::BlsScalar;
use dusk_jubjub::{JubJubAffine, JubJubExtended};
impl Point {
pub fn fast_add(
&self,
composer: &mut StandardComposer,
point_b: Point,
) -> Point {
let x_1 = self.x;
let y_1 = self.y;
let x_2 = point_b.x;
let y_2 = point_b.y;
let x_1_scalar = composer.variables.get(&x_1).unwrap();
let y_1_scalar = composer.variables.get(&y_1).unwrap();
let x_2_scalar = composer.variables.get(&x_2).unwrap();
let y_2_scalar = composer.variables.get(&y_2).unwrap();
let p1 = JubJubAffine::from_raw_unchecked(*x_1_scalar, *y_1_scalar);
let p2 = JubJubAffine::from_raw_unchecked(*x_2_scalar, *y_2_scalar);
let point: JubJubAffine = (JubJubExtended::from(p1) + p2).into();
let x_3_scalar = point.get_x();
let y_3_scalar = point.get_y();
let x1_scalar_y2_scalar = x_1_scalar * y_2_scalar;
let x_1_y_2 = composer.add_input(x1_scalar_y2_scalar);
let x_3 = composer.add_input(x_3_scalar);
let y_3 = composer.add_input(y_3_scalar);
composer.w_l.extend(&[x_1, x_3]);
composer.w_r.extend(&[y_1, y_3]);
composer.w_o.extend(&[x_2, composer.zero_var]);
composer.w_4.extend(&[y_2, x_1_y_2]);
let zeros = [BlsScalar::zero(), BlsScalar::zero()];
composer.q_l.extend(&zeros);
composer.q_r.extend(&zeros);
composer.q_c.extend(&zeros);
composer.q_o.extend(&zeros);
composer.q_m.extend(&zeros);
composer.q_4.extend(&zeros);
composer.q_arith.extend(&zeros);
composer.q_range.extend(&zeros);
composer.q_logic.extend(&zeros);
composer.q_fixed_group_add.extend(&zeros);
composer.q_variable_group_add.push(BlsScalar::one());
composer.q_variable_group_add.push(BlsScalar::zero());
composer
.perm
.add_variables_to_map(x_1, y_1, x_2, y_2, composer.n);
composer.n += 1;
composer.perm.add_variables_to_map(
x_3,
y_3,
composer.zero_var,
x_1_y_2,
composer.n,
);
composer.n += 1;
Point { x: x_3, y: y_3 }
}
}
#[cfg(test)]
mod test {
use super::*;
use crate::constraint_system::helper::*;
use dusk_jubjub::GENERATOR;
use dusk_jubjub::{JubJubAffine, JubJubExtended};
#[test]
fn test_curve_addition() {
let res = gadget_tester(
|composer| {
let expected_point: JubJubAffine =
(JubJubExtended::from(GENERATOR)
+ JubJubExtended::from(GENERATOR))
.into();
let x = composer.add_input(GENERATOR.get_x());
let y = composer.add_input(GENERATOR.get_y());
let point_a = Point { x, y };
let point_b = Point { x, y };
let point = point_a.fast_add(composer, point_b);
let point2 = point_a.slow_add(composer, point_b);
composer.assert_equal_point(point, point2);
composer
.assert_equal_public_point(point.into(), expected_point);
},
2000,
);
assert!(res.is_ok());
}
}