mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-07-31 19:53:17 +00:00
test for split nonnative, and fixes
This commit is contained in:
parent
53a2a92258
commit
67b7193e82
@ -230,7 +230,7 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
|
||||
let windows = self.split_nonnative_to_4_bit_limbs(n);
|
||||
let m = C::ScalarField::BITS / WINDOW_SIZE;
|
||||
for i in m..0 {
|
||||
for i in (0..m).rev() {
|
||||
result = self.curve_double(&result);
|
||||
let window = windows[i];
|
||||
|
||||
@ -411,6 +411,38 @@ mod tests {
|
||||
verify(proof, &data.verifier_only, &data.common)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_curve_mul_windowed() -> Result<()> {
|
||||
const D: usize = 2;
|
||||
type C = PoseidonGoldilocksConfig;
|
||||
type F = <C as GenericConfig<D>>::F;
|
||||
|
||||
let config = CircuitConfig::standard_ecc_config();
|
||||
|
||||
let pw = PartialWitness::new();
|
||||
let mut builder = CircuitBuilder::<F, D>::new(config);
|
||||
|
||||
let g = Secp256K1::GENERATOR_AFFINE;
|
||||
let five = Secp256K1Scalar::from_canonical_usize(5);
|
||||
let neg_five = five.neg();
|
||||
let neg_five_scalar = CurveScalar::<Secp256K1>(neg_five);
|
||||
let neg_five_g = (neg_five_scalar * g.to_projective()).to_affine();
|
||||
let neg_five_g_expected = builder.constant_affine_point(neg_five_g);
|
||||
builder.curve_assert_valid(&neg_five_g_expected);
|
||||
|
||||
let g_target = builder.constant_affine_point(g);
|
||||
let neg_five_target = builder.constant_nonnative(neg_five);
|
||||
let neg_five_g_actual = builder.curve_scalar_mul_windowed(&g_target, &neg_five_target);
|
||||
/*builder.curve_assert_valid(&neg_five_g_actual);
|
||||
|
||||
builder.connect_affine_point(&neg_five_g_expected, &neg_five_g_actual);*/
|
||||
|
||||
let data = builder.build::<C>();
|
||||
let proof = data.prove(pw).unwrap();
|
||||
|
||||
verify(proof, &data.verifier_only, &data.common)
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_curve_random() -> Result<()> {
|
||||
|
||||
@ -1,8 +1,11 @@
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use itertools::Itertools;
|
||||
use plonky2_field::extension_field::Extendable;
|
||||
use plonky2_field::field_types::Field;
|
||||
|
||||
use crate::gadgets::arithmetic_u32::U32Target;
|
||||
use crate::gadgets::biguint::BigUintTarget;
|
||||
use crate::gadgets::nonnative::NonNativeTarget;
|
||||
use crate::hash::hash_types::RichField;
|
||||
use crate::iop::target::Target;
|
||||
@ -10,7 +13,7 @@ use crate::plonk::circuit_builder::CircuitBuilder;
|
||||
|
||||
impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
pub fn split_u32_to_4_bit_limbs(&mut self, val: U32Target) -> Vec<Target> {
|
||||
let two_bit_limbs = self.split_le_base::<2>(val.0, 16);
|
||||
let two_bit_limbs = self.split_le_base::<4>(val.0, 16);
|
||||
let four = self.constant(F::from_canonical_usize(4));
|
||||
let combined_limbs = two_bit_limbs
|
||||
.iter()
|
||||
@ -31,4 +34,64 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
.flat_map(|&l| self.split_u32_to_4_bit_limbs(l))
|
||||
.collect()
|
||||
}
|
||||
|
||||
// Note: assumes its inputs are 4-bit limbs, and does not range-check.
|
||||
pub fn recombine_nonnative_4_bit_limbs<FF: Field>(
|
||||
&mut self,
|
||||
limbs: Vec<Target>,
|
||||
) -> NonNativeTarget<FF> {
|
||||
let base = self.constant_u32(1 << 4);
|
||||
let u32_limbs = limbs
|
||||
.chunks(8)
|
||||
.map(|chunk| {
|
||||
let mut combined_chunk = self.zero_u32();
|
||||
for i in (0..8).rev() {
|
||||
let (low, _high) = self.mul_add_u32(combined_chunk, base, U32Target(chunk[i]));
|
||||
combined_chunk = low;
|
||||
}
|
||||
combined_chunk
|
||||
})
|
||||
.collect();
|
||||
|
||||
NonNativeTarget {
|
||||
value: BigUintTarget { limbs: u32_limbs },
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use anyhow::Result;
|
||||
use plonky2_field::field_types::Field;
|
||||
use plonky2_field::secp256k1_scalar::Secp256K1Scalar;
|
||||
|
||||
use crate::gadgets::nonnative::NonNativeTarget;
|
||||
use crate::iop::witness::PartialWitness;
|
||||
use crate::plonk::circuit_builder::CircuitBuilder;
|
||||
use crate::plonk::circuit_data::CircuitConfig;
|
||||
use crate::plonk::config::{GenericConfig, PoseidonGoldilocksConfig};
|
||||
use crate::plonk::verifier::verify;
|
||||
|
||||
#[test]
|
||||
fn test_split_nonnative() -> Result<()> {
|
||||
type FF = Secp256K1Scalar;
|
||||
const D: usize = 2;
|
||||
type C = PoseidonGoldilocksConfig;
|
||||
type F = <C as GenericConfig<D>>::F;
|
||||
|
||||
let config = CircuitConfig::standard_ecc_config();
|
||||
let pw = PartialWitness::new();
|
||||
let mut builder = CircuitBuilder::<F, D>::new(config);
|
||||
|
||||
let x = FF::rand();
|
||||
let x_target = builder.constant_nonnative(x);
|
||||
let split = builder.split_nonnative_to_4_bit_limbs(&x_target);
|
||||
let combined: NonNativeTarget<Secp256K1Scalar> = builder.recombine_nonnative_4_bit_limbs(split);
|
||||
builder.connect_nonnative(&x_target, &combined);
|
||||
|
||||
let data = builder.build::<C>();
|
||||
let proof = data.prove(pw).unwrap();
|
||||
verify(proof, &data.verifier_only, &data.common)
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user