more circuits for u32, u64 arithmetics

This commit is contained in:
Manish Kumar 2024-05-31 00:34:13 +05:30
parent 7cc901e521
commit 1db0d91ed1
3 changed files with 49 additions and 28 deletions

View File

@ -1,25 +1,30 @@
use plonky2::iop::target::{BoolTarget, Target};
use plonky2::iop::target::BoolTarget;
use plonky2::hash::hash_types::RichField;
use plonky2::field::extension::Extendable;
use plonky2::plonk::circuit_builder::CircuitBuilder;
use plonky2_u32::gadgets::arithmetic_u32::U32Target;
use super::binary_arithmetic::CircuitBuilderBoolTarget;
#[derive(Clone, Copy, Debug)]
pub struct U32Target(pub Target);
use plonky2_u32::gadgets::arithmetic_u32::CircuitBuilderU32;
pub trait CircuitBuilderU32<F: RichField + Extendable<D>, const D: usize> {
pub trait CircuitBuilderU32M<F: RichField + Extendable<D>, const D: usize> {
fn or_u32(&mut self, a: U32Target, b: U32Target) -> U32Target;
fn and_u32(&mut self, a: U32Target, b: U32Target) -> U32Target;
fn xor_u32(&mut self, a: U32Target, b: U32Target) -> U32Target;
fn rotate_left_u32(&mut self, a: U32Target, n: u8) -> U32Target;
fn from_u32(&mut self, a: U32Target) -> Vec<BoolTarget>;
fn to_u32(&mut self, a: Vec<BoolTarget>) -> U32Target;
// fn constant_u32(&mut self, c: u32) -> U32Target;
}
impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilderU32<F, D>
impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilderU32M<F, D>
for CircuitBuilder<F, D>{
// fn constant_u32(&mut self, c: u32) -> U32Target {
// U32Target(self.constant(F::from_canonical_u32(c)))
// }
fn from_u32(&mut self, a: U32Target) -> Vec<BoolTarget> {
let mut res = Vec::new();
@ -77,4 +82,10 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilderU32<F, D>
}
self.to_u32(res)
}
fn rotate_left_u32(&mut self, a: U32Target, n: u8) -> U32Target {
let two_power_n = self.constant_u32(0x1 << n);
let (lo, hi) = self.mul_u32(a, two_power_n);
self.add_u32(lo, hi).0
}
}

View File

@ -1,19 +1,24 @@
use plonky2::hash::hash_types::RichField;
use plonky2::field::extension::Extendable;
use plonky2::plonk::circuit_builder::CircuitBuilder;
use super::u32_arithmetic::CircuitBuilderU32;
use super::u32_arithmetic::U32Target;
use plonky2_u32::gadgets::arithmetic_u32::U32Target;
use super::u32_arithmetic::CircuitBuilderU32M;
use plonky2_u32::gadgets::arithmetic_u32::CircuitBuilderU32;
#[derive(Clone, Copy, Debug)]
pub struct U64Target(pub [U32Target;2]);
pub trait CircuitBuilderU64<F: RichField + Extendable<D>, const D: usize> {
fn and(&mut self, a: U64Target, b: U64Target) -> U64Target;
fn xor(&mut self, a: U64Target, b: U64Target) -> U64Target;
fn and_u64(&mut self, a: U64Target, b: U64Target) -> U64Target;
fn xor_u64(&mut self, a: U64Target, b: U64Target) -> U64Target;
fn rotate_left_u64(&mut self, a: U64Target, n: u8) -> U64Target;
fn zero_u64(&mut self) -> U64Target;
}
impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilderU64<F, D>
for CircuitBuilder<F, D>{
fn xor(&mut self, a: U64Target, b: U64Target) -> U64Target {
fn xor_u64(&mut self, a: U64Target, b: U64Target) -> U64Target {
let mut result = Vec::new();
for i in 0..2 {
result.push(self.xor_u32(a.0[i], b.0[i]));
@ -21,7 +26,7 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilderU64<F, D>
U64Target([result[0], result[1]])
}
fn and(&mut self, a: U64Target, b: U64Target) -> U64Target {
fn and_u64(&mut self, a: U64Target, b: U64Target) -> U64Target {
let mut result = Vec::new();
for i in 0..2 {
@ -29,4 +34,19 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilderU64<F, D>
}
U64Target([result[0], result[1]])
}
fn rotate_left_u64(&mut self, a: U64Target, n: u8) -> U64Target {
let (lo, hi) = if n < 32 { (a.0[0], a.0[1]) } else { (a.0[1], a.0[0]) };
let two_power_x = self.constant_u32(0x1 << (n % 32));
let (lo0, hi0) = self.mul_u32(lo, two_power_x);
let (lo1, hi1) = self.mul_add_u32(hi, two_power_x, hi0);
U64Target([self.add_u32(lo0, hi1).0, lo1])
}
fn zero_u64(&mut self) -> U64Target {
let zero_u32 = self.zero_u32();
U64Target([zero_u32,zero_u32])
}
}

View File

@ -1,27 +1,17 @@
// use anyhow::Result;
use plonky2::field::types::Field;
// use plonky2::gates::poseidon::PoseidonGate;
// use plonky2::hash::hash_types::{HashOutTarget, RichField};
use plonky2::field::goldilocks_field::GoldilocksField;
use plonky2::hash::keccak::{KeccakHash, KeccakPermutation, /*KeccakPermutation */};
// use plonky2::hash::keccak;
use plonky2::hash::poseidon::PoseidonHash;
// use plonky2::iop::witness::{PartialWitness, WitnessWrite};
use plonky2::hash::keccak::KeccakHash;
use plonky2::plonk::circuit_builder::CircuitBuilder;
use plonky2::plonk::circuit_data::CircuitConfig;
use plonky2::plonk::config::{/*AlgebraicHasher,*/ GenericConfig,/* PoseidonGoldilocksConfig, */ KeccakGoldilocksConfig};
use plonky2::plonk::config::{GenericConfig, KeccakGoldilocksConfig};
use rand::Rng;
// use plonky2::iop::target::Target;
// use plonky2::iop::target::BoolTarget;
use plonky2::field::extension::Extendable;
// use std::marker::PhantomData;
use plonky2::plonk::config::Hasher;
use plonky2_u32::gadgets::arithmetic_u32::{CircuitBuilderU32, U32Target};
use plonky2::field::types::PrimeField64;
use plonky2::iop::witness::Witness;
use plonky2::hash::hash_types::RichField;
use plonky2::iop::target::BoolTarget;
use crate::arithmetic::u64_arithmetic::U64Target;
use crate::arithmetic::u64_arithmetic::CircuitBuilderU64;
fn generate_data(size: usize) -> Vec<GoldilocksField> {