fixed Secp256K1Scalar

This commit is contained in:
Nicholas Ward 2021-11-30 15:00:12 -08:00
parent b1bbe30dac
commit 39300bcf01
4 changed files with 61 additions and 41 deletions

View File

@ -84,6 +84,19 @@ macro_rules! test_field_arithmetic {
assert_eq!(base.exp_biguint(&pow), base.exp_biguint(&big_pow));
assert_ne!(base.exp_biguint(&pow), base.exp_biguint(&big_pow_wrong));
}
#[test]
fn inverses() {
type F = $field;
let x = F::rand();
let x1 = x.inverse();
let x2 = x1.inverse();
let x3 = x2.inverse();
assert_eq!(x, x2);
assert_eq!(x1, x3);
}
}
};
}

View File

@ -241,3 +241,10 @@ impl DivAssign for Secp256K1Base {
*self = *self / rhs;
}
}
#[cfg(test)]
mod tests {
use crate::test_field_arithmetic;
test_field_arithmetic!(crate::field::secp256k1_base::Secp256K1Base);
}

View File

@ -80,7 +80,7 @@ impl Field for Secp256K1Scalar {
const NEG_ONE: Self = Self([
0xBFD25E8CD0364140,
0xBAAEDCE6AF48A03B,
0xFFFFFFFFFFFFFC2F,
0xFFFFFFFFFFFFFFFE,
0xFFFFFFFFFFFFFFFF,
]);
@ -105,7 +105,7 @@ impl Field for Secp256K1Scalar {
fn order() -> BigUint {
BigUint::from_slice(&[
0xD0364141, 0xBFD25E8C, 0xAF48A03B, 0xBAAEDCE6, 0xFFFFFC2F, 0xFFFFFFFF, 0xFFFFFFFF,
0xD0364141, 0xBFD25E8C, 0xAF48A03B, 0xBAAEDCE6, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF,
])
}
@ -251,3 +251,10 @@ impl DivAssign for Secp256K1Scalar {
*self = *self / rhs;
}
}
#[cfg(test)]
mod tests {
use crate::test_field_arithmetic;
test_field_arithmetic!(crate::field::secp256k1_scalar::Secp256K1Scalar);
}

View File

@ -18,17 +18,6 @@ impl<C: Curve> AffinePointTarget<C> {
}
}
const WINDOW_BITS: usize = 4;
const BASE: usize = 1 << WINDOW_BITS;
fn digits_per_scalar<C: Curve>() -> usize {
(C::ScalarField::BITS + WINDOW_BITS - 1) / WINDOW_BITS
}
pub struct MulPrecomputationTarget<C: Curve> {
powers: Vec<AffinePointTarget<C>>,
}
impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
pub fn constant_affine_point<C: Curve>(
&mut self,
@ -138,25 +127,6 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
}
}
pub fn mul_precompute<C: Curve>(
&mut self,
p: &AffinePointTarget<C>,
) -> MulPrecomputationTarget<C> {
let num_digits = digits_per_scalar::<C>();
let mut powers = Vec::with_capacity(num_digits);
powers.push(p.clone());
for i in 1..num_digits {
let mut power_i = powers[i - 1].clone();
for _j in 0..WINDOW_BITS {
power_i = self.curve_double(&power_i);
}
powers.push(power_i);
}
MulPrecomputationTarget { powers }
}
pub fn curve_scalar_mul<C: Curve>(
&mut self,
p: &AffinePointTarget<C>,
@ -182,15 +152,10 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
let result_plus_2_i_p = self.curve_add(&result, &two_i_times_p);
let result_x = result.x;
let result_y = result.y;
let result_plus_2_i_p_x = result_plus_2_i_p.x;
let result_plus_2_i_p_y = result_plus_2_i_p.y;
let new_x_if_bit = self.mul_nonnative(bit, &result_plus_2_i_p_x);
let new_x_if_not_bit = self.mul_nonnative(&not_bit, &result_x);
let new_y_if_bit = self.mul_nonnative(bit, &result_plus_2_i_p_y);
let new_y_if_not_bit = self.mul_nonnative(&not_bit, &result_y);
let new_x_if_bit = self.mul_nonnative(bit, &result_plus_2_i_p.x);
let new_x_if_not_bit = self.mul_nonnative(&not_bit, &result.x);
let new_y_if_bit = self.mul_nonnative(bit, &result_plus_2_i_p.y);
let new_y_if_not_bit = self.mul_nonnative(&not_bit, &result.y);
let new_x = self.add_nonnative(&new_x_if_bit, &new_x_if_not_bit);
let new_y = self.add_nonnative(&new_y_if_bit, &new_y_if_not_bit);
@ -371,4 +336,32 @@ mod tests {
verify(proof, &data.verifier_only, &data.common)
}
#[test]
fn test_curve_random() -> Result<()> {
type F = GoldilocksField;
const D: usize = 4;
let config = CircuitConfig {
num_routed_wires: 33,
..CircuitConfig::standard_recursion_config()
};
let pw = PartialWitness::new();
let mut builder = CircuitBuilder::<F, D>::new(config);
let rando =
(CurveScalar(Secp256K1Scalar::rand()) * Secp256K1::GENERATOR_PROJECTIVE).to_affine();
let randot = builder.constant_affine_point(rando);
let two_target = builder.constant_nonnative(Secp256K1Scalar::TWO);
let randot_doubled = builder.curve_double(&randot);
let randot_times_two = builder.curve_scalar_mul(&randot, &two_target);
builder.connect_affine_point(&randot_doubled, &randot_times_two);
let data = builder.build();
let proof = data.prove(pw).unwrap();
verify(proof, &data.verifier_only, &data.common)
}
}