mirror of
https://github.com/logos-storage/zk-benchmarks.git
synced 2026-01-02 22:03:10 +00:00
restructure of funtions
This commit is contained in:
parent
d2cf4f7c81
commit
5e7d6fd8c8
@ -6,8 +6,8 @@ use plonky2::iop::target::BoolTarget;
|
||||
//TODO: remove the dead codes later
|
||||
#[allow(dead_code)]
|
||||
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 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;
|
||||
|
||||
}
|
||||
@ -22,11 +22,11 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilderBoolTarget<F, D
|
||||
|
||||
}
|
||||
|
||||
fn and(&mut self, a: BoolTarget, b: BoolTarget) -> BoolTarget {
|
||||
self.and(a, b)
|
||||
}
|
||||
// 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)
|
||||
}
|
||||
// fn or(&mut self, a: BoolTarget, b: BoolTarget) -> BoolTarget {
|
||||
// self.or(a, b)
|
||||
// }
|
||||
}
|
||||
@ -9,10 +9,10 @@ use plonky2_u32::gadgets::arithmetic_u32::CircuitBuilderU32;
|
||||
//TODO: remove the dead codes later
|
||||
#[allow(dead_code)]
|
||||
pub trait CircuitBuilderU32M<F: RichField + Extendable<D>, const D: usize> {
|
||||
fn or_u32(&mut self, a: U32Target, b: U32Target) -> U32Target;
|
||||
// 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 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;
|
||||
@ -43,18 +43,18 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilderU32M<F, D>
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
// 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 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)
|
||||
}
|
||||
// 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);
|
||||
@ -83,11 +83,11 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilderU32M<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
|
||||
}
|
||||
// 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
|
||||
// }
|
||||
|
||||
// not := 0xFFFFFFFF - x
|
||||
fn not_u32(&mut self, a: U32Target) -> U32Target {
|
||||
|
||||
@ -1,381 +0,0 @@
|
||||
use plonky2::field::types::Field;
|
||||
use plonky2::field::goldilocks_field::GoldilocksField;
|
||||
use plonky2::hash::keccak::KeccakHash;
|
||||
use plonky2::plonk::circuit_builder::CircuitBuilder;
|
||||
use plonky2::plonk::circuit_data::CircuitConfig;
|
||||
use plonky2::plonk::config::{GenericConfig, KeccakGoldilocksConfig};
|
||||
use rand::Rng;
|
||||
use plonky2::field::extension::Extendable;
|
||||
use plonky2::plonk::config::Hasher;
|
||||
use plonky2::hash::hash_types::RichField;
|
||||
use plonky2_u32::gadgets::arithmetic_u32::CircuitBuilderU32;
|
||||
use crate::arithmetic::u64_arithmetic::U64Target;
|
||||
use crate::arithmetic::u64_arithmetic::CircuitBuilderU64;
|
||||
use plonky2::iop::witness::Witness;
|
||||
use plonky2::field::types::PrimeField64;
|
||||
|
||||
fn generate_data(size: usize) -> Vec<GoldilocksField> {
|
||||
|
||||
let mut data: Vec<GoldilocksField> = Vec::new();
|
||||
for _ in 0..(1<<size) {
|
||||
let mut rng = rand::thread_rng();
|
||||
let random_u64: u64 = rng.gen();
|
||||
data.push(GoldilocksField::from_canonical_u64(random_u64));
|
||||
}
|
||||
data
|
||||
|
||||
}
|
||||
|
||||
//TODO: remove the dead codes later
|
||||
#[allow(dead_code)]
|
||||
pub trait WitnessU64<F: PrimeField64>: Witness<F> {
|
||||
fn set_u64_target(&mut self, target: U64Target, value: u64);
|
||||
// fn get_u64_target(&self, target: U64Target) -> (u64, u64);
|
||||
}
|
||||
|
||||
impl<T: Witness<F>, F: PrimeField64> WitnessU64<F> for T {
|
||||
fn set_u64_target(&mut self, target: U64Target, value: u64) {
|
||||
self.set_target(target.0[0].0, F::from_canonical_u32((value & 0xFFFFFFFF) as u32));
|
||||
self.set_target(target.0[1].0, F::from_canonical_u32(((value >> 32) & 0xFFFFFFFF) as u32));
|
||||
}
|
||||
|
||||
// fn get_u64_target(&self, target: U64Target) -> (u64, u64) {
|
||||
// let x_u64 = self.get_target(target.0).to_canonical_u64();
|
||||
// let low = x_u64 as u32;
|
||||
// let high = (x_u64 >> 32) as u32;
|
||||
// (low, high)
|
||||
// }
|
||||
}
|
||||
|
||||
// TODO: Circuit needs to be implemented
|
||||
pub fn keccak_bench(_size: usize) {
|
||||
|
||||
let data = generate_data(2);
|
||||
const D: usize = 2;
|
||||
type C = KeccakGoldilocksConfig;
|
||||
type F = <C as GenericConfig<D>>::F;
|
||||
|
||||
let config = CircuitConfig::standard_recursion_config();
|
||||
let mut builder = CircuitBuilder::<F, D>::new(config);
|
||||
|
||||
let _initial = builder.add_virtual_targets(data.len());
|
||||
|
||||
let hash = KeccakHash::<32>::hash_or_noop(&data);
|
||||
eprintln!("{:?}", hash);
|
||||
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------
|
||||
|
||||
|
||||
// const KECCAK_WIDTH: usize = 1600;
|
||||
const KECCAK_RATE: usize = 1088;
|
||||
// const KECCAK_CsAPACITY: usize = KECCAK_WIDTH - KECCAK_RATE;
|
||||
// const KECCAKs_LANES: usize = KECCAK_WIDTH / 64;
|
||||
const KECCAK_ROUNDS: usize = 24;
|
||||
|
||||
//TODO: remove the dead codes later
|
||||
#[allow(dead_code)]
|
||||
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,
|
||||
];
|
||||
|
||||
//TODO: remove the dead codes later
|
||||
#[allow(dead_code)]
|
||||
// Theta
|
||||
pub fn theta<F: RichField + Extendable<D>, const D: usize>(
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
state: &mut [[U64Target; 5]; 5]
|
||||
){
|
||||
let mut c = [builder.zero_u64(); 5];
|
||||
let mut d = [builder.zero_u64(); 5];
|
||||
|
||||
// Compute column parities
|
||||
for x in 0..5 {
|
||||
|
||||
let xor_x0_x1 = builder.xor_u64(state[x][0], state[x][1]);
|
||||
let xor_x0_x1_x2 = builder.xor_u64(xor_x0_x1, state[x][2]);
|
||||
let xor_x0_x1_x2_x3 = builder.xor_u64(xor_x0_x1_x2, state[x][3]);
|
||||
c[x] = builder.xor_u64(xor_x0_x1_x2_x3, state[x][4]);
|
||||
|
||||
}
|
||||
|
||||
// Compute rotated parities
|
||||
for x in 0..5 {
|
||||
let c_left = c[(x + 4) % 5];
|
||||
let c_right_rot = builder.rotate_left_u64(c[(x + 1) % 5], 1);
|
||||
d[x] = builder.xor_u64(c_left, c_right_rot);
|
||||
}
|
||||
|
||||
// Modify the state
|
||||
for x in 0..5 {
|
||||
for y in 0..5 {
|
||||
state[x][y] = builder.xor_u64(state[x][y], d[x]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: remove the dead codes later
|
||||
#[allow(dead_code)]
|
||||
//rho
|
||||
fn rho<F: RichField + Extendable<D>, const D: usize>(
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
state: &mut [[U64Target; 5]; 5]
|
||||
){
|
||||
const RHO_OFFSETS: [[usize; 5]; 5] = [
|
||||
[0, 1, 62, 28, 27],
|
||||
[36, 44, 6, 55, 20],
|
||||
[3, 10, 43, 25, 39],
|
||||
[41, 45, 15, 21, 8],
|
||||
[18, 2, 61, 56, 14],
|
||||
];
|
||||
|
||||
for x in 0..5 {
|
||||
for y in 0..5 {
|
||||
let rotation = RHO_OFFSETS[x][y];
|
||||
state[x][y] = builder.rotate_left_u64(state[x][y], rotation as u8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: remove the dead codes later
|
||||
#[allow(dead_code)]
|
||||
//pi
|
||||
fn pi<F: RichField + Extendable<D>, const D: usize>(
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
state: &mut [[U64Target; 5]; 5]
|
||||
){
|
||||
let mut new_state = [[builder.zero_u64(); 5]; 5];
|
||||
for x in 0..5 {
|
||||
for y in 0..5 {
|
||||
new_state[(2 * x + 3 * y) % 5][y] = state[x][y];
|
||||
}
|
||||
}
|
||||
*state = new_state;
|
||||
}
|
||||
|
||||
//TODO: remove the dead codes later
|
||||
#[allow(dead_code)]
|
||||
//iota
|
||||
fn iota<F: RichField + Extendable<D>, const D: usize>(
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
state: &mut [[U64Target; 5]; 5],
|
||||
round: usize
|
||||
){
|
||||
|
||||
let lo = builder.constant_u32((ROUND_CONSTANTS[round] & 0xFFFFFFFF) as u32);
|
||||
let hi = builder.constant_u32(((ROUND_CONSTANTS[round] >> 32)& 0xFFFFFFFF) as u32);
|
||||
state[0][0] = builder.xor_u64(state[0][0], U64Target([lo,hi])) ;
|
||||
}
|
||||
|
||||
//TODO: remove the dead codes later
|
||||
#[allow(dead_code)]
|
||||
fn chi<F: RichField + Extendable<D>, const D: usize>(
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
state: &mut [[U64Target; 5]; 5]
|
||||
){
|
||||
for x in 0..5 {
|
||||
let mut temp = [builder.zero_u64(); 5];
|
||||
for y in 0..5 {
|
||||
temp[y] = state[x][y];
|
||||
}
|
||||
|
||||
|
||||
for y in 0..5 {
|
||||
let t1 = builder.not_u64(temp[(y + 1) % 5]);
|
||||
let t2 = builder.and_u64(t1, temp[(y + 2) % 5]);
|
||||
state[x][y] = builder.xor_u64(state[x][y], t2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: remove the dead codes later
|
||||
#[allow(dead_code)]
|
||||
// permutation
|
||||
fn keccak_f<F: RichField + Extendable<D>, const D: usize>(
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
state: &mut [[U64Target; 5]; 5]
|
||||
) {
|
||||
for i in 0..24 {
|
||||
theta(builder, state);
|
||||
rho(builder, state);
|
||||
pi(builder, state);
|
||||
chi(builder, state);
|
||||
iota(builder, state, i)
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: remove the dead codes later
|
||||
#[allow(dead_code)]
|
||||
fn absorb<F: RichField + Extendable<D>, const D: usize>(
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
state: &mut [[U64Target; 5]; 5],
|
||||
message: &[U64Target],
|
||||
rate: usize
|
||||
) {
|
||||
let chunks = message.chunks(rate / 64);
|
||||
for block in chunks {
|
||||
for (i, &word) in block.iter().enumerate() {
|
||||
let x = i % 5;
|
||||
let y = i / 5;
|
||||
state[x][y] = builder.xor_u64(state[x][y], word);
|
||||
}
|
||||
keccak_f(builder, state); // Assume keccak_f is implemented as a circuit
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: remove the dead codes later
|
||||
#[allow(dead_code)]
|
||||
fn squeeze<F: RichField + Extendable<D>, const D: usize>(
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
state: &mut [[U64Target; 5]; 5],
|
||||
rate: usize,
|
||||
output_length: usize
|
||||
) -> Vec<U64Target> {
|
||||
let mut hash = Vec::new();
|
||||
while hash.len() * 8 < output_length {
|
||||
for y in 0..5 {
|
||||
for x in 0..5 {
|
||||
if (x + 5 * y) * 64 < rate {
|
||||
hash.push(state[x][y]);
|
||||
if hash.len() * 8 >= output_length {
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
keccak_f(builder, state); // Assume keccak_f is implemented as a circuit
|
||||
}
|
||||
hash
|
||||
}
|
||||
|
||||
//TODO: remove the dead codes later
|
||||
#[allow(dead_code)]
|
||||
fn keccak_pad<F: RichField + Extendable<D>, const D: usize>(
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
message: &[U64Target],
|
||||
rate: usize
|
||||
) -> Vec<U64Target> {
|
||||
let mut padded_message = message.to_vec();
|
||||
let rate_words = rate / 64;
|
||||
let mut pad_len = rate_words - (message.len() % rate_words);
|
||||
|
||||
if pad_len == 0 {
|
||||
pad_len = rate_words;
|
||||
}
|
||||
|
||||
if pad_len == 1 {
|
||||
padded_message.push(U64Target([builder.one_u32(), builder.one_u32()]));
|
||||
} else {
|
||||
padded_message.push(U64Target([builder.one_u32(), builder.zero_u32()]));
|
||||
for _ in 1..(pad_len - 1) {
|
||||
padded_message.push(U64Target([builder.zero_u32(), builder.zero_u32()]));
|
||||
}
|
||||
padded_message.push(U64Target([builder.zero_u32(), builder.one_u32()]));
|
||||
}
|
||||
|
||||
padded_message
|
||||
}
|
||||
|
||||
//TODO: remove the dead codes later
|
||||
#[allow(dead_code)]
|
||||
fn keccak256<F: RichField + Extendable<D>, const D: usize>(
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
message: &[U64Target]
|
||||
) -> Vec<U64Target> {
|
||||
let mut state = [[builder.zero_u64(); 5]; 5];
|
||||
let rate = KECCAK_RATE;
|
||||
|
||||
// Padding
|
||||
let padded_message = keccak_pad(builder, message, rate);
|
||||
|
||||
// Absorbing
|
||||
absorb(builder, &mut state, &padded_message, rate);
|
||||
|
||||
// Squeezing
|
||||
let hash = squeeze(builder, &mut state, rate, 256);
|
||||
|
||||
hash
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_keccak256() {
|
||||
// use plonky2_u32::gadgets::arithmetic_u32::U32Target;
|
||||
// use plonky2::iop::target::Target;
|
||||
use plonky2::iop::witness::PartialWitness;
|
||||
use plonky2::plonk::config::PoseidonGoldilocksConfig;
|
||||
// use plonky2_u32::witness::WitnessU32;
|
||||
type F = GoldilocksField; // Choose the field used in your implementation.
|
||||
const D: usize = 2; // This should match the extension degree used.
|
||||
|
||||
// Create circuit builder.
|
||||
let config = CircuitConfig::standard_recursion_config();
|
||||
let mut builder = CircuitBuilder::<F, D>::new(config);
|
||||
|
||||
// Example input message
|
||||
let input = b"hello";
|
||||
|
||||
// Convert input to U64Target format used in your Keccak circuit.
|
||||
let input_u64: Vec<U64Target> = input.chunks(8)
|
||||
.map(|chunk| {
|
||||
let mut chunk_padded = [0u8; 8];
|
||||
chunk_padded[..chunk.len()].copy_from_slice(chunk);
|
||||
let value = u64::from_le_bytes(chunk_padded);
|
||||
U64Target([
|
||||
builder.constant_u32(value as u32),
|
||||
builder.constant_u32((value >> 32) as u32),
|
||||
])
|
||||
})
|
||||
.collect();
|
||||
|
||||
|
||||
|
||||
// Build the Keccak-256 circuit.
|
||||
let _ = keccak256(&mut builder, &input_u64);
|
||||
|
||||
// Generate the circuit and witness.
|
||||
let data = builder.build::<PoseidonGoldilocksConfig>();
|
||||
let mut pw = PartialWitness::new();
|
||||
|
||||
let input_u64_plain: Vec<u64> = input.chunks(8)
|
||||
.map(|chunk| {
|
||||
let mut chunk_padded = [0u8; 8];
|
||||
chunk_padded[..chunk.len()].copy_from_slice(chunk);
|
||||
u64::from_le_bytes(chunk_padded)
|
||||
})
|
||||
.collect();
|
||||
|
||||
for (i, &byte) in input_u64_plain.iter().enumerate() {
|
||||
pw.set_u64_target(input_u64[i], byte as u64);
|
||||
}
|
||||
|
||||
// Run the circuit.
|
||||
let hash_result = data.prove(pw).unwrap();
|
||||
|
||||
let _ = data.verify(hash_result);
|
||||
|
||||
// // Extract the hash result from the circuit output.
|
||||
// let mut output_bytes = Vec::new();
|
||||
// for target in hash_targets {
|
||||
// let lo = hash_result.get_u32(target.0[0]) as u64;
|
||||
// let hi = (hash_result.get_u32(target.0[1]) as u64) << 32;
|
||||
// let combined = lo | hi;
|
||||
// output_bytes.extend_from_slice(&combined.to_le_bytes());
|
||||
// }
|
||||
|
||||
// // Truncate to 256 bits (32 bytes).
|
||||
// output_bytes.truncate(32);
|
||||
|
||||
// // Compute the expected hash using a reference implementation.
|
||||
// let expected_hash = keccak256_reference(input);
|
||||
|
||||
// // Compare the circuit output with the expected hash.
|
||||
// assert_eq!(output_bytes, expected_hash, "Keccak-256 hash mismatch");
|
||||
}
|
||||
|
||||
25
hash/plonky2/src/bench/keccak256/chi.rs
Normal file
25
hash/plonky2/src/bench/keccak256/chi.rs
Normal file
@ -0,0 +1,25 @@
|
||||
use plonky2::hash::hash_types::RichField;
|
||||
use plonky2::plonk::circuit_builder::CircuitBuilder;
|
||||
use plonky2::field::extension::Extendable;
|
||||
use crate::arithmetic::u64_arithmetic::CircuitBuilderU64;
|
||||
|
||||
use crate::arithmetic::u64_arithmetic::U64Target;
|
||||
|
||||
pub fn chi<F: RichField + Extendable<D>, const D: usize>(
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
state: &mut [[U64Target; 5]; 5]
|
||||
){
|
||||
for x in 0..5 {
|
||||
let mut temp = [builder.zero_u64(); 5];
|
||||
for y in 0..5 {
|
||||
temp[y] = state[x][y];
|
||||
}
|
||||
|
||||
|
||||
for y in 0..5 {
|
||||
let t1 = builder.not_u64(temp[(y + 1) % 5]);
|
||||
let t2 = builder.and_u64(t1, temp[(y + 2) % 5]);
|
||||
state[x][y] = builder.xor_u64(state[x][y], t2);
|
||||
}
|
||||
}
|
||||
}
|
||||
30
hash/plonky2/src/bench/keccak256/iota.rs
Normal file
30
hash/plonky2/src/bench/keccak256/iota.rs
Normal file
@ -0,0 +1,30 @@
|
||||
use plonky2::hash::hash_types::RichField;
|
||||
use plonky2::plonk::circuit_builder::CircuitBuilder;
|
||||
use plonky2::field::extension::Extendable;
|
||||
use crate::arithmetic::u64_arithmetic::CircuitBuilderU64;
|
||||
|
||||
use crate::arithmetic::u64_arithmetic::U64Target;
|
||||
use plonky2_u32::gadgets::arithmetic_u32::CircuitBuilderU32;
|
||||
|
||||
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,
|
||||
];
|
||||
|
||||
//iota
|
||||
pub fn iota<F: RichField + Extendable<D>, const D: usize>(
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
state: &mut [[U64Target; 5]; 5],
|
||||
round: usize
|
||||
){
|
||||
|
||||
let lo = builder.constant_u32((ROUND_CONSTANTS[round] & 0xFFFFFFFF) as u32);
|
||||
let hi = builder.constant_u32(((ROUND_CONSTANTS[round] >> 32)& 0xFFFFFFFF) as u32);
|
||||
state[0][0] = builder.xor_u64(state[0][0], U64Target([lo,hi])) ;
|
||||
}
|
||||
699
hash/plonky2/src/bench/keccak256/keccak.rs
Normal file
699
hash/plonky2/src/bench/keccak256/keccak.rs
Normal file
@ -0,0 +1,699 @@
|
||||
use plonky2::field::types::Field;
|
||||
use plonky2::field::goldilocks_field::GoldilocksField;
|
||||
use plonky2::hash::keccak::KeccakHash;
|
||||
use plonky2::plonk::circuit_builder::CircuitBuilder;
|
||||
use plonky2::plonk::circuit_data::CircuitConfig;
|
||||
use plonky2::plonk::config::{GenericConfig, KeccakGoldilocksConfig};
|
||||
use rand::Rng;
|
||||
use plonky2::field::extension::Extendable;
|
||||
use plonky2::plonk::config::Hasher;
|
||||
use plonky2::hash::hash_types::RichField;
|
||||
use plonky2_u32::gadgets::arithmetic_u32::CircuitBuilderU32;
|
||||
use crate::arithmetic::u64_arithmetic::U64Target;
|
||||
use crate::arithmetic::u64_arithmetic::CircuitBuilderU64;
|
||||
use plonky2::iop::witness::Witness;
|
||||
use plonky2::field::types::PrimeField64;
|
||||
use super::{chi::chi, iota::iota, pi::pi, rho::rho, theta::theta};
|
||||
fn generate_data(size: usize) -> Vec<GoldilocksField> {
|
||||
|
||||
let mut data: Vec<GoldilocksField> = Vec::new();
|
||||
for _ in 0..(1<<size) {
|
||||
let mut rng = rand::thread_rng();
|
||||
let random_u64: u64 = rng.gen();
|
||||
data.push(GoldilocksField::from_canonical_u64(random_u64));
|
||||
}
|
||||
data
|
||||
|
||||
}
|
||||
|
||||
|
||||
pub trait WitnessU64<F: PrimeField64>: Witness<F> {
|
||||
fn set_u64_target(&mut self, target: U64Target, value: u64);
|
||||
// fn get_u64_target(&self, target: U64Target) -> (u64, u64);
|
||||
}
|
||||
|
||||
impl<T: Witness<F>, F: PrimeField64> WitnessU64<F> for T {
|
||||
fn set_u64_target(&mut self, target: U64Target, value: u64) {
|
||||
self.set_target(target.0[0].0, F::from_canonical_u32((value & 0xFFFFFFFF) as u32));
|
||||
self.set_target(target.0[1].0, F::from_canonical_u32(((value >> 32) & 0xFFFFFFFF) as u32));
|
||||
}
|
||||
|
||||
// fn get_u64_target(&self, target: U64Target) -> (u64, u64) {
|
||||
// let x_u64 = self.get_target(target.0[0].0).to_canonical_u64();
|
||||
// let y_u64 = self.get_target(target.0[1].0).to_canonical_u64();
|
||||
|
||||
|
||||
// (x_u64, y_u64)
|
||||
// }
|
||||
}
|
||||
|
||||
// TODO: Circuit needs to be implemented
|
||||
pub fn keccak_bench(_size: usize) {
|
||||
|
||||
let data = generate_data(2);
|
||||
const D: usize = 2;
|
||||
type C = KeccakGoldilocksConfig;
|
||||
type F = <C as GenericConfig<D>>::F;
|
||||
|
||||
let config = CircuitConfig::standard_recursion_config();
|
||||
let mut builder = CircuitBuilder::<F, D>::new(config);
|
||||
|
||||
let _initial = builder.add_virtual_targets(data.len());
|
||||
|
||||
let hash = KeccakHash::<32>::hash_or_noop(&data);
|
||||
eprintln!("{:?}", hash);
|
||||
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------
|
||||
|
||||
|
||||
// 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;
|
||||
|
||||
// permutation
|
||||
fn keccak_f<F: RichField + Extendable<D>, const D: usize>(
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
state: &mut [[U64Target; 5]; 5]
|
||||
) {
|
||||
for i in 0..24 {
|
||||
let _ = theta(builder, state);
|
||||
let _ = rho(builder, state);
|
||||
let _ = pi(builder, state);
|
||||
let _ = chi(builder, state);
|
||||
let _ = iota(builder, state, i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn absorb<F: RichField + Extendable<D>, const D: usize>(
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
state: &mut [[U64Target; 5]; 5],
|
||||
message: &[U64Target],
|
||||
rate: usize
|
||||
) {
|
||||
let chunks = message.chunks(rate / 64);
|
||||
for block in chunks {
|
||||
for (i, &word) in block.iter().enumerate() {
|
||||
let x = i % 5;
|
||||
let y = i / 5;
|
||||
state[x][y] = builder.xor_u64(state[x][y], word);
|
||||
}
|
||||
keccak_f(builder, state); // Assume keccak_f is implemented as a circuit
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn squeeze<F: RichField + Extendable<D>, const D: usize>(
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
state: &mut [[U64Target; 5]; 5],
|
||||
rate: usize,
|
||||
output_length: usize
|
||||
) -> Vec<U64Target> {
|
||||
let mut hash = Vec::new();
|
||||
while hash.len() * 8 < output_length {
|
||||
for y in 0..5 {
|
||||
for x in 0..5 {
|
||||
if (x + 5 * y) * 64 < rate {
|
||||
hash.push(state[x][y]);
|
||||
if hash.len() * 8 >= output_length {
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
keccak_f(builder, state); // Assume keccak_f is implemented as a circuit
|
||||
}
|
||||
hash
|
||||
}
|
||||
|
||||
|
||||
fn keccak_pad<F: RichField + Extendable<D>, const D: usize>(
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
message: &[U64Target],
|
||||
rate: usize
|
||||
) -> Vec<U64Target> {
|
||||
let mut padded_message = message.to_vec();
|
||||
let rate_words = rate / 64;
|
||||
let mut pad_len = rate_words - (message.len() % rate_words);
|
||||
|
||||
if pad_len == 0 {
|
||||
pad_len = rate_words;
|
||||
}
|
||||
|
||||
if pad_len == 1 {
|
||||
padded_message.push(U64Target([builder.one_u32(), builder.one_u32()]));
|
||||
} else {
|
||||
padded_message.push(U64Target([builder.one_u32(), builder.zero_u32()]));
|
||||
for _ in 1..(pad_len - 1) {
|
||||
padded_message.push(U64Target([builder.zero_u32(), builder.zero_u32()]));
|
||||
}
|
||||
padded_message.push(U64Target([builder.zero_u32(), builder.one_u32()]));
|
||||
}
|
||||
|
||||
padded_message
|
||||
}
|
||||
|
||||
|
||||
fn keccak256<F: RichField + Extendable<D>, const D: usize>(
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
message: &[U64Target]
|
||||
) -> Vec<U64Target> {
|
||||
let mut state = [[builder.zero_u64(); 5]; 5];
|
||||
let rate = KECCAK_RATE;
|
||||
|
||||
// Padding
|
||||
let padded_message = keccak_pad(builder, message, rate);
|
||||
|
||||
// Absorbing
|
||||
absorb(builder, &mut state, &padded_message, rate);
|
||||
|
||||
// Squeezing
|
||||
let hash = squeeze(builder, &mut state, rate, 256);
|
||||
|
||||
hash
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_keccak256() {
|
||||
// use plonky2_u32::gadgets::arithmetic_u32::U32Target;
|
||||
// use plonky2::iop::target::Target;
|
||||
use plonky2::iop::witness::PartialWitness;
|
||||
use plonky2::plonk::config::PoseidonGoldilocksConfig;
|
||||
use rand::RngCore;
|
||||
|
||||
// use plonky2_u32::witness::WitnessU32;
|
||||
type F = GoldilocksField; // Choose the field used in your implementation.
|
||||
const D: usize = 2; // This should match the extension degree used.
|
||||
|
||||
// Create circuit builder.
|
||||
let config = CircuitConfig::standard_recursion_config();
|
||||
let mut builder = CircuitBuilder::<F, D>::new(config);
|
||||
|
||||
// Example input message
|
||||
let mut input = [0u8; 8];
|
||||
let _ = rand::thread_rng().try_fill_bytes(&mut input);
|
||||
|
||||
// let input = b"hello world";
|
||||
eprintln!("{:?}", input.len());
|
||||
// Convert input to U64Target format used in your Keccak circuit.
|
||||
let input_u64: Vec<U64Target> = input.chunks(8)
|
||||
.map(|chunk| {
|
||||
let mut chunk_padded = [0u8; 8];
|
||||
chunk_padded[..chunk.len()].copy_from_slice(chunk);
|
||||
let value = u64::from_le_bytes(chunk_padded);
|
||||
U64Target([
|
||||
builder.constant_u32(value as u32),
|
||||
builder.constant_u32((value >> 32) as u32),
|
||||
])
|
||||
})
|
||||
.collect();
|
||||
|
||||
|
||||
|
||||
// Build the Keccak-256 circuit.
|
||||
let _ = keccak256(&mut builder, &input_u64);
|
||||
|
||||
eprintln!("{:?}", builder.num_gates());
|
||||
|
||||
// Generate the circuit and witness.
|
||||
let data = builder.build::<PoseidonGoldilocksConfig>();
|
||||
let mut pw = PartialWitness::new();
|
||||
|
||||
let input_u64_plain: Vec<u64> = input.chunks(8)
|
||||
.map(|chunk| {
|
||||
let mut chunk_padded = [0u8; 8];
|
||||
chunk_padded[..chunk.len()].copy_from_slice(chunk);
|
||||
u64::from_le_bytes(chunk_padded)
|
||||
})
|
||||
.collect();
|
||||
|
||||
for (i, &byte) in input_u64_plain.iter().enumerate() {
|
||||
pw.set_u64_target(input_u64[i], byte as u64);
|
||||
}
|
||||
|
||||
// Run the circuit.
|
||||
let hash_result = data.prove(pw).unwrap();
|
||||
|
||||
let _ = data.verify(hash_result.clone());
|
||||
|
||||
// Extract the hash result from the circuit output.
|
||||
// let mut output_bytes = Vec::new();
|
||||
// for target in hash_targets {
|
||||
// let lo = hash_result.get_u32(target.0[0]) as u64;
|
||||
// let hi = (hash_result.get_u32(target.0[1]) as u64) << 32;
|
||||
// let combined = lo | hi;
|
||||
// output_bytes.extend_from_slice(&combined.to_le_bytes());
|
||||
// }
|
||||
|
||||
// // Truncate to 256 bits (32 bytes).
|
||||
// output_bytes.truncate(32);
|
||||
|
||||
// // Compute the expected hash using a reference implementation.
|
||||
// let expected_hash = keccak256_reference(input);
|
||||
|
||||
// // Compare the circuit output with the expected hash.
|
||||
// assert_eq!(output_bytes, expected_hash, "Keccak-256 hash mismatch");
|
||||
|
||||
println!("{:?}",hash_result.get_public_inputs_hash());
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use plonky2::field::goldilocks_field::GoldilocksField;
|
||||
// use plonky2::field::types::Field;
|
||||
use plonky2::hash::hash_types::RichField;
|
||||
use plonky2::iop::witness::{PartialWitness/* , Witness*/};
|
||||
use plonky2::plonk::circuit_builder::CircuitBuilder;
|
||||
use plonky2::plonk::circuit_data::CircuitConfig;
|
||||
use plonky2::plonk::config::PoseidonGoldilocksConfig;
|
||||
// use plonky2_u32::gadgets::arithmetic_u32::U32Target;
|
||||
use crate::arithmetic::u64_arithmetic::U64Target;
|
||||
|
||||
fn create_u64_target<F: RichField + Extendable<D>, const D: usize>(
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
value: u64
|
||||
) -> U64Target {
|
||||
let lo = value as u32;
|
||||
let hi = (value >> 32) as u32;
|
||||
U64Target([builder.constant_u32(lo), builder.constant_u32(hi)])
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_theta_function() {
|
||||
type F = GoldilocksField;
|
||||
const D: usize = 2;
|
||||
|
||||
// Create circuit builder
|
||||
let config = CircuitConfig::standard_recursion_config();
|
||||
let mut builder = CircuitBuilder::<F, D>::new(config);
|
||||
|
||||
// Input state
|
||||
let input_state: [[U64Target; 5]; 5] = [
|
||||
[
|
||||
create_u64_target(&mut builder, 0x0000000000000001),
|
||||
create_u64_target(&mut builder, 0x0000000000000002),
|
||||
create_u64_target(&mut builder, 0x0000000000000003),
|
||||
create_u64_target(&mut builder, 0x0000000000000004),
|
||||
create_u64_target(&mut builder, 0x0000000000000005)
|
||||
],
|
||||
[
|
||||
create_u64_target(&mut builder, 0x0000000000000006),
|
||||
create_u64_target(&mut builder, 0x0000000000000007),
|
||||
create_u64_target(&mut builder, 0x0000000000000008),
|
||||
create_u64_target(&mut builder, 0x0000000000000009),
|
||||
create_u64_target(&mut builder, 0x000000000000000A)
|
||||
],
|
||||
[
|
||||
create_u64_target(&mut builder, 0x000000000000000B),
|
||||
create_u64_target(&mut builder, 0x000000000000000C),
|
||||
create_u64_target(&mut builder, 0x000000000000000D),
|
||||
create_u64_target(&mut builder, 0x000000000000000E),
|
||||
create_u64_target(&mut builder, 0x000000000000000F)
|
||||
],
|
||||
[
|
||||
create_u64_target(&mut builder, 0x0000000000000010),
|
||||
create_u64_target(&mut builder, 0x0000000000000011),
|
||||
create_u64_target(&mut builder, 0x0000000000000012),
|
||||
create_u64_target(&mut builder, 0x0000000000000013),
|
||||
create_u64_target(&mut builder, 0x0000000000000014)
|
||||
],
|
||||
[
|
||||
create_u64_target(&mut builder, 0x0000000000000015),
|
||||
create_u64_target(&mut builder, 0x0000000000000016),
|
||||
create_u64_target(&mut builder, 0x0000000000000017),
|
||||
create_u64_target(&mut builder, 0x0000000000000018),
|
||||
create_u64_target(&mut builder, 0x0000000000000019)
|
||||
]
|
||||
];
|
||||
|
||||
// Expected output state (after theta)
|
||||
let expected_state = [
|
||||
[
|
||||
create_u64_target(&mut builder, 0x7B7B7B7B7B7B7B7B),
|
||||
create_u64_target(&mut builder, 0x8B8B8B8B8B8B8B8B),
|
||||
create_u64_target(&mut builder, 0x9B9B9B9B9B9B9B9B),
|
||||
create_u64_target(&mut builder, 0xABABABABABABABAB),
|
||||
create_u64_target(&mut builder, 0xBBBBBBBBBBBBBBBB)
|
||||
],
|
||||
[
|
||||
create_u64_target(&mut builder, 0xCBCBCBCBCBCBCBCB),
|
||||
create_u64_target(&mut builder, 0xDBDBDBDBDBDBDBDB),
|
||||
create_u64_target(&mut builder, 0xEBEBEBEBEBEBEBEB),
|
||||
create_u64_target(&mut builder, 0xFBFBFBFBFBFBFBFB),
|
||||
create_u64_target(&mut builder, 0x0B0B0B0B0B0B0B0B)
|
||||
],
|
||||
[
|
||||
create_u64_target(&mut builder, 0x1B1B1B1B1B1B1B1B),
|
||||
create_u64_target(&mut builder, 0x2B2B2B2B2B2B2B2B),
|
||||
create_u64_target(&mut builder, 0x3B3B3B3B3B3B3B3B),
|
||||
create_u64_target(&mut builder, 0x4B4B4B4B4B4B4B4B),
|
||||
create_u64_target(&mut builder, 0x5B5B5B5B5B5B5B5B)
|
||||
],
|
||||
[
|
||||
create_u64_target(&mut builder, 0x6B6B6B6B6B6B6B6B),
|
||||
create_u64_target(&mut builder, 0x7B7B7B7B7B7B7B7B),
|
||||
create_u64_target(&mut builder, 0x8B8B8B8B8B8B8B8B),
|
||||
create_u64_target(&mut builder, 0x9B9B9B9B9B9B9B9B),
|
||||
create_u64_target(&mut builder, 0xABABABABABABABAB)
|
||||
],
|
||||
[
|
||||
create_u64_target(&mut builder, 0xBBBBBBBBBBBBBBBB),
|
||||
create_u64_target(&mut builder, 0xCBCBCBCBCBCBCBCB),
|
||||
create_u64_target(&mut builder, 0xDBDBDBDBDBDBDBDB),
|
||||
create_u64_target(&mut builder, 0xEBEBEBEBEBEBEBEB),
|
||||
create_u64_target(&mut builder, 0xFBFBFBFBFBFBFBFB)
|
||||
]
|
||||
];
|
||||
|
||||
// Run the theta function
|
||||
let mut state = input_state;
|
||||
theta(&mut builder, &mut state);
|
||||
|
||||
|
||||
// Check if the output state matches the expected state
|
||||
for x in 0..5 {
|
||||
for y in 0..5 {
|
||||
for i in 0..2 {
|
||||
println!("Comparing: {:?} and {:?}", state[x][y].0[i].0, expected_state[x][y].0[i].0);
|
||||
let res = builder.is_equal(state[x][y].0[i].0, expected_state[x][y].0[i].0);
|
||||
builder.assert_bool(res);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
println!("{:?}", builder.num_gates());
|
||||
// Build the circuit
|
||||
let data = builder.build::<PoseidonGoldilocksConfig>();
|
||||
|
||||
// Create witness and prove
|
||||
let mut pw = PartialWitness::new();
|
||||
pw.set_u64_target(input_state[0][0], 0x0000000000000001);
|
||||
pw.set_u64_target(input_state[0][1], 0x0000000000000002);
|
||||
pw.set_u64_target(input_state[0][2], 0x0000000000000003);
|
||||
pw.set_u64_target(input_state[0][3], 0x0000000000000004);
|
||||
pw.set_u64_target(input_state[0][4], 0x0000000000000005);
|
||||
pw.set_u64_target(input_state[1][0], 0x0000000000000006);
|
||||
pw.set_u64_target(input_state[1][1], 0x0000000000000007);
|
||||
pw.set_u64_target(input_state[1][2], 0x0000000000000008);
|
||||
pw.set_u64_target(input_state[1][3], 0x0000000000000009);
|
||||
pw.set_u64_target(input_state[1][4], 0x000000000000000A);
|
||||
pw.set_u64_target(input_state[2][0], 0x000000000000000B);
|
||||
pw.set_u64_target(input_state[2][1], 0x000000000000000C);
|
||||
pw.set_u64_target(input_state[2][2], 0x000000000000000D);
|
||||
pw.set_u64_target(input_state[2][3], 0x000000000000000E);
|
||||
pw.set_u64_target(input_state[2][4], 0x000000000000000F);
|
||||
pw.set_u64_target(input_state[3][0], 0x0000000000000010);
|
||||
pw.set_u64_target(input_state[3][1], 0x0000000000000011);
|
||||
pw.set_u64_target(input_state[3][2], 0x0000000000000012);
|
||||
pw.set_u64_target(input_state[3][3], 0x0000000000000013);
|
||||
pw.set_u64_target(input_state[3][4], 0x0000000000000014);
|
||||
pw.set_u64_target(input_state[4][0], 0x0000000000000015);
|
||||
pw.set_u64_target(input_state[4][1], 0x0000000000000016);
|
||||
pw.set_u64_target(input_state[4][2], 0x0000000000000017);
|
||||
pw.set_u64_target(input_state[4][3], 0x0000000000000018);
|
||||
pw.set_u64_target(input_state[4][4], 0x0000000000000019);
|
||||
|
||||
let proof = data.prove(pw).unwrap();
|
||||
assert!(data.verify(proof).is_ok());
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn test_rho_function() {
|
||||
type F = GoldilocksField;
|
||||
const D: usize = 2;
|
||||
|
||||
// Create circuit builder
|
||||
let config = CircuitConfig::standard_recursion_config();
|
||||
let mut builder = CircuitBuilder::<F, D>::new(config);
|
||||
|
||||
// Input state (example, should be taken from an authoritative source)
|
||||
let input_state = [
|
||||
[
|
||||
create_u64_target(&mut builder, 0x0000000000000001),
|
||||
create_u64_target(&mut builder, 0x0000000000000002),
|
||||
create_u64_target(&mut builder, 0x0000000000000003),
|
||||
create_u64_target(&mut builder, 0x0000000000000004),
|
||||
create_u64_target(&mut builder, 0x0000000000000005)
|
||||
],
|
||||
[
|
||||
create_u64_target(&mut builder, 0x0000000000000006),
|
||||
create_u64_target(&mut builder, 0x0000000000000007),
|
||||
create_u64_target(&mut builder, 0x0000000000000008),
|
||||
create_u64_target(&mut builder, 0x0000000000000009),
|
||||
create_u64_target(&mut builder, 0x000000000000000A)
|
||||
],
|
||||
[
|
||||
create_u64_target(&mut builder, 0x000000000000000B),
|
||||
create_u64_target(&mut builder, 0x000000000000000C),
|
||||
create_u64_target(&mut builder, 0x000000000000000D),
|
||||
create_u64_target(&mut builder, 0x000000000000000E),
|
||||
create_u64_target(&mut builder, 0x000000000000000F)
|
||||
],
|
||||
[
|
||||
create_u64_target(&mut builder, 0x0000000000000010),
|
||||
create_u64_target(&mut builder, 0x0000000000000011),
|
||||
create_u64_target(&mut builder, 0x0000000000000012),
|
||||
create_u64_target(&mut builder, 0x0000000000000013),
|
||||
create_u64_target(&mut builder, 0x0000000000000014)
|
||||
],
|
||||
[
|
||||
create_u64_target(&mut builder, 0x0000000000000015),
|
||||
create_u64_target(&mut builder, 0x0000000000000016),
|
||||
create_u64_target(&mut builder, 0x0000000000000017),
|
||||
create_u64_target(&mut builder, 0x0000000000000018),
|
||||
create_u64_target(&mut builder, 0x0000000000000019)
|
||||
]
|
||||
];
|
||||
|
||||
// Expected state after rho (example, should be taken from an authoritative source)
|
||||
let expected_state = [
|
||||
[
|
||||
create_u64_target(&mut builder, 0x0000000000000001),
|
||||
create_u64_target(&mut builder, 0x0000000000000100),
|
||||
create_u64_target(&mut builder, 0x0000000000003000),
|
||||
create_u64_target(&mut builder, 0x0000000000040000),
|
||||
create_u64_target(&mut builder, 0x0000000000500000)
|
||||
],
|
||||
[
|
||||
create_u64_target(&mut builder, 0x0000000000600000),
|
||||
create_u64_target(&mut builder, 0x0000000000700000),
|
||||
create_u64_target(&mut builder, 0x0000000008000000),
|
||||
create_u64_target(&mut builder, 0x0000000009000000),
|
||||
create_u64_target(&mut builder, 0x00000000A0000000)
|
||||
],
|
||||
[
|
||||
create_u64_target(&mut builder, 0x00000000B0000000),
|
||||
create_u64_target(&mut builder, 0x00000000C0000000),
|
||||
create_u64_target(&mut builder, 0x0000000D00000000),
|
||||
create_u64_target(&mut builder, 0x0000000E00000000),
|
||||
create_u64_target(&mut builder, 0x0000000F00000000)
|
||||
],
|
||||
[
|
||||
create_u64_target(&mut builder, 0x0000001000000000),
|
||||
create_u64_target(&mut builder, 0x0000001100000000),
|
||||
create_u64_target(&mut builder, 0x0000001200000000),
|
||||
create_u64_target(&mut builder, 0x0000001300000000),
|
||||
create_u64_target(&mut builder, 0x0000001400000000)
|
||||
],
|
||||
[
|
||||
create_u64_target(&mut builder, 0x0000001500000000),
|
||||
create_u64_target(&mut builder, 0x0000001600000000),
|
||||
create_u64_target(&mut builder, 0x0000001700000000),
|
||||
create_u64_target(&mut builder, 0x0000001800000000),
|
||||
create_u64_target(&mut builder, 0x0000001900000000)
|
||||
]
|
||||
];
|
||||
|
||||
// Run the rho function
|
||||
let mut state = input_state;
|
||||
rho(&mut builder, &mut state);
|
||||
// Check if the output state matches the expected state
|
||||
for x in 0..5 {
|
||||
for y in 0..5 {
|
||||
let res = builder.is_equal(state[x][y].0[0].0, expected_state[x][y].0[0].0);
|
||||
let res2 = builder.is_equal(state[x][y].0[1].0, expected_state[x][y].0[1].0);
|
||||
|
||||
builder.assert_bool(res);
|
||||
builder.assert_bool(res2);
|
||||
}
|
||||
}
|
||||
|
||||
println!("{:?}", builder.num_gates());
|
||||
// Build the circuit
|
||||
let data = builder.build::<PoseidonGoldilocksConfig>();
|
||||
|
||||
// Create witness and prove
|
||||
let pw = PartialWitness::new();
|
||||
let proof = data.prove(pw).unwrap();
|
||||
assert!(data.verify(proof).is_ok());
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn test_keccak256_permutation() {
|
||||
type F = GoldilocksField;
|
||||
const D: usize = 2;
|
||||
|
||||
// Create circuit builder
|
||||
let config = CircuitConfig::standard_recursion_config();
|
||||
let mut builder = CircuitBuilder::<F, D>::new(config);
|
||||
|
||||
// Input state (example, should be taken from an authoritative source)
|
||||
let input_state = [
|
||||
[
|
||||
create_u64_target(&mut builder, 0x0000000000000001),
|
||||
create_u64_target(&mut builder, 0x0000000000000002),
|
||||
create_u64_target(&mut builder, 0x0000000000000003),
|
||||
create_u64_target(&mut builder, 0x0000000000000004),
|
||||
create_u64_target(&mut builder, 0x0000000000000005)
|
||||
],
|
||||
[
|
||||
create_u64_target(&mut builder, 0x0000000000000006),
|
||||
create_u64_target(&mut builder, 0x0000000000000007),
|
||||
create_u64_target(&mut builder, 0x0000000000000008),
|
||||
create_u64_target(&mut builder, 0x0000000000000009),
|
||||
create_u64_target(&mut builder, 0x000000000000000A)
|
||||
],
|
||||
[
|
||||
create_u64_target(&mut builder, 0x000000000000000B),
|
||||
create_u64_target(&mut builder, 0x000000000000000C),
|
||||
create_u64_target(&mut builder, 0x000000000000000D),
|
||||
create_u64_target(&mut builder, 0x000000000000000E),
|
||||
create_u64_target(&mut builder, 0x000000000000000F)
|
||||
],
|
||||
[
|
||||
create_u64_target(&mut builder, 0x0000000000000010),
|
||||
create_u64_target(&mut builder, 0x0000000000000011),
|
||||
create_u64_target(&mut builder, 0x0000000000000012),
|
||||
create_u64_target(&mut builder, 0x0000000000000013),
|
||||
create_u64_target(&mut builder, 0x0000000000000014)
|
||||
],
|
||||
[
|
||||
create_u64_target(&mut builder, 0x0000000000000015),
|
||||
create_u64_target(&mut builder, 0x0000000000000016),
|
||||
create_u64_target(&mut builder, 0x0000000000000017),
|
||||
create_u64_target(&mut builder, 0x0000000000000018),
|
||||
create_u64_target(&mut builder, 0x0000000000000019)
|
||||
]
|
||||
];
|
||||
|
||||
// Expected state after keccak256 permutation (example, should be taken from an authoritative source)
|
||||
let expected_state = [
|
||||
[
|
||||
create_u64_target(&mut builder, 0xE69F6BAE986CCF06),
|
||||
create_u64_target(&mut builder, 0xDF9D77905A3546B6),
|
||||
create_u64_target(&mut builder, 0x7BFBFFF923073CEB),
|
||||
create_u64_target(&mut builder, 0xB2D9AB3E200FD999),
|
||||
create_u64_target(&mut builder, 0x1A741CAEC020555C)
|
||||
],
|
||||
[
|
||||
create_u64_target(&mut builder, 0x56D7B52E1442C0AE),
|
||||
create_u64_target(&mut builder, 0xEBA39A0E00EF9FE9),
|
||||
create_u64_target(&mut builder, 0x2D6FF9BE61A295EE),
|
||||
create_u64_target(&mut builder, 0xC82D01AE6E142988),
|
||||
create_u64_target(&mut builder, 0xCDEDECBAD32B9246)
|
||||
],
|
||||
[
|
||||
create_u64_target(&mut builder, 0x7AF13F3C6F6E4AF6),
|
||||
create_u64_target(&mut builder, 0xBD469F697CCF7B91),
|
||||
create_u64_target(&mut builder, 0xAB4F902ED5B9FD93),
|
||||
create_u64_target(&mut builder, 0xFC4F6A6C27E0190B),
|
||||
create_u64_target(&mut builder, 0x3D41F5EF85540B06)
|
||||
],
|
||||
[
|
||||
create_u64_target(&mut builder, 0x2D9F050A3E1600F4),
|
||||
create_u64_target(&mut builder, 0x0ED46287DA8AA931),
|
||||
create_u64_target(&mut builder, 0xA13AD679DFAA4EA3),
|
||||
create_u64_target(&mut builder, 0x70B1D7A7C896E12A),
|
||||
create_u64_target(&mut builder, 0xA2CF9C93C5326E0D)
|
||||
],
|
||||
[
|
||||
create_u64_target(&mut builder, 0x2CE66FBC3AC94F5B),
|
||||
create_u64_target(&mut builder, 0x4960E539C1EF3BA7),
|
||||
create_u64_target(&mut builder, 0xC7C50305DF46E1BB),
|
||||
create_u64_target(&mut builder, 0xEE6FE33D998F8A8B),
|
||||
create_u64_target(&mut builder, 0x2A971ED5399DC662)
|
||||
]
|
||||
];
|
||||
|
||||
// Run the keccak256 permutation function
|
||||
let mut state = input_state;
|
||||
keccak_f(&mut builder, &mut state);
|
||||
|
||||
// Check if the output state matches the expected state
|
||||
for x in 0..5 {
|
||||
for y in 0..5 {
|
||||
let res1 = builder.is_equal(state[x][y].0[0].0, expected_state[x][y].0[0].0);
|
||||
let res2 = builder.is_equal(state[x][y].0[1].0, expected_state[x][y].0[1].0);
|
||||
|
||||
builder.assert_bool(res1);
|
||||
builder.assert_bool(res2);
|
||||
}
|
||||
}
|
||||
println!("{:?}", builder.num_gates());
|
||||
// Build the circuit
|
||||
let data = builder.build::<PoseidonGoldilocksConfig>();
|
||||
|
||||
// Create witness and prove
|
||||
let pw = PartialWitness::new();
|
||||
let proof = data.prove(pw).unwrap();
|
||||
assert!(data.verify(proof).is_ok());
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn test_keccak256_hash() {
|
||||
type F = GoldilocksField;
|
||||
const D: usize = 2;
|
||||
|
||||
// Create circuit builder
|
||||
let config = CircuitConfig::standard_recursion_config();
|
||||
let mut builder = CircuitBuilder::<F, D>::new(config);
|
||||
|
||||
// Input message (example, should be taken from an authoritative source)
|
||||
let input_message = vec![
|
||||
create_u64_target(&mut builder, 0x0000000000000001),
|
||||
create_u64_target(&mut builder, 0x0000000000000002),
|
||||
create_u64_target(&mut builder, 0x0000000000000003),
|
||||
create_u64_target(&mut builder, 0x0000000000000004)
|
||||
];
|
||||
|
||||
// Expected hash (example, should be taken from an authoritative source)
|
||||
let expected_hash = vec![
|
||||
create_u64_target(&mut builder, 0xA7FFC6F8BF1ED766),
|
||||
create_u64_target(&mut builder, 0x51C14756A061D662),
|
||||
create_u64_target(&mut builder, 0xF580FF4DE43B49FA),
|
||||
create_u64_target(&mut builder, 0x82D80A4B80F8434A)
|
||||
];
|
||||
|
||||
// Run the keccak256 hash function
|
||||
let hash = keccak256(&mut builder, &input_message);
|
||||
|
||||
// Check if the output hash matches the expected hash
|
||||
for i in 0..expected_hash.len() {
|
||||
let res1 = builder.is_equal(hash[i].0[0].0, expected_hash[i].0[0].0);
|
||||
let res2 = builder.is_equal(hash[i].0[1].0, expected_hash[i].0[1].0);
|
||||
|
||||
builder.assert_bool(res1);
|
||||
builder.assert_bool(res2);
|
||||
}
|
||||
|
||||
println!("{:?}", builder.num_gates());
|
||||
// Build the circuit
|
||||
let data = builder.build::<PoseidonGoldilocksConfig>();
|
||||
|
||||
// Create witness and prove
|
||||
let pw = PartialWitness::new();
|
||||
let proof = data.prove(pw).unwrap();
|
||||
assert!(data.verify(proof).is_ok());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
20
hash/plonky2/src/bench/keccak256/pi.rs
Normal file
20
hash/plonky2/src/bench/keccak256/pi.rs
Normal file
@ -0,0 +1,20 @@
|
||||
use plonky2::hash::hash_types::RichField;
|
||||
use plonky2::plonk::circuit_builder::CircuitBuilder;
|
||||
use plonky2::field::extension::Extendable;
|
||||
use crate::arithmetic::u64_arithmetic::CircuitBuilderU64;
|
||||
|
||||
use crate::arithmetic::u64_arithmetic::U64Target;
|
||||
|
||||
//pi
|
||||
pub fn pi<F: RichField + Extendable<D>, const D: usize>(
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
state: &mut [[U64Target; 5]; 5]
|
||||
){
|
||||
let mut new_state = [[builder.zero_u64(); 5]; 5];
|
||||
for x in 0..5 {
|
||||
for y in 0..5 {
|
||||
new_state[(2 * x + 3 * y) % 5][y] = state[x][y];
|
||||
}
|
||||
}
|
||||
*state = new_state;
|
||||
}
|
||||
27
hash/plonky2/src/bench/keccak256/rho.rs
Normal file
27
hash/plonky2/src/bench/keccak256/rho.rs
Normal file
@ -0,0 +1,27 @@
|
||||
use plonky2::hash::hash_types::RichField;
|
||||
use plonky2::plonk::circuit_builder::CircuitBuilder;
|
||||
use plonky2::field::extension::Extendable;
|
||||
use crate::arithmetic::u64_arithmetic::CircuitBuilderU64;
|
||||
|
||||
use crate::arithmetic::u64_arithmetic::U64Target;
|
||||
|
||||
//rho
|
||||
pub fn rho<F: RichField + Extendable<D>, const D: usize>(
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
state: &mut [[U64Target; 5]; 5]
|
||||
){
|
||||
const RHO_OFFSETS: [[usize; 5]; 5] = [
|
||||
[0, 1, 62, 28, 27],
|
||||
[36, 44, 6, 55, 20],
|
||||
[3, 10, 43, 25, 39],
|
||||
[41, 45, 15, 21, 8],
|
||||
[18, 2, 61, 56, 14],
|
||||
];
|
||||
|
||||
for x in 0..5 {
|
||||
for y in 0..5 {
|
||||
let rotation = RHO_OFFSETS[x][y];
|
||||
state[x][y] = builder.rotate_left_u64(state[x][y], rotation as u8);
|
||||
}
|
||||
}
|
||||
}
|
||||
204
hash/plonky2/src/bench/keccak256/theta.rs
Normal file
204
hash/plonky2/src/bench/keccak256/theta.rs
Normal file
@ -0,0 +1,204 @@
|
||||
use plonky2::hash::hash_types::RichField;
|
||||
use plonky2::plonk::circuit_builder::CircuitBuilder;
|
||||
use plonky2::field::extension::Extendable;
|
||||
use crate::arithmetic::u64_arithmetic::CircuitBuilderU64;
|
||||
|
||||
|
||||
use crate::arithmetic::u64_arithmetic::U64Target;
|
||||
|
||||
// Theta
|
||||
pub fn theta<F: RichField + Extendable<D>, const D: usize>(
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
state: &mut [[U64Target; 5]; 5]
|
||||
){
|
||||
let mut c = [builder.zero_u64(); 5];
|
||||
let mut d = [builder.zero_u64(); 5];
|
||||
|
||||
// Compute column parities
|
||||
for x in 0..5 {
|
||||
|
||||
let xor_x0_x1 = builder.xor_u64(state[x][0], state[x][1]);
|
||||
let xor_x0_x1_x2 = builder.xor_u64(xor_x0_x1, state[x][2]);
|
||||
let xor_x0_x1_x2_x3 = builder.xor_u64(xor_x0_x1_x2, state[x][3]);
|
||||
c[x] = builder.xor_u64(xor_x0_x1_x2_x3, state[x][4]);
|
||||
|
||||
}
|
||||
|
||||
// Compute rotated parities
|
||||
for x in 0..5 {
|
||||
let c_left = c[(x + 4) % 5];
|
||||
let c_right_rot = builder.rotate_left_u64(c[(x + 1) % 5], 1);
|
||||
d[x] = builder.xor_u64(c_left, c_right_rot);
|
||||
}
|
||||
|
||||
// Modify the state
|
||||
for x in 0..5 {
|
||||
for y in 0..5 {
|
||||
state[x][y] = builder.xor_u64(state[x][y], d[x]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use plonky2::field::goldilocks_field::GoldilocksField;
|
||||
use plonky2::hash::hash_types::RichField;
|
||||
use plonky2::iop::witness::PartialWitness;
|
||||
use plonky2::plonk::circuit_builder::CircuitBuilder;
|
||||
use plonky2::plonk::circuit_data::CircuitConfig;
|
||||
use plonky2::plonk::config::PoseidonGoldilocksConfig;
|
||||
use crate::arithmetic::u64_arithmetic::U64Target;
|
||||
use plonky2_u32::gadgets::arithmetic_u32::CircuitBuilderU32;
|
||||
use crate::bench::keccak256::keccak::WitnessU64;
|
||||
|
||||
fn create_u64_target<F: RichField + Extendable<D>, const D: usize>(
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
value: u64
|
||||
) -> U64Target {
|
||||
let lo = value as u32;
|
||||
let hi = (value >> 32) as u32;
|
||||
U64Target([builder.constant_u32(lo), builder.constant_u32(hi)])
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_theta_function() {
|
||||
type F = GoldilocksField;
|
||||
const D: usize = 2;
|
||||
|
||||
// Create circuit builder
|
||||
let config = CircuitConfig::standard_recursion_config();
|
||||
let mut builder = CircuitBuilder::<F, D>::new(config);
|
||||
|
||||
// Input state
|
||||
let input_state: [[U64Target; 5]; 5] = [
|
||||
[
|
||||
create_u64_target(&mut builder, 0x0000000000000001),
|
||||
create_u64_target(&mut builder, 0x0000000000000002),
|
||||
create_u64_target(&mut builder, 0x0000000000000003),
|
||||
create_u64_target(&mut builder, 0x0000000000000004),
|
||||
create_u64_target(&mut builder, 0x0000000000000005)
|
||||
],
|
||||
[
|
||||
create_u64_target(&mut builder, 0x0000000000000006),
|
||||
create_u64_target(&mut builder, 0x0000000000000007),
|
||||
create_u64_target(&mut builder, 0x0000000000000008),
|
||||
create_u64_target(&mut builder, 0x0000000000000009),
|
||||
create_u64_target(&mut builder, 0x000000000000000A)
|
||||
],
|
||||
[
|
||||
create_u64_target(&mut builder, 0x000000000000000B),
|
||||
create_u64_target(&mut builder, 0x000000000000000C),
|
||||
create_u64_target(&mut builder, 0x000000000000000D),
|
||||
create_u64_target(&mut builder, 0x000000000000000E),
|
||||
create_u64_target(&mut builder, 0x000000000000000F)
|
||||
],
|
||||
[
|
||||
create_u64_target(&mut builder, 0x0000000000000010),
|
||||
create_u64_target(&mut builder, 0x0000000000000011),
|
||||
create_u64_target(&mut builder, 0x0000000000000012),
|
||||
create_u64_target(&mut builder, 0x0000000000000013),
|
||||
create_u64_target(&mut builder, 0x0000000000000014)
|
||||
],
|
||||
[
|
||||
create_u64_target(&mut builder, 0x0000000000000015),
|
||||
create_u64_target(&mut builder, 0x0000000000000016),
|
||||
create_u64_target(&mut builder, 0x0000000000000017),
|
||||
create_u64_target(&mut builder, 0x0000000000000018),
|
||||
create_u64_target(&mut builder, 0x0000000000000019)
|
||||
]
|
||||
];
|
||||
|
||||
// Expected output state (after theta)
|
||||
let expected_state = [
|
||||
[
|
||||
create_u64_target(&mut builder, 0x7B7B7B7B7B7B7B7B),
|
||||
create_u64_target(&mut builder, 0x8B8B8B8B8B8B8B8B),
|
||||
create_u64_target(&mut builder, 0x9B9B9B9B9B9B9B9B),
|
||||
create_u64_target(&mut builder, 0xABABABABABABABAB),
|
||||
create_u64_target(&mut builder, 0xBBBBBBBBBBBBBBBB)
|
||||
],
|
||||
[
|
||||
create_u64_target(&mut builder, 0xCBCBCBCBCBCBCBCB),
|
||||
create_u64_target(&mut builder, 0xDBDBDBDBDBDBDBDB),
|
||||
create_u64_target(&mut builder, 0xEBEBEBEBEBEBEBEB),
|
||||
create_u64_target(&mut builder, 0xFBFBFBFBFBFBFBFB),
|
||||
create_u64_target(&mut builder, 0x0B0B0B0B0B0B0B0B)
|
||||
],
|
||||
[
|
||||
create_u64_target(&mut builder, 0x1B1B1B1B1B1B1B1B),
|
||||
create_u64_target(&mut builder, 0x2B2B2B2B2B2B2B2B),
|
||||
create_u64_target(&mut builder, 0x3B3B3B3B3B3B3B3B),
|
||||
create_u64_target(&mut builder, 0x4B4B4B4B4B4B4B4B),
|
||||
create_u64_target(&mut builder, 0x5B5B5B5B5B5B5B5B)
|
||||
],
|
||||
[
|
||||
create_u64_target(&mut builder, 0x6B6B6B6B6B6B6B6B),
|
||||
create_u64_target(&mut builder, 0x7B7B7B7B7B7B7B7B),
|
||||
create_u64_target(&mut builder, 0x8B8B8B8B8B8B8B8B),
|
||||
create_u64_target(&mut builder, 0x9B9B9B9B9B9B9B9B),
|
||||
create_u64_target(&mut builder, 0xABABABABABABABAB)
|
||||
],
|
||||
[
|
||||
create_u64_target(&mut builder, 0xBBBBBBBBBBBBBBBB),
|
||||
create_u64_target(&mut builder, 0xCBCBCBCBCBCBCBCB),
|
||||
create_u64_target(&mut builder, 0xDBDBDBDBDBDBDBDB),
|
||||
create_u64_target(&mut builder, 0xEBEBEBEBEBEBEBEB),
|
||||
create_u64_target(&mut builder, 0xFBFBFBFBFBFBFBFB)
|
||||
]
|
||||
];
|
||||
|
||||
// Run the theta function
|
||||
let mut state = input_state;
|
||||
let _ = theta(&mut builder, &mut state);
|
||||
|
||||
|
||||
// Check if the output state matches the expected state
|
||||
for x in 0..5 {
|
||||
for y in 0..5 {
|
||||
for i in 0..2 {
|
||||
println!("Comparing: {:?} and {:?}", state[x][y].0[i].0, expected_state[x][y].0[i].0);
|
||||
let res = builder.is_equal(state[x][y].0[i].0, expected_state[x][y].0[i].0);
|
||||
builder.assert_bool(res);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
println!("{:?}", builder.num_gates());
|
||||
// Build the circuit
|
||||
let data = builder.build::<PoseidonGoldilocksConfig>();
|
||||
|
||||
// Create witness and prove
|
||||
let mut pw = PartialWitness::new();
|
||||
pw.set_u64_target(input_state[0][0], 0x0000000000000001);
|
||||
pw.set_u64_target(input_state[0][1], 0x0000000000000002);
|
||||
pw.set_u64_target(input_state[0][2], 0x0000000000000003);
|
||||
pw.set_u64_target(input_state[0][3], 0x0000000000000004);
|
||||
pw.set_u64_target(input_state[0][4], 0x0000000000000005);
|
||||
pw.set_u64_target(input_state[1][0], 0x0000000000000006);
|
||||
pw.set_u64_target(input_state[1][1], 0x0000000000000007);
|
||||
pw.set_u64_target(input_state[1][2], 0x0000000000000008);
|
||||
pw.set_u64_target(input_state[1][3], 0x0000000000000009);
|
||||
pw.set_u64_target(input_state[1][4], 0x000000000000000A);
|
||||
pw.set_u64_target(input_state[2][0], 0x000000000000000B);
|
||||
pw.set_u64_target(input_state[2][1], 0x000000000000000C);
|
||||
pw.set_u64_target(input_state[2][2], 0x000000000000000D);
|
||||
pw.set_u64_target(input_state[2][3], 0x000000000000000E);
|
||||
pw.set_u64_target(input_state[2][4], 0x000000000000000F);
|
||||
pw.set_u64_target(input_state[3][0], 0x0000000000000010);
|
||||
pw.set_u64_target(input_state[3][1], 0x0000000000000011);
|
||||
pw.set_u64_target(input_state[3][2], 0x0000000000000012);
|
||||
pw.set_u64_target(input_state[3][3], 0x0000000000000013);
|
||||
pw.set_u64_target(input_state[3][4], 0x0000000000000014);
|
||||
pw.set_u64_target(input_state[4][0], 0x0000000000000015);
|
||||
pw.set_u64_target(input_state[4][1], 0x0000000000000016);
|
||||
pw.set_u64_target(input_state[4][2], 0x0000000000000017);
|
||||
pw.set_u64_target(input_state[4][3], 0x0000000000000018);
|
||||
pw.set_u64_target(input_state[4][4], 0x0000000000000019);
|
||||
|
||||
let proof = data.prove(pw).unwrap();
|
||||
assert!(data.verify(proof).is_ok());
|
||||
}
|
||||
}
|
||||
@ -1,14 +1,12 @@
|
||||
use anyhow::Result;
|
||||
use plonky2::field::types::Field;
|
||||
// use plonky2::hash::hash_types::{HashOutTarget, RichField};
|
||||
use plonky2::field::goldilocks_field::GoldilocksField;
|
||||
// use plonky2::hash::keccak;
|
||||
// use plonky2::hash::keccak::KeccakHash;
|
||||
|
||||
use plonky2::hash::poseidon::PoseidonHash;
|
||||
use plonky2::iop::witness::{PartialWitness, WitnessWrite};
|
||||
use plonky2::plonk::circuit_builder::CircuitBuilder;
|
||||
use plonky2::plonk::circuit_data::CircuitConfig;
|
||||
use plonky2::plonk::config::{/*AlgebraicHasher,*/ GenericConfig, PoseidonGoldilocksConfig};
|
||||
use plonky2::plonk::config::{GenericConfig, PoseidonGoldilocksConfig};
|
||||
use rand::Rng;
|
||||
use std::time;
|
||||
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
use std::process;
|
||||
mod bench{
|
||||
pub mod keccak;
|
||||
pub mod poseidon;
|
||||
pub mod sha256{
|
||||
pub mod constants;
|
||||
@ -13,6 +12,15 @@ mod bench{
|
||||
pub mod ch;
|
||||
|
||||
}
|
||||
|
||||
pub mod keccak256{
|
||||
pub mod theta;
|
||||
pub mod rho;
|
||||
pub mod pi;
|
||||
pub mod iota;
|
||||
pub mod chi;
|
||||
pub mod keccak;
|
||||
}
|
||||
}
|
||||
|
||||
mod arithmetic {
|
||||
@ -22,7 +30,7 @@ mod arithmetic {
|
||||
}
|
||||
|
||||
use bench::poseidon::poseidon_bench;
|
||||
use bench::keccak::keccak_bench;
|
||||
use bench::keccak256::keccak::keccak_bench;
|
||||
use bench::sha256::sha::sha256_bench;
|
||||
|
||||
fn main() {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user