decaf377/fields/fr/u64/
wrapper.rs1use ark_ed_on_bls12_377::Fr as ArkworksFr;
2use ark_ff::{biginteger::BigInt, Field, PrimeField};
3use ark_serialize::CanonicalSerialize;
4
5use super::super::{N_64, N_8};
6
7const N: usize = N_64;
8
9#[derive(Copy, Clone)]
10pub struct Fr(ArkworksFr);
11
12impl PartialEq for Fr {
13 fn eq(&self, other: &Self) -> bool {
14 self.0 == other.0
15 }
16}
17
18impl Eq for Fr {}
19
20impl zeroize::Zeroize for Fr {
21 fn zeroize(&mut self) {
22 self.0 .0.zeroize()
23 }
24}
25
26impl Fr {
27 pub(crate) fn from_le_limbs(limbs: [u64; N_64]) -> Fr {
28 let mut bytes = [0u8; N_8];
29 for i in 0..N_64 {
30 let this_byte = limbs[i].to_le_bytes();
31 for j in 0..8 {
32 bytes[8 * i + j] = this_byte[j];
33 }
34 }
35
36 Self::from_raw_bytes(&bytes)
37 }
38
39 pub(crate) fn from_raw_bytes(bytes: &[u8; N_8]) -> Fr {
40 Self(ArkworksFr::from_le_bytes_mod_order(bytes))
41 }
42
43 pub(crate) fn to_le_limbs(&self) -> [u64; N_64] {
44 let le_bytes = self.to_bytes_le();
45 let mut out = [0u64; N_64];
46 for i in 0..N_64 {
47 out[i] = u64::from_le_bytes([
48 le_bytes[8 * i],
49 le_bytes[8 * i + 1],
50 le_bytes[8 * i + 2],
51 le_bytes[8 * i + 3],
52 le_bytes[8 * i + 4],
53 le_bytes[8 * i + 5],
54 le_bytes[8 * i + 6],
55 le_bytes[8 * i + 7],
56 ]);
57 }
58 out
59 }
60
61 pub fn to_bytes_le(&self) -> [u8; N_8] {
62 let mut bytes = [0u8; 32];
63 self.0
64 .serialize_compressed(&mut bytes[..])
65 .expect("serialization into array should be infallible");
66 bytes
67 }
68
69 pub(crate) const fn from_montgomery_limbs(limbs: [u64; N]) -> Fr {
70 Self(ArkworksFr::new_unchecked(BigInt::new(limbs)))
71 }
72
73 pub const ZERO: Self = Self(ArkworksFr::new(BigInt::new([0; N])));
74 pub const ONE: Self = Self(ArkworksFr::new(BigInt::one()));
75
76 pub fn square(&self) -> Fr {
77 Fr(self.0.square())
78 }
79
80 pub fn inverse(&self) -> Option<Fr> {
81 if self == &Self::ZERO {
82 return None;
83 }
84
85 Some(Fr(self.0.inverse()?))
86 }
87
88 pub fn add(self, other: &Fr) -> Fr {
89 Fr(self.0 + other.0)
90 }
91
92 pub fn sub(self, other: &Fr) -> Fr {
93 Fr(self.0 - other.0)
94 }
95
96 pub fn mul(self, other: &Fr) -> Fr {
97 Fr(self.0 * other.0)
98 }
99
100 pub fn neg(self) -> Fr {
101 Fr(-self.0)
102 }
103}