From 1db0d91ed1a9b6a7bf85ec7328db0b4c270f94d2 Mon Sep 17 00:00:00 2001 From: Manish Kumar Date: Fri, 31 May 2024 00:34:13 +0530 Subject: [PATCH] more circuits for u32, u64 arithmetics --- hash/plonky2/src/arithmetic/u32_arithmetic.rs | 23 +++++++++---- hash/plonky2/src/arithmetic/u64_arithmetic.rs | 32 +++++++++++++++---- hash/plonky2/src/bench/keccak.rs | 22 ++++--------- 3 files changed, 49 insertions(+), 28 deletions(-) diff --git a/hash/plonky2/src/arithmetic/u32_arithmetic.rs b/hash/plonky2/src/arithmetic/u32_arithmetic.rs index 08ba34b..f6c4676 100644 --- a/hash/plonky2/src/arithmetic/u32_arithmetic.rs +++ b/hash/plonky2/src/arithmetic/u32_arithmetic.rs @@ -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, const D: usize> { +pub trait CircuitBuilderU32M, 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; fn to_u32(&mut self, a: Vec) -> U32Target; + // fn constant_u32(&mut self, c: u32) -> U32Target; } -impl, const D: usize> CircuitBuilderU32 +impl, const D: usize> CircuitBuilderU32M for CircuitBuilder{ + // fn constant_u32(&mut self, c: u32) -> U32Target { + // U32Target(self.constant(F::from_canonical_u32(c))) + // } + fn from_u32(&mut self, a: U32Target) -> Vec { let mut res = Vec::new(); @@ -77,4 +82,10 @@ impl, const D: usize> CircuitBuilderU32 } 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 + } } \ No newline at end of file diff --git a/hash/plonky2/src/arithmetic/u64_arithmetic.rs b/hash/plonky2/src/arithmetic/u64_arithmetic.rs index abd711d..9d3f0b7 100644 --- a/hash/plonky2/src/arithmetic/u64_arithmetic.rs +++ b/hash/plonky2/src/arithmetic/u64_arithmetic.rs @@ -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, 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, const D: usize> CircuitBuilderU64 for CircuitBuilder{ - 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, const D: usize> CircuitBuilderU64 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, const D: usize> CircuitBuilderU64 } 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]) + } } \ No newline at end of file diff --git a/hash/plonky2/src/bench/keccak.rs b/hash/plonky2/src/bench/keccak.rs index e64b0b9..5822815 100644 --- a/hash/plonky2/src/bench/keccak.rs +++ b/hash/plonky2/src/bench/keccak.rs @@ -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 {