mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-12 02:33:06 +00:00
* Split into crates
I kept other changes to a minimum, so 95% of this is just moving things. One complication that came up is that since `PrimeField` is now outside the plonky2 crate, these two impls now conflict:
```
impl<F: PrimeField> From<HashOut<F>> for Vec<u8> { ... }
impl<F: PrimeField> From<HashOut<F>> for Vec<F> { ... }
```
with this note:
```
note: upstream crates may add a new impl of trait `plonky2_field::field_types::PrimeField` for type `u8` in future versions
```
I worked around this by adding a `GenericHashOut` trait with methods like `to_bytes()` instead of overloading `From`/`Into`. Personally I prefer the explicitness anyway.
* Move out permutation network stuff also
* Fix imports
* Fix import
* Also move out insertion
* Comment
* fmt
* PR feedback
66 lines
2.4 KiB
Rust
66 lines
2.4 KiB
Rust
use crate::field_types::Field;
|
|
use crate::packable::Packable;
|
|
use crate::packed_field::PackedField;
|
|
|
|
fn pack_with_leftovers_split_point<P: PackedField>(slice: &[P::Scalar]) -> usize {
|
|
let n = slice.len();
|
|
let n_leftover = n % P::WIDTH;
|
|
n - n_leftover
|
|
}
|
|
|
|
fn pack_slice_with_leftovers<P: PackedField>(slice: &[P::Scalar]) -> (&[P], &[P::Scalar]) {
|
|
let split_point = pack_with_leftovers_split_point::<P>(slice);
|
|
let (slice_packable, slice_leftovers) = slice.split_at(split_point);
|
|
let slice_packed = P::pack_slice(slice_packable);
|
|
(slice_packed, slice_leftovers)
|
|
}
|
|
|
|
fn pack_slice_with_leftovers_mut<P: PackedField>(
|
|
slice: &mut [P::Scalar],
|
|
) -> (&mut [P], &mut [P::Scalar]) {
|
|
let split_point = pack_with_leftovers_split_point::<P>(slice);
|
|
let (slice_packable, slice_leftovers) = slice.split_at_mut(split_point);
|
|
let slice_packed = P::pack_slice_mut(slice_packable);
|
|
(slice_packed, slice_leftovers)
|
|
}
|
|
|
|
/// Elementwise inplace multiplication of two slices of field elements.
|
|
/// Implementation be faster than the trivial for loop.
|
|
pub fn batch_multiply_inplace<F: Field>(out: &mut [F], a: &[F]) {
|
|
let n = out.len();
|
|
assert_eq!(n, a.len(), "both arrays must have the same length");
|
|
|
|
// Split out slice of vectors, leaving leftovers as scalars
|
|
let (out_packed, out_leftovers) =
|
|
pack_slice_with_leftovers_mut::<<F as Packable>::Packing>(out);
|
|
let (a_packed, a_leftovers) = pack_slice_with_leftovers::<<F as Packable>::Packing>(a);
|
|
|
|
// Multiply packed and the leftovers
|
|
for (x_out, x_a) in out_packed.iter_mut().zip(a_packed) {
|
|
*x_out *= *x_a;
|
|
}
|
|
for (x_out, x_a) in out_leftovers.iter_mut().zip(a_leftovers) {
|
|
*x_out *= *x_a;
|
|
}
|
|
}
|
|
|
|
/// Elementwise inplace addition of two slices of field elements.
|
|
/// Implementation be faster than the trivial for loop.
|
|
pub fn batch_add_inplace<F: Field>(out: &mut [F], a: &[F]) {
|
|
let n = out.len();
|
|
assert_eq!(n, a.len(), "both arrays must have the same length");
|
|
|
|
// Split out slice of vectors, leaving leftovers as scalars
|
|
let (out_packed, out_leftovers) =
|
|
pack_slice_with_leftovers_mut::<<F as Packable>::Packing>(out);
|
|
let (a_packed, a_leftovers) = pack_slice_with_leftovers::<<F as Packable>::Packing>(a);
|
|
|
|
// Add packed and the leftovers
|
|
for (x_out, x_a) in out_packed.iter_mut().zip(a_packed) {
|
|
*x_out += *x_a;
|
|
}
|
|
for (x_out, x_a) in out_leftovers.iter_mut().zip(a_leftovers) {
|
|
*x_out += *x_a;
|
|
}
|
|
}
|