Skip to content

Commit

Permalink
merge merkle hash changes
Browse files Browse the repository at this point in the history
  • Loading branch information
tamirhemo committed Feb 26, 2024
2 parents b6f8bb0 + 16b590d commit 62ffb17
Show file tree
Hide file tree
Showing 50 changed files with 1,039 additions and 471 deletions.
6 changes: 1 addition & 5 deletions baby-bear/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,7 @@ rand_chacha = "0.3.1"
serde_json = "1.0.113"

[[bench]]
name = "inverse"
harness = false

[[bench]]
name = "root_7"
name = "bench_field"
harness = false

[[bench]]
Expand Down
37 changes: 37 additions & 0 deletions baby-bear/benches/bench_field.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
use criterion::{criterion_group, criterion_main, BatchSize, Criterion};
use p3_baby_bear::BabyBear;
use p3_field::AbstractField;
use p3_field_testing::bench_func::{
benchmark_add_latency, benchmark_add_throughput, benchmark_inv, benchmark_iter_sum,
benchmark_sub_latency, benchmark_sub_throughput,
};

type F = BabyBear;

fn bench_field(c: &mut Criterion) {
let name = "BabyBear";
const REPS: usize = 1000;
benchmark_inv::<F>(c, name);
benchmark_iter_sum::<F, 4, REPS>(c, name);
benchmark_iter_sum::<F, 8, REPS>(c, name);
benchmark_iter_sum::<F, 12, REPS>(c, name);

// Note that each round of throughput has 10 operations
// So we should have 10 * more repitions for latency tests.
const L_REPS: usize = 10 * REPS;
benchmark_add_latency::<F, L_REPS>(c, name);
benchmark_add_throughput::<F, REPS>(c, name);
benchmark_sub_latency::<F, L_REPS>(c, name);
benchmark_sub_throughput::<F, REPS>(c, name);

c.bench_function("7th_root", |b| {
b.iter_batched(
rand::random::<F>,
|x| x.exp_u64(1725656503),
BatchSize::SmallInput,
)
});
}

criterion_group!(baby_bear_arithmetic, bench_field);
criterion_main!(baby_bear_arithmetic);
18 changes: 0 additions & 18 deletions baby-bear/benches/inverse.rs

This file was deleted.

18 changes: 0 additions & 18 deletions baby-bear/benches/root_7.rs

This file was deleted.

11 changes: 7 additions & 4 deletions baby-bear/src/aarch64_neon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use core::iter::{Product, Sum};
use core::mem::transmute;
use core::ops::{Add, AddAssign, Div, Mul, MulAssign, Neg, Sub, SubAssign};

use p3_field::{AbstractField, Field, PackedField};
use p3_field::{AbstractField, Field, PackedField, PackedValue};
use rand::distributions::{Distribution, Standard};
use rand::Rng;

Expand Down Expand Up @@ -582,9 +582,8 @@ fn interleave2(v0: uint32x4_t, v1: uint32x4_t) -> (uint32x4_t, uint32x4_t) {
}
}

unsafe impl PackedField for PackedBabyBearNeon {
type Scalar = BabyBear;

unsafe impl PackedValue for PackedBabyBearNeon {
type Value = BabyBear;
const WIDTH: usize = WIDTH;

#[inline]
Expand Down Expand Up @@ -623,6 +622,10 @@ unsafe impl PackedField for PackedBabyBearNeon {
fn as_slice_mut(&mut self) -> &mut [BabyBear] {
&mut self.0[..]
}
}

unsafe impl PackedField for PackedBabyBearNeon {
type Scalar = BabyBear;

#[inline]
fn interleave(&self, other: Self, block_len: usize) -> (Self, Self) {
Expand Down
13 changes: 11 additions & 2 deletions baby-bear/src/baby_bear.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use core::iter::{Product, Sum};
use core::ops::{Add, AddAssign, Div, Mul, MulAssign, Neg, Sub, SubAssign};

use p3_field::{
exp_1725656503, exp_u64_by_squaring, AbstractField, Field, PrimeField, PrimeField32,
exp_1725656503, exp_u64_by_squaring, AbstractField, Field, Packable, PrimeField, PrimeField32,
PrimeField64, TwoAdicField,
};
use rand::distributions::{Distribution, Standard};
Expand Down Expand Up @@ -107,6 +107,8 @@ const MONTY_ONE: u32 = to_monty(1);
const MONTY_TWO: u32 = to_monty(2);
const MONTY_NEG_ONE: u32 = to_monty(P - 1);

impl Packable for BabyBear {}

impl AbstractField for BabyBear {
type F = Self;

Expand Down Expand Up @@ -335,7 +337,14 @@ impl AddAssign for BabyBear {
impl Sum for BabyBear {
#[inline]
fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
iter.reduce(|x, y| x + y).unwrap_or(Self::zero())
// This is faster than iter.reduce(|x, y| x + y).unwrap_or(Self::zero()) for iterators of length > 2.
// There might be a faster reduction method possible for lengths <= 16 which avoids %.

// This sum will not overflow so long as iter.len() < 2^33.
let sum = iter.map(|x| (x.value as u64)).sum::<u64>();
BabyBear {
value: (sum % P as u64) as u32,
}
}
}

Expand Down
4 changes: 3 additions & 1 deletion baby-bear/src/x86_64_avx2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -831,7 +831,7 @@ mod tests {
#[test]
fn test_neg_own_inverse() {
let vec = packed_from_random(0xee4df174b850a35f);
let res = --vec;
let res = -(-vec);
assert_eq!(res, vec);
}

Expand Down Expand Up @@ -1144,6 +1144,7 @@ mod tests {
let vec = PackedBabyBearAVX2(arr);
let vec_res = -vec;

#[allow(clippy::needless_range_loop)]
for i in 0..WIDTH {
assert_eq!(vec_res.0[i], -arr[i]);
}
Expand All @@ -1156,6 +1157,7 @@ mod tests {
let vec = PackedBabyBearAVX2(arr);
let vec_res = -vec;

#[allow(clippy::needless_range_loop)]
for i in 0..WIDTH {
assert_eq!(vec_res.0[i], -arr[i]);
}
Expand Down
1 change: 1 addition & 0 deletions challenger/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ license = "MIT OR Apache-2.0"

[dependencies]
p3-field = { path = "../field" }
p3-util = { path = "../util" }
p3-maybe-rayon = { path = "../maybe-rayon" }
p3-symmetric = { path = "../symmetric" }
tracing = "0.1.37"
Expand Down
15 changes: 14 additions & 1 deletion challenger/src/duplex_challenger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use alloc::vec;
use alloc::vec::Vec;

use p3_field::{ExtensionField, Field, PrimeField64};
use p3_symmetric::CryptographicPermutation;
use p3_symmetric::{CryptographicPermutation, Hash};

use crate::{CanObserve, CanSample, CanSampleBits, FieldChallenger};

Expand Down Expand Up @@ -87,6 +87,19 @@ where
}
}

impl<F, P, const N: usize, const WIDTH: usize> CanObserve<Hash<F, F, N>>
for DuplexChallenger<F, P, WIDTH>
where
F: Copy,
P: CryptographicPermutation<[F; WIDTH]>,
{
fn observe(&mut self, values: Hash<F, F, N>) {
for value in values {
self.observe(value);
}
}
}

impl<F, EF, P, const WIDTH: usize> CanSample<EF> for DuplexChallenger<F, P, WIDTH>
where
F: Field,
Expand Down
45 changes: 22 additions & 23 deletions challenger/src/hash_challenger.rs
Original file line number Diff line number Diff line change
@@ -1,28 +1,27 @@
use alloc::vec;
use alloc::vec::Vec;

use p3_field::Field;
use p3_symmetric::CryptographicHasher;

use crate::{CanObserve, CanSample};

#[derive(Clone)]
pub struct HashChallenger<F, H, const OUT_LEN: usize>
pub struct HashChallenger<T, H, const OUT_LEN: usize>
where
F: Field,
H: CryptographicHasher<F, [F; OUT_LEN]>,
T: Clone,
H: CryptographicHasher<T, [T; OUT_LEN]>,
{
input_buffer: Vec<F>,
output_buffer: Vec<F>,
input_buffer: Vec<T>,
output_buffer: Vec<T>,
hasher: H,
}

impl<F, H, const OUT_LEN: usize> HashChallenger<F, H, OUT_LEN>
impl<T, H, const OUT_LEN: usize> HashChallenger<T, H, OUT_LEN>
where
F: Field,
H: CryptographicHasher<F, [F; OUT_LEN]>,
T: Clone,
H: CryptographicHasher<T, [T; OUT_LEN]>,
{
pub fn new(initial_state: Vec<F>, hasher: H) -> Self {
pub fn new(initial_state: Vec<T>, hasher: H) -> Self {
Self {
input_buffer: initial_state,
output_buffer: vec![],
Expand All @@ -41,38 +40,38 @@ where
}
}

impl<F, H, const OUT_LEN: usize> CanObserve<F> for HashChallenger<F, H, OUT_LEN>
impl<T, H, const OUT_LEN: usize> CanObserve<T> for HashChallenger<T, H, OUT_LEN>
where
F: Field,
H: CryptographicHasher<F, [F; OUT_LEN]>,
T: Clone,
H: CryptographicHasher<T, [T; OUT_LEN]>,
{
fn observe(&mut self, value: F) {
fn observe(&mut self, value: T) {
// Any buffered output is now invalid.
self.output_buffer.clear();

self.input_buffer.push(value);
}
}

impl<F, H, const N: usize, const OUT_LEN: usize> CanObserve<[F; N]>
for HashChallenger<F, H, OUT_LEN>
impl<T, H, const N: usize, const OUT_LEN: usize> CanObserve<[T; N]>
for HashChallenger<T, H, OUT_LEN>
where
F: Field,
H: CryptographicHasher<F, [F; OUT_LEN]>,
T: Clone,
H: CryptographicHasher<T, [T; OUT_LEN]>,
{
fn observe(&mut self, values: [F; N]) {
fn observe(&mut self, values: [T; N]) {
for value in values {
self.observe(value);
}
}
}

impl<F, H, const OUT_LEN: usize> CanSample<F> for HashChallenger<F, H, OUT_LEN>
impl<T, H, const OUT_LEN: usize> CanSample<T> for HashChallenger<T, H, OUT_LEN>
where
F: Field,
H: CryptographicHasher<F, [F; OUT_LEN]>,
T: Clone,
H: CryptographicHasher<T, [T; OUT_LEN]>,
{
fn sample(&mut self) -> F {
fn sample(&mut self) -> T {
if self.output_buffer.is_empty() {
self.flush();
}
Expand Down
2 changes: 2 additions & 0 deletions challenger/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ extern crate alloc;
mod duplex_challenger;
mod grinding_challenger;
mod hash_challenger;
mod serializing_challenger;

use alloc::vec::Vec;
use core::array;
Expand All @@ -15,6 +16,7 @@ pub use duplex_challenger::*;
pub use grinding_challenger::*;
pub use hash_challenger::*;
use p3_field::{AbstractExtensionField, Field};
pub use serializing_challenger::*;

pub trait CanObserve<T> {
fn observe(&mut self, value: T);
Expand Down
Loading

0 comments on commit 62ffb17

Please sign in to comment.