Skip to content

Commit 72f0de7

Browse files
committed
gf2x512 for faster committing time
1 parent 27328b2 commit 72f0de7

File tree

18 files changed

+1288
-106
lines changed

18 files changed

+1288
-106
lines changed

arith/gf2/src/gf2.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Galios field over 2^128
1+
// Galois field over 2^128
22
// credit to intel for the original implementation
33
// https://www.intel.com/content/dam/develop/external/us/en/documents/clmul-wp-rev-2-02-2014-04-20.pdf
44

@@ -43,7 +43,7 @@ impl FieldSerde for GF2 {
4343
impl Field for GF2 {
4444
// still will pack 8 bits into a u8
4545

46-
const NAME: &'static str = "Galios Field 2";
46+
const NAME: &'static str = "Galois Field 2";
4747

4848
const SIZE: usize = 1;
4949

arith/gf2/src/gf2x128.rs

+44
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
use std::mem::transmute;
2+
3+
use arith::{Field, SimdField};
4+
5+
use crate::{GF2x64, GF2};
6+
17
#[cfg(target_arch = "x86_64")]
28
mod avx;
39
#[cfg(target_arch = "x86_64")]
@@ -7,3 +13,41 @@ pub type GF2x128 = avx::AVXGF2x128;
713
mod neon;
814
#[cfg(target_arch = "aarch64")]
915
pub type GF2x128 = neon::NeonGF2x128;
16+
17+
impl SimdField for GF2x128 {
18+
type Scalar = GF2;
19+
20+
const PACK_SIZE: usize = 128;
21+
22+
#[inline(always)]
23+
fn scale(&self, challenge: &Self::Scalar) -> Self {
24+
if challenge.v == 0 {
25+
<Self as Field>::ZERO
26+
} else {
27+
*self
28+
}
29+
}
30+
31+
#[inline(always)]
32+
fn pack(base_vec: &[Self::Scalar]) -> Self {
33+
assert_eq!(base_vec.len(), Self::PACK_SIZE);
34+
let mut packed_to_gf2x64 = [GF2x64::ZERO; Self::PACK_SIZE / GF2x64::PACK_SIZE];
35+
packed_to_gf2x64
36+
.iter_mut()
37+
.zip(base_vec.chunks(GF2x64::PACK_SIZE))
38+
.for_each(|(gf2x64, pack)| *gf2x64 = GF2x64::pack(pack));
39+
40+
unsafe { transmute(packed_to_gf2x64) }
41+
}
42+
43+
#[inline(always)]
44+
fn unpack(&self) -> Vec<Self::Scalar> {
45+
let packed_to_gf2x64: [GF2x64; Self::PACK_SIZE / GF2x64::PACK_SIZE] =
46+
unsafe { transmute(*self) };
47+
48+
packed_to_gf2x64
49+
.iter()
50+
.flat_map(|packed| packed.unpack())
51+
.collect()
52+
}
53+
}

arith/gf2/src/gf2x128/avx.rs

+3-41
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ use std::{
44
ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign},
55
};
66

7-
use arith::{Field, FieldSerde, FieldSerdeResult, SimdField};
7+
use arith::{Field, FieldSerde, FieldSerdeResult};
88

9-
use crate::{GF2x64, GF2};
9+
use crate::GF2;
1010

1111
#[derive(Debug, Clone, Copy)]
1212
pub struct AVXGF2x128 {
@@ -48,7 +48,7 @@ impl FieldSerde for AVXGF2x128 {
4848
}
4949

5050
impl Field for AVXGF2x128 {
51-
const NAME: &'static str = "Galios Field 2 SIMD 128";
51+
const NAME: &'static str = "AVX Galois Field 2 SIMD 128";
5252

5353
const SIZE: usize = 128 / 8;
5454

@@ -314,41 +314,3 @@ impl From<GF2> for AVXGF2x128 {
314314
}
315315
}
316316
}
317-
318-
impl SimdField for AVXGF2x128 {
319-
type Scalar = GF2;
320-
321-
const PACK_SIZE: usize = 128;
322-
323-
#[inline(always)]
324-
fn scale(&self, challenge: &Self::Scalar) -> Self {
325-
if challenge.v == 0 {
326-
Self::ZERO
327-
} else {
328-
*self
329-
}
330-
}
331-
332-
#[inline(always)]
333-
fn pack(base_vec: &[Self::Scalar]) -> Self {
334-
assert_eq!(base_vec.len(), Self::PACK_SIZE);
335-
let mut packed_to_gf2x64 = [GF2x64::ZERO; Self::PACK_SIZE / GF2x64::PACK_SIZE];
336-
packed_to_gf2x64
337-
.iter_mut()
338-
.zip(base_vec.chunks(GF2x64::PACK_SIZE))
339-
.for_each(|(gf2x64, pack)| *gf2x64 = GF2x64::pack(pack));
340-
341-
unsafe { transmute(packed_to_gf2x64) }
342-
}
343-
344-
#[inline(always)]
345-
fn unpack(&self) -> Vec<Self::Scalar> {
346-
let packed_to_gf2x64: [GF2x64; Self::PACK_SIZE / GF2x64::PACK_SIZE] =
347-
unsafe { transmute(*self) };
348-
349-
packed_to_gf2x64
350-
.iter()
351-
.flat_map(|packed| packed.unpack())
352-
.collect()
353-
}
354-
}

arith/gf2/src/gf2x128/neon.rs

+3-41
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ use std::{
44
ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign},
55
};
66

7-
use arith::{Field, FieldSerde, FieldSerdeResult, SimdField};
7+
use arith::{Field, FieldSerde, FieldSerdeResult};
88

9-
use crate::{GF2x64, GF2};
9+
use crate::GF2;
1010

1111
#[derive(Clone, Copy, Debug)]
1212
pub struct NeonGF2x128 {
@@ -49,7 +49,7 @@ impl FieldSerde for NeonGF2x128 {
4949
}
5050

5151
impl Field for NeonGF2x128 {
52-
const NAME: &'static str = "Galios Field 2 SIMD 128";
52+
const NAME: &'static str = "Neon Galois Field 2 SIMD 128";
5353

5454
const SIZE: usize = 128 / 8;
5555

@@ -317,41 +317,3 @@ impl From<GF2> for NeonGF2x128 {
317317
}
318318
}
319319
}
320-
321-
impl SimdField for NeonGF2x128 {
322-
type Scalar = GF2;
323-
324-
const PACK_SIZE: usize = 128;
325-
326-
#[inline(always)]
327-
fn scale(&self, challenge: &Self::Scalar) -> Self {
328-
if challenge.v == 0 {
329-
Self::ZERO
330-
} else {
331-
*self
332-
}
333-
}
334-
335-
#[inline(always)]
336-
fn pack(base_vec: &[Self::Scalar]) -> Self {
337-
assert_eq!(base_vec.len(), Self::PACK_SIZE);
338-
let mut packed_to_gf2x64 = [GF2x64::ZERO; Self::PACK_SIZE / GF2x64::PACK_SIZE];
339-
packed_to_gf2x64
340-
.iter_mut()
341-
.zip(base_vec.chunks(GF2x64::PACK_SIZE))
342-
.for_each(|(gf2x64, pack)| *gf2x64 = GF2x64::pack(pack));
343-
344-
unsafe { transmute(packed_to_gf2x64) }
345-
}
346-
347-
#[inline(always)]
348-
fn unpack(&self) -> Vec<Self::Scalar> {
349-
let packed_to_gf2x64: [GF2x64; Self::PACK_SIZE / GF2x64::PACK_SIZE] =
350-
unsafe { transmute(*self) };
351-
352-
packed_to_gf2x64
353-
.iter()
354-
.flat_map(|packed| packed.unpack())
355-
.collect()
356-
}
357-
}

arith/gf2/src/gf2x512.rs

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
use std::mem::transmute;
2+
3+
use arith::{Field, SimdField};
4+
5+
use crate::{GF2x64, GF2};
6+
7+
#[cfg(target_arch = "aarch64")]
8+
mod neon;
9+
#[cfg(target_arch = "aarch64")]
10+
pub type GF2x512 = neon::NeonGF2x512;
11+
12+
#[cfg(all(target_arch = "x86_64", target_feature = "avx512f"))]
13+
mod avx512;
14+
#[cfg(all(target_arch = "x86_64", target_feature = "avx512f"))]
15+
pub type GF2x512 = avx512::AVX512GF2x512;
16+
17+
// Fallback, use avx2
18+
#[cfg(all(target_arch = "x86_64", not(target_feature = "avx512f")))]
19+
mod avx256;
20+
#[cfg(all(target_arch = "x86_64", not(target_feature = "avx512f")))]
21+
pub type GF2x512 = avx256::AVX256GF2x512;
22+
23+
impl SimdField for GF2x512 {
24+
type Scalar = GF2;
25+
26+
const PACK_SIZE: usize = 512;
27+
28+
#[inline(always)]
29+
fn scale(&self, challenge: &Self::Scalar) -> Self {
30+
if challenge.v == 0 {
31+
<Self as Field>::ZERO
32+
} else {
33+
*self
34+
}
35+
}
36+
37+
#[inline(always)]
38+
fn pack(base_vec: &[Self::Scalar]) -> Self {
39+
assert_eq!(base_vec.len(), Self::PACK_SIZE);
40+
let mut packed_to_gf2x64 = [GF2x64::ZERO; Self::PACK_SIZE / GF2x64::PACK_SIZE];
41+
packed_to_gf2x64
42+
.iter_mut()
43+
.zip(base_vec.chunks(GF2x64::PACK_SIZE))
44+
.for_each(|(gf2x64, pack)| *gf2x64 = GF2x64::pack(pack));
45+
46+
unsafe { transmute(packed_to_gf2x64) }
47+
}
48+
49+
#[inline(always)]
50+
fn unpack(&self) -> Vec<Self::Scalar> {
51+
let packed_to_gf2x64: [GF2x64; Self::PACK_SIZE / GF2x64::PACK_SIZE] =
52+
unsafe { transmute(*self) };
53+
54+
packed_to_gf2x64
55+
.iter()
56+
.flat_map(|packed| packed.unpack())
57+
.collect()
58+
}
59+
}

0 commit comments

Comments
 (0)