1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
// SPDX-License-Identifier: GPL-3.0-or-later
use crate::{FBAlgo, FBObj, FieldOps, Packing, WrappingOps};
use crypto_bigint::{Limb, NonZero, U128};

/// [`FBObj`] with a block size of 128 bits.
pub type FB128 = FBObj<U128>;

const PRIME_POS_VAL: u16 = 159;
const PRIME: U128 = U128::MAX.wrapping_sub(&U128::from_u16(PRIME_POS_VAL-1));
const PRIME_POS: Limb = Limb::from_u16(PRIME_POS_VAL);

impl FBAlgo<U128> for FBObj<U128> {
	const MODULUS: NonZero<U128> = NonZero::<U128>::const_new(PRIME).0;
}

impl FieldOps for U128 {
	fn field_add(&self, rhs: &Self) -> Self {
		self.add_mod_special(rhs, PRIME_POS)
	}
	fn field_sub(&self, rhs: &Self) -> Self {
		self.sub_mod_special(rhs, PRIME_POS)
	}
	fn field_mul(&self, rhs: &Self) -> Self {
		self.mul_mod_special(rhs, PRIME_POS)
	}
	fn field_inv(&self) -> Self {
		self.inv_odd_mod(&PRIME).0
	}
}

impl Packing for U128 {
	const R_BOUND: U128 = PRIME.wrapping_sub(&U128::ONE);
}

impl WrappingOps for U128 {
	fn wrapping_add(&self, rhs: &U128) -> U128 {
		self.wrapping_add(rhs)
	}
	fn wrapping_sub(&self, rhs: &U128) -> U128 {
		self.wrapping_sub(rhs)
	}
}