This commit is contained in:
Nicholas Ward 2021-11-10 09:53:27 -08:00
parent ebcfde1d81
commit 912204d685
3 changed files with 29 additions and 19 deletions

View File

@ -6,7 +6,7 @@ use crate::gates::arithmetic_u32::{U32ArithmeticGate, NUM_U32_ARITHMETIC_OPS};
use crate::iop::target::Target;
use crate::plonk::circuit_builder::CircuitBuilder;
pub struct U32Target(Target);
pub struct U32Target(pub Target);
impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
pub fn add_virtual_u32_target(&self) -> U32Target {

View File

@ -13,19 +13,23 @@ use crate::iop::target::Target;
use crate::iop::witness::{PartitionWitness, Witness};
use crate::plonk::circuit_builder::CircuitBuilder;
use crate::util::bimap::bimap_from_lists;
pub struct NonNativeTarget {
/// The modulus of the field F' being represented.
modulus: BigUint,
pub struct ForeignFieldTarget<FF: Field> {
/// These F elements are assumed to contain 32-bit values.
limbs: Vec<U32Target>,
_phantom: PhantomData<FF>,
}
impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
pub fn add_nonnative(&mut self, a: NonNativeTarget, b: NonNativeTarget) -> NonNativeTarget {
let modulus = a.modulus;
pub fn order_u32_limbs<FF: Field>(&self) -> Vec<U32Target> {
let modulus = FF::order();
let limbs = modulus.to_u32_digits();
limbs.iter().map(|&limb| self.constant_u32(F::from_canonical_u32(limb))).collect()
}
// Add two `ForeignFieldTarget`s, which we assume are both normalized.
pub fn add_nonnative<FF: Field>(&mut self, a: ForeignFieldTarget<FF>, b: ForeignFieldTarget<FF>) -> ForeignFieldTarget<FF> {
let num_limbs = a.limbs.len();
debug_assert!(b.modulus == modulus);
debug_assert!(b.limbs.len() == num_limbs);
let mut combined_limbs = self.add_virtual_u32_targets(num_limbs + 1);
@ -36,21 +40,21 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
}
combined_limbs[num_limbs] = carry;
let reduced_limbs = self.reduce_add_result(combined_limbs, modulus);
NonNativeTarget {
modulus,
let reduced_limbs = self.reduce_add_result::<FF>(combined_limbs);
ForeignFieldTarget {
limbs: reduced_limbs,
_phantom: PhantomData,
}
}
pub fn reduce_add_result(&mut self, limbs: Vec<U32Target>, modulus: BigUint) -> Vec<U32Target> {
pub fn reduce_add_result<FF: Field>(&mut self, limbs: Vec<U32Target>) -> Vec<U32Target> {
let modulus = FF::order();
todo!()
}
pub fn mul_nonnative(&mut self, a: NonNativeTarget, b: NonNativeTarget) -> NonNativeTarget {
let modulus = a.modulus;
pub fn mul_nonnative<FF: Field>(&mut self, a: ForeignFieldTarget<FF>, b: ForeignFieldTarget<FF>) -> ForeignFieldTarget<FF> {
let num_limbs = a.limbs.len();
debug_assert!(b.modulus == modulus);
debug_assert!(b.limbs.len() == num_limbs);
let mut combined_limbs = self.add_virtual_targets(2 * num_limbs - 1);
@ -61,15 +65,15 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
}
}
let reduced_limbs = self.reduce_mul_result(combined_limbs, modulus);
let reduced_limbs = self.reduce_mul_result::<FF>(combined_limbs);
NonNativeTarget {
modulus,
ForeignFieldTarget {
limbs: reduced_limbs,
_phantom: PhantomData,
}
}
pub fn reduce_mul_result(&mut self, limbs: Vec<U32Target>, modulus: BigUint) -> Vec<U32Target> {
pub fn reduce_mul_result<FF: Field>(&mut self, limbs: Vec<U32Target>) -> Vec<U32Target> {
todo!()
}
}

View File

@ -13,6 +13,7 @@ use crate::field::field_types::{Field, RichField};
use crate::fri::commitment::PolynomialBatchCommitment;
use crate::fri::{FriConfig, FriParams};
use crate::gadgets::arithmetic_extension::ArithmeticOperation;
use crate::gadgets::arithmetic_u32::U32Target;
use crate::gates::arithmetic::ArithmeticExtensionGate;
use crate::gates::constant::ConstantGate;
use crate::gates::gate::{Gate, GateInstance, GateRef, PrefixedGate};
@ -349,6 +350,11 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
}
}
/// Returns a U32Target for the value `c`, which is assumed to be at most 32 bits.
pub fn constant_u32(&mut self, c: F) -> U32Target {
U32Target(self.constant(c))
}
/// If the given target is a constant (i.e. it was created by the `constant(F)` method), returns
/// its constant value. Otherwise, returns `None`.
pub fn target_as_constant(&self, target: Target) -> Option<F> {