zero_crypto/arithmetic/limbs/bits_384/
represent.rs

1use crate::arithmetic::bits_384::*;
2use crate::arithmetic::utils::{Bits, Naf, Nafs};
3use crate::common::Vec;
4use rand_core::RngCore;
5
6pub const fn zero() -> [u64; 6] {
7    [0; 6]
8}
9
10pub const fn one(r2: [u64; 6], p: [u64; 6], inv: u64) -> [u64; 6] {
11    to_mont_form([1, 0, 0, 0, 0, 0], r2, p, inv)
12}
13
14pub const fn from_u64(val: u64, r2: [u64; 6], p: [u64; 6], inv: u64) -> [u64; 6] {
15    to_mont_form([val, 0, 0, 0, 0, 0], r2, p, inv)
16}
17
18pub const fn from_u512(
19    limbs: [u64; 12],
20    r2: [u64; 6],
21    r3: [u64; 6],
22    p: [u64; 6],
23    inv: u64,
24) -> [u64; 6] {
25    let a = mul(
26        [limbs[0], limbs[1], limbs[2], limbs[3], limbs[4], limbs[5]],
27        r2,
28        p,
29        inv,
30    );
31    let b = mul(
32        [limbs[6], limbs[7], limbs[8], limbs[9], limbs[10], limbs[11]],
33        r3,
34        p,
35        inv,
36    );
37    add(a, b, p)
38}
39
40pub const fn to_mont_form(val: [u64; 6], r2: [u64; 6], p: [u64; 6], inv: u64) -> [u64; 6] {
41    mul(val, r2, p, inv)
42}
43
44pub fn to_bits(val: [u64; 6]) -> Bits {
45    let mut index = 384;
46    let mut bits: [u8; 384] = [0; 384];
47    for limb in val {
48        for byte in limb.to_le_bytes().iter() {
49            for i in 0..8 {
50                index -= 1;
51                bits[index] = byte >> i & 1;
52            }
53        }
54    }
55    bits.to_vec()
56}
57
58pub fn to_nafs(val: [u64; 6]) -> Nafs {
59    let mut index = 0;
60    let mut bits: [u8; 386] = [0; 386];
61    for limb in val {
62        for byte in limb.to_le_bytes().iter() {
63            for i in 0..8 {
64                bits[index] = byte >> i & 1;
65                index += 1;
66            }
67        }
68    }
69    let mut carry = 0;
70    let mut nafs: Vec<Naf> = bits
71        .iter()
72        .map(|bit| {
73            let triple = bit * 3;
74            let bit_3 = (triple + carry) % 2;
75            carry = (triple + carry) / 2;
76            (bit_3 as i8 - *bit as i8).into()
77        })
78        .collect::<Vec<_>>()
79        .into_iter()
80        .rev()
81        .skip_while(|x| x == &Naf::Zero)
82        .collect::<Vec<_>>();
83    nafs.pop();
84    nafs.reverse();
85    nafs
86}
87
88pub fn random_limbs(
89    mut rand: impl RngCore,
90    r2: [u64; 6],
91    r3: [u64; 6],
92    p: [u64; 6],
93    inv: u64,
94) -> [u64; 6] {
95    from_u512(
96        [
97            rand.next_u64(),
98            rand.next_u64(),
99            rand.next_u64(),
100            rand.next_u64(),
101            rand.next_u64(),
102            rand.next_u64(),
103            rand.next_u64(),
104            rand.next_u64(),
105            rand.next_u64(),
106            rand.next_u64(),
107            rand.next_u64(),
108            rand.next_u64(),
109        ],
110        r2,
111        r3,
112        p,
113        inv,
114    )
115}
116
117pub const fn little_fermat(p: [u64; 6]) -> [u64; 6] {
118    sub(zero(), [2, 0, 0, 0, 0, 0], p)
119}