Skip to content

Commit

Permalink
Merge branch 'master' into touchups
Browse files Browse the repository at this point in the history
  • Loading branch information
tcoratger authored Nov 30, 2024
2 parents 81a3879 + 9ce33e6 commit 31a1714
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 30 deletions.
7 changes: 2 additions & 5 deletions curves/curve-constraint-tests/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ pub mod fields {
AllocationMode::Constant,
];
for &mode in &modes {
let cs = ConstraintSystem::<ConstraintF>::new_ref();
let cs = ConstraintSystem::new_ref();

let mut rng = test_rng();
let a_native = F::rand(&mut rng);
Expand Down Expand Up @@ -152,10 +152,7 @@ pub mod fields {
for c in &mut constants {
*c = UniformRand::rand(&mut test_rng());
}
let bits = [
Boolean::<ConstraintF>::constant(false),
Boolean::constant(true),
];
let bits = [Boolean::constant(false), Boolean::constant(true)];
let lookup_result = AF::two_bit_lookup(&bits, constants.as_ref())?;
assert_eq!(lookup_result.value()?, constants[2]);
assert!(cs.is_satisfied().unwrap());
Expand Down
4 changes: 2 additions & 2 deletions ec/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,8 @@ assert!(new_a.is_in_correct_subgroup_assuming_on_curve());
Besides the foregoing abstract interfaces for elliptic curve groups, `ark-ec` also provides
the following concrete instantiations of common elliptic curve models:

* [*Short Weierstrass*](https://github.com/arkworks-rs/algebra/blob/master/ec/src/models/short_weierstrass.rs) curves. The `AffineRepr` in this case is in typical Short Weierstrass point representation, and the `CurveGroup` is using points in [Jacobian Coordinates](https://en.wikibooks.org/wiki/Cryptography/Prime_Curve/Jacobian_Coordinates).
* [*Twisted Edwards*](https://github.com/arkworks-rs/algebra/blob/master/ec/src/models/twisted_edwards.rs) curves. The `AffineRepr` in this case is in standard Twisted Edwards curve representation, whereas the `CurveGroup` uses points in [Extended Twisted Edwards Coordinates](https://eprint.iacr.org/2008/522.pdf).
* [*Short Weierstrass*](https://github.com/arkworks-rs/algebra/blob/master/ec/src/models/short_weierstrass/mod.rs) curves. The `AffineRepr` in this case is in typical Short Weierstrass point representation, and the `CurveGroup` is using points in [Jacobian Coordinates](https://en.wikibooks.org/wiki/Cryptography/Prime_Curve/Jacobian_Coordinates).
* [*Twisted Edwards*](https://github.com/arkworks-rs/algebra/blob/master/ec/src/models/twisted_edwards/mod.rs) curves. The `AffineRepr` in this case is in standard Twisted Edwards curve representation, whereas the `CurveGroup` uses points in [Extended Twisted Edwards Coordinates](https://eprint.iacr.org/2008/522.pdf).

### Pairings

Expand Down
6 changes: 2 additions & 4 deletions ec/src/pairing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -333,12 +333,10 @@ impl<P: Pairing> Mul<P::ScalarField> for MillerLoopOutput<P> {

/// Preprocesses a G1 element for use in a pairing.
pub fn prepare_g1<E: Pairing>(g: impl Into<E::G1Affine>) -> E::G1Prepared {
let g: E::G1Affine = g.into();
E::G1Prepared::from(g)
E::G1Prepared::from(g.into())
}

/// Preprocesses a G2 element for use in a pairing.
pub fn prepare_g2<E: Pairing>(g: impl Into<E::G2Affine>) -> E::G2Prepared {
let g: E::G2Affine = g.into();
E::G2Prepared::from(g)
E::G2Prepared::from(g.into())
}
8 changes: 3 additions & 5 deletions ec/src/scalar_mul/glv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,11 @@ pub trait GLVConfig: Send + Sync + 'static + SWCurveConfig {
) -> ((bool, Self::ScalarField), (bool, Self::ScalarField)) {
let scalar: BigInt = k.into_bigint().into().into();

let coeff_bigints: [BigInt; 4] = Self::SCALAR_DECOMP_COEFFS.map(|x| {
let [n11, n12, n21, n22] = Self::SCALAR_DECOMP_COEFFS.map(|x| {
let sign = if x.0 { Sign::Plus } else { Sign::Minus };
BigInt::from_biguint(sign, x.1.into())
});

let [n11, n12, n21, n22] = coeff_bigints;

let r = BigInt::from(Self::ScalarField::MODULUS.into());

// beta = vector([k,0]) * self.curve.N_inv
Expand Down Expand Up @@ -81,8 +79,8 @@ pub trait GLVConfig: Send + Sync + 'static + SWCurveConfig {
let k2_abs = BigUint::try_from(k2.abs()).unwrap();

(
(k1.sign() == Sign::Plus, Self::ScalarField::from(k1_abs)),
(k2.sign() == Sign::Plus, Self::ScalarField::from(k2_abs)),
(k1.sign() == Sign::Plus, k1_abs.into()),
(k2.sign() == Sign::Plus, k2_abs.into()),
)
}

Expand Down
139 changes: 125 additions & 14 deletions poly/src/polynomial/univariate/dense.rs
Original file line number Diff line number Diff line change
Expand Up @@ -352,28 +352,28 @@ impl<'a, F: Field> Add<&'a SparsePolynomial<F>> for &DensePolynomial<F> {
}
}


impl<'a, F: Field> AddAssign<&'a Self> for DensePolynomial<F> {
fn add_assign(&mut self, other: &'a Self) {
if other.is_zero() {
self.truncate_leading_zeros();
return;
}

if self.is_zero() {
self.coeffs.truncate(0);
self.coeffs.clear();
self.coeffs.extend_from_slice(&other.coeffs);
} else if other.is_zero() {
} else if self.degree() >= other.degree() {
self.coeffs
.iter_mut()
.zip(&other.coeffs)
.for_each(|(a, b)| {
*a += b;
});
} else {
// Add the necessary number of zero coefficients.
self.coeffs.resize(other.coeffs.len(), F::zero());
let other_coeffs_len = other.coeffs.len();
if other_coeffs_len > self.coeffs.len() {
// Add the necessary number of zero coefficients.
self.coeffs.resize(other_coeffs_len, F::zero());
}

self.coeffs
.iter_mut()
.zip(&other.coeffs)
.for_each(|(a, b)| {
*a += b;
});
.for_each(|(a, b)| *a += b);
}
self.truncate_leading_zeros();
}
Expand Down Expand Up @@ -1311,4 +1311,115 @@ mod tests {
assert!(result.is_zero(), "The resulting polynomial should be zero.");
assert_eq!(result.coeffs, vec![], "Leading zeros were not truncated.");
}

#[test]
fn test_dense_dense_add_assign_with_zero_self() {
// Create a zero polynomial
let mut poly1 = DensePolynomial { coeffs: Vec::new() };

// Create a non-zero polynomial: 2 + 3x
let poly2 = DensePolynomial {
coeffs: vec![Fr::from(2), Fr::from(3)],
};

// Add the non-zero polynomial to the zero polynomial
poly1 += &poly2;

// Check that poly1 now equals poly2
assert_eq!(poly1.coeffs, poly2.coeffs);
}

#[test]
fn test_dense_dense_add_assign_with_zero_other() {
// Create a non-zero polynomial: 2 + 3x
let mut poly1 = DensePolynomial {
coeffs: vec![Fr::from(2), Fr::from(3)],
};

// Create a zero polynomial
let poly2 = DensePolynomial { coeffs: Vec::new() };

// Add the zero polynomial to poly1
poly1 += &poly2;

// Check that poly1 remains unchanged
assert_eq!(poly1.coeffs, vec![Fr::from(2), Fr::from(3)]);
}

#[test]
fn test_dense_dense_add_assign_with_different_degrees() {
// Create a polynomial: 1 + 2x + 3x^2
let mut poly1 = DensePolynomial {
coeffs: vec![Fr::from(1), Fr::from(2), Fr::from(3)],
};

// Create a smaller polynomial: 4 + 5x
let poly2 = DensePolynomial {
coeffs: vec![Fr::from(4), Fr::from(5)],
};

// Add the smaller polynomial to the larger one
poly1 += &poly2;

assert_eq!(poly1.coeffs, vec![Fr::from(5), Fr::from(7), Fr::from(3)]);
}

#[test]
fn test_dense_dense_truncate_leading_zeros_after_addition() {
// Create a first polynomial
let mut poly1 = DensePolynomial {
coeffs: vec![Fr::from(1), Fr::from(2)],
};

// Create another polynomial that will cancel out the first two terms
let poly2 = DensePolynomial {
coeffs: vec![-poly1.coeffs[0], -poly1.coeffs[1]],
};

// Add the two polynomials
poly1 += &poly2;

// Check that the resulting polynomial is zero (empty coefficients)
assert!(poly1.is_zero());
assert_eq!(poly1.coeffs, vec![]);
}

#[test]
fn test_dense_dense_add_assign_with_equal_degrees() {
// Create two polynomials with the same degree
let mut poly1 = DensePolynomial {
coeffs: vec![Fr::from(1), Fr::from(2), Fr::from(3)],
};
let poly2 = DensePolynomial {
coeffs: vec![Fr::from(4), Fr::from(5), Fr::from(6)],
};

// Add the polynomials
poly1 += &poly2;

// Check the resulting coefficients
assert_eq!(poly1.coeffs, vec![Fr::from(5), Fr::from(7), Fr::from(9)]);
}

#[test]
fn test_dense_dense_add_assign_with_other_zero_truncates_leading_zeros() {
use ark_test_curves::bls12_381::Fr;

// Create a polynomial with leading zeros: 1 + 2x + 0x^2 + 0x^3
let mut poly1 = DensePolynomial {
coeffs: vec![Fr::from(1), Fr::from(2), Fr::from(0), Fr::from(0)],
};

// Create a zero polynomial
let poly2 = DensePolynomial { coeffs: Vec::new() };

// Add the zero polynomial to poly1
poly1 += &poly2;

// Check that the leading zeros are truncated
assert_eq!(poly1.coeffs, vec![Fr::from(1), Fr::from(2)]);

// Ensure the polynomial is not zero (as it has non-zero coefficients)
assert!(!poly1.is_zero());
}
}

0 comments on commit 31a1714

Please sign in to comment.