mirror of
https://github.com/logos-storage/zk-benchmarks.git
synced 2026-01-05 23:33:07 +00:00
circuits for different arithemtic operations of BoolTarget, u32 and u64(needed for different hashes)
This commit is contained in:
parent
53dcdaa370
commit
7cc901e521
30
hash/plonky2/src/arithmetic/binary_arithmetic.rs
Normal file
30
hash/plonky2/src/arithmetic/binary_arithmetic.rs
Normal file
@ -0,0 +1,30 @@
|
||||
use plonky2::hash::hash_types::RichField;
|
||||
use plonky2::field::extension::Extendable;
|
||||
use plonky2::plonk::circuit_builder::CircuitBuilder;
|
||||
use plonky2::iop::target::BoolTarget;
|
||||
|
||||
pub trait CircuitBuilderBoolTarget<F: RichField + Extendable<D>, const D: usize> {
|
||||
fn and(&mut self, a: BoolTarget, b: BoolTarget) -> BoolTarget;
|
||||
fn or(&mut self, a: BoolTarget, b: BoolTarget) -> BoolTarget;
|
||||
fn xor(&mut self, a: BoolTarget, b: BoolTarget) -> BoolTarget;
|
||||
|
||||
}
|
||||
|
||||
impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilderBoolTarget<F, D>
|
||||
for CircuitBuilder<F, D>{
|
||||
fn xor(&mut self, a: BoolTarget, b: BoolTarget) -> BoolTarget {
|
||||
|
||||
// a ^ b := (a - b)^2
|
||||
let s = self.sub(a.target, b.target);
|
||||
BoolTarget::new_unsafe(self.mul(s, s))
|
||||
|
||||
}
|
||||
|
||||
fn and(&mut self, a: BoolTarget, b: BoolTarget) -> BoolTarget {
|
||||
self.and(a, b)
|
||||
}
|
||||
|
||||
fn or(&mut self, a: BoolTarget, b: BoolTarget) -> BoolTarget {
|
||||
self.or(a, b)
|
||||
}
|
||||
}
|
||||
80
hash/plonky2/src/arithmetic/u32_arithmetic.rs
Normal file
80
hash/plonky2/src/arithmetic/u32_arithmetic.rs
Normal file
@ -0,0 +1,80 @@
|
||||
use plonky2::iop::target::{BoolTarget, Target};
|
||||
use plonky2::hash::hash_types::RichField;
|
||||
use plonky2::field::extension::Extendable;
|
||||
use plonky2::plonk::circuit_builder::CircuitBuilder;
|
||||
|
||||
use super::binary_arithmetic::CircuitBuilderBoolTarget;
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct U32Target(pub Target);
|
||||
|
||||
pub trait CircuitBuilderU32<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 from_u32(&mut self, a: U32Target) -> Vec<BoolTarget>;
|
||||
fn to_u32(&mut self, a: Vec<BoolTarget>) -> U32Target;
|
||||
|
||||
}
|
||||
|
||||
impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilderU32<F, D>
|
||||
for CircuitBuilder<F, D>{
|
||||
|
||||
fn from_u32(&mut self, a: U32Target) -> Vec<BoolTarget> {
|
||||
|
||||
let mut res = Vec::new();
|
||||
let bit_targets = self.split_le_base::<2>(a.0, 32);
|
||||
|
||||
for i in (0..32).rev() {
|
||||
res.push(BoolTarget::new_unsafe(bit_targets[i]));
|
||||
}
|
||||
res
|
||||
}
|
||||
|
||||
fn to_u32(&mut self, a: Vec<BoolTarget>) -> U32Target {
|
||||
let bit_len = a.len();
|
||||
assert_eq!(bit_len, 32);
|
||||
U32Target(self.le_sum(a[0..32].iter().rev()))
|
||||
}
|
||||
|
||||
|
||||
fn or_u32(&mut self, a: U32Target, b: U32Target) -> U32Target {
|
||||
let binary_target_a = self.from_u32(a);
|
||||
let binary_target_b = self.from_u32(b);
|
||||
|
||||
let mut res = Vec::<BoolTarget>::new();
|
||||
for i in 0..32 {
|
||||
|
||||
let r = self.or(binary_target_a[i], binary_target_b[i]);
|
||||
res.push(r);
|
||||
}
|
||||
self.to_u32(res)
|
||||
}
|
||||
|
||||
fn and_u32(&mut self, a: U32Target, b: U32Target) -> U32Target {
|
||||
let binary_target_a = self.from_u32(a);
|
||||
let binary_target_b = self.from_u32(b);
|
||||
|
||||
let mut res = Vec::<BoolTarget>::new();
|
||||
for i in 0..32 {
|
||||
|
||||
let r = self.and(binary_target_a[i], binary_target_b[i]);
|
||||
res.push(r);
|
||||
}
|
||||
self.to_u32(res)
|
||||
|
||||
}
|
||||
|
||||
fn xor_u32(&mut self, a: U32Target, b: U32Target) -> U32Target {
|
||||
let binary_target_a = self.from_u32(a);
|
||||
let binary_target_b = self.from_u32(b);
|
||||
|
||||
let mut res = Vec::<BoolTarget>::new();
|
||||
for i in 0..32 {
|
||||
|
||||
let r = self.xor(binary_target_a[i], binary_target_b[i]);
|
||||
res.push(r);
|
||||
}
|
||||
self.to_u32(res)
|
||||
}
|
||||
}
|
||||
32
hash/plonky2/src/arithmetic/u64_arithmetic.rs
Normal file
32
hash/plonky2/src/arithmetic/u64_arithmetic.rs
Normal file
@ -0,0 +1,32 @@
|
||||
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;
|
||||
#[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;
|
||||
}
|
||||
|
||||
impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilderU64<F, D>
|
||||
for CircuitBuilder<F, D>{
|
||||
fn xor(&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]));
|
||||
}
|
||||
U64Target([result[0], result[1]])
|
||||
}
|
||||
|
||||
fn and(&mut self, a: U64Target, b: U64Target) -> U64Target {
|
||||
let mut result = Vec::new();
|
||||
|
||||
for i in 0..2 {
|
||||
result.push(self.and_u32(a.0[i], b.0[i]));
|
||||
}
|
||||
U64Target([result[0], result[1]])
|
||||
}
|
||||
}
|
||||
@ -56,87 +56,87 @@ pub fn keccak_bench(_size: usize) {
|
||||
|
||||
//----------------------------------------------------------
|
||||
|
||||
const KECCAK_WIDTH: usize = 1600;
|
||||
const KECCAK_RATE: usize = 1088;
|
||||
const KECCAK_CAPACITY: usize = KECCAK_WIDTH - KECCAK_RATE;
|
||||
const KECCAK_LANES: usize = KECCAK_WIDTH / 64;
|
||||
const KECCAK_ROUNDS: usize = 24;
|
||||
// const KECCAK_WIDTH: usize = 1600;
|
||||
// const KECCAK_RATE: usize = 1088;
|
||||
// const KECCAK_CAPACITY: usize = KECCAK_WIDTH - KECCAK_RATE;
|
||||
// const KECCAK_LANES: usize = KECCAK_WIDTH / 64;
|
||||
// const KECCAK_ROUNDS: usize = 24;
|
||||
|
||||
const ROUND_CONSTANTS: [u64; KECCAK_ROUNDS] = [
|
||||
0x0000000000000001, 0x0000000000008082, 0x800000000000808A, 0x8000000080008000,
|
||||
0x000000000000808B, 0x0000000080000001, 0x8000000080008081, 0x8000000000008009,
|
||||
0x000000000000008A, 0x0000000000000088, 0x0000000080008009, 0x000000008000000A,
|
||||
0x000000008000808B, 0x800000000000008B, 0x8000000000008089, 0x8000000000008003,
|
||||
0x8000000000008002, 0x8000000000000080, 0x000000000000800A, 0x800000008000000A,
|
||||
0x8000000080008081, 0x8000000000008080, 0x0000000080000001, 0x8000000080008008,
|
||||
];
|
||||
// const ROUND_CONSTANTS: [u64; KECCAK_ROUNDS] = [
|
||||
// 0x0000000000000001, 0x0000000000008082, 0x800000000000808A, 0x8000000080008000,
|
||||
// 0x000000000000808B, 0x0000000080000001, 0x8000000080008081, 0x8000000000008009,
|
||||
// 0x000000000000008A, 0x0000000000000088, 0x0000000080008009, 0x000000008000000A,
|
||||
// 0x000000008000808B, 0x800000000000008B, 0x8000000000008089, 0x8000000000008003,
|
||||
// 0x8000000000008002, 0x8000000000000080, 0x000000000000800A, 0x800000008000000A,
|
||||
// 0x8000000080008081, 0x8000000000008080, 0x0000000080000001, 0x8000000080008008,
|
||||
// ];
|
||||
|
||||
fn initialize_state() -> [u64; KECCAK_LANES] {
|
||||
[0; KECCAK_LANES]
|
||||
}
|
||||
pub struct U64Target([U32Target;2]);
|
||||
// fn initialize_state() -> [u64; KECCAK_LANES] {
|
||||
// [0; KECCAK_LANES]
|
||||
// }
|
||||
// pub struct U64Target([U32Target;2]);
|
||||
|
||||
// copied from sha256 circuit
|
||||
// TODO: move to some common place
|
||||
pub fn u32_to_bits_target<F: RichField + Extendable<D>, const D: usize, const B: usize>(
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
a: &U32Target,
|
||||
) -> Vec<BoolTarget> {
|
||||
let mut res = Vec::new();
|
||||
let bit_targets = builder.split_le_base::<B>(a.0, 32);
|
||||
for i in (0..32).rev() {
|
||||
res.push(BoolTarget::new_unsafe(bit_targets[i]));
|
||||
}
|
||||
res
|
||||
}
|
||||
// // copied from sha256 circuit
|
||||
// // TODO: move to some common place
|
||||
// pub fn u32_to_bits_target<F: RichField + Extendable<D>, const D: usize, const B: usize>(
|
||||
// builder: &mut CircuitBuilder<F, D>,
|
||||
// a: &U32Target,
|
||||
// ) -> Vec<BoolTarget> {
|
||||
// let mut res = Vec::new();
|
||||
// let bit_targets = builder.split_le_base::<B>(a.0, 32);
|
||||
// for i in (0..32).rev() {
|
||||
// res.push(BoolTarget::new_unsafe(bit_targets[i]));
|
||||
// }
|
||||
// res
|
||||
// }
|
||||
|
||||
// copied from sha256 circuit
|
||||
// TODO: move to some common place
|
||||
pub fn bits_to_u32_target<F: RichField + Extendable<D>, const D: usize>(
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
bits_target: Vec<BoolTarget>,
|
||||
) -> U32Target {
|
||||
let bit_len = bits_target.len();
|
||||
assert_eq!(bit_len, 32);
|
||||
U32Target(builder.le_sum(bits_target[0..32].iter().rev()))
|
||||
}
|
||||
// // copied from sha256 circuit
|
||||
// // TODO: move to some common place
|
||||
// pub fn bits_to_u32_target<F: RichField + Extendable<D>, const D: usize>(
|
||||
// builder: &mut CircuitBuilder<F, D>,
|
||||
// bits_target: Vec<BoolTarget>,
|
||||
// ) -> U32Target {
|
||||
// let bit_len = bits_target.len();
|
||||
// assert_eq!(bit_len, 32);
|
||||
// U32Target(builder.le_sum(bits_target[0..32].iter().rev()))
|
||||
// }
|
||||
|
||||
//TODO: not tested
|
||||
pub fn xor_u64<F: RichField + Extendable<D>, const D: usize>(
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
x: U64Target,
|
||||
y: U64Target,
|
||||
) -> U64Target {
|
||||
let xor_x0_y0 = xor_u32(builder, x.0[0], y.0[0]);
|
||||
let xor_x1_y1 = xor_u32(builder, x.0[1], y.0[1]);
|
||||
// //TODO: not tested
|
||||
// pub fn xor_u64<F: RichField + Extendable<D>, const D: usize>(
|
||||
// builder: &mut CircuitBuilder<F, D>,
|
||||
// x: U64Target,
|
||||
// y: U64Target,
|
||||
// ) -> U64Target {
|
||||
// let xor_x0_y0 = xor_u32(builder, x.0[0], y.0[0]);
|
||||
// let xor_x1_y1 = xor_u32(builder, x.0[1], y.0[1]);
|
||||
|
||||
U64Target([xor_x0_y0,xor_x1_y1])
|
||||
// U64Target([xor_x0_y0,xor_x1_y1])
|
||||
|
||||
}
|
||||
// }
|
||||
|
||||
pub fn xor_u32<F: RichField + Extendable<D>, const D: usize>(
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
x: U32Target,
|
||||
y: U32Target,
|
||||
) -> U32Target {
|
||||
// pub fn xor_u32<F: RichField + Extendable<D>, const D: usize>(
|
||||
// builder: &mut CircuitBuilder<F, D>,
|
||||
// x: U32Target,
|
||||
// y: U32Target,
|
||||
// ) -> U32Target {
|
||||
|
||||
let bits_target_x = u32_to_bits_target::<F, D, 2>(builder, &x);
|
||||
let bits_target_y = u32_to_bits_target::<F, D, 2>(builder, &y);
|
||||
// let bits_target_x = u32_to_bits_target::<F, D, 2>(builder, &x);
|
||||
// let bits_target_y = u32_to_bits_target::<F, D, 2>(builder, &y);
|
||||
|
||||
assert_eq!(bits_target_x.len(), bits_target_y.len());
|
||||
// assert_eq!(bits_target_x.len(), bits_target_y.len());
|
||||
|
||||
let mut xor_result_final = Vec::<BoolTarget>::new();
|
||||
for i in 0..bits_target_x.len() {
|
||||
let a_plus_b = builder.add(bits_target_x.get(i).unwrap().target, bits_target_y.get(i).unwrap().target);
|
||||
let ab = builder.mul(bits_target_x.get(i).unwrap().target, bits_target_y.get(i).unwrap().target);
|
||||
let two_ab = builder.mul_const(F::from_canonical_u64(2), ab);
|
||||
let xor_result = builder.sub(a_plus_b, two_ab);
|
||||
xor_result_final.push(BoolTarget::new_unsafe(xor_result));
|
||||
}
|
||||
let result = bits_to_u32_target(builder, xor_result_final);
|
||||
result
|
||||
// let mut xor_result_final = Vec::<BoolTarget>::new();
|
||||
// for i in 0..bits_target_x.len() {
|
||||
// let a_plus_b = builder.add(bits_target_x.get(i).unwrap().target, bits_target_y.get(i).unwrap().target);
|
||||
// let ab = builder.mul(bits_target_x.get(i).unwrap().target, bits_target_y.get(i).unwrap().target);
|
||||
// let two_ab = builder.mul_const(F::from_canonical_u64(2), ab);
|
||||
// let xor_result = builder.sub(a_plus_b, two_ab);
|
||||
// xor_result_final.push(BoolTarget::new_unsafe(xor_result));
|
||||
// }
|
||||
// let result = bits_to_u32_target(builder, xor_result_final);
|
||||
// result
|
||||
|
||||
}
|
||||
// }
|
||||
|
||||
// Theta
|
||||
// pub fn theta<F: RichField + Extendable<D>, const D: usize>(
|
||||
|
||||
@ -15,6 +15,12 @@ mod bench{
|
||||
}
|
||||
}
|
||||
|
||||
mod arithmetic {
|
||||
pub mod binary_arithmetic;
|
||||
pub mod u32_arithmetic;
|
||||
pub mod u64_arithmetic;
|
||||
}
|
||||
|
||||
use bench::poseidon::poseidon_bench;
|
||||
use bench::keccak::keccak_bench;
|
||||
use bench::sha256::sha::sha256_bench;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user