1use super::{
16 elem::{binary_op, binary_op_assign},
17 elem_sqr_mul, elem_sqr_mul_acc, Modulus, *,
18};
19use core::marker::PhantomData;
20
21macro_rules! p384_limbs {
22 [$($limb:expr),+] => {
23 limbs![$($limb),+]
24 };
25}
26
27pub static COMMON_OPS: CommonOps = CommonOps {
28 num_limbs: 384 / LIMB_BITS,
29
30 q: Modulus {
31 p: p384_limbs![
32 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xfffffffe, 0xffffffff, 0xffffffff,
33 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff
34 ],
35 rr: p384_limbs![1, 0xfffffffe, 0, 2, 0, 0xfffffffe, 0, 2, 1, 0, 0, 0],
36 },
37 n: Elem {
38 limbs: p384_limbs![
39 0xccc52973, 0xecec196a, 0x48b0a77a, 0x581a0db2, 0xf4372ddf, 0xc7634d81, 0xffffffff,
40 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff
41 ],
42 m: PhantomData,
43 encoding: PhantomData, },
45
46 a: Elem {
47 limbs: p384_limbs![
48 0xfffffffc, 0x00000003, 0x00000000, 0xfffffffc, 0xfffffffb, 0xffffffff, 0xffffffff,
49 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff
50 ],
51 m: PhantomData,
52 encoding: PhantomData, },
54 b: Elem {
55 limbs: p384_limbs![
56 0x9d412dcc, 0x08118871, 0x7a4c32ec, 0xf729add8, 0x1920022e, 0x77f2209b, 0x94938ae2,
57 0xe3374bee, 0x1f022094, 0xb62b21f4, 0x604fbff9, 0xcd08114b
58 ],
59 m: PhantomData,
60 encoding: PhantomData, },
62
63 elem_add_impl: GFp_p384_elem_add,
64 elem_mul_mont: GFp_p384_elem_mul_mont,
65 elem_sqr_mont: GFp_p384_elem_sqr_mont,
66
67 point_add_jacobian_impl: GFp_nistz384_point_add,
68};
69
70pub static PRIVATE_KEY_OPS: PrivateKeyOps = PrivateKeyOps {
71 common: &COMMON_OPS,
72 elem_inv_squared: p384_elem_inv_squared,
73 point_mul_base_impl: p384_point_mul_base_impl,
74 point_mul_impl: GFp_nistz384_point_mul,
75};
76
77fn p384_elem_inv_squared(a: &Elem<R>) -> Elem<R> {
78 #[inline]
86 fn sqr_mul(a: &Elem<R>, squarings: usize, b: &Elem<R>) -> Elem<R> {
87 elem_sqr_mul(&COMMON_OPS, a, squarings, b)
88 }
89
90 #[inline]
91 fn sqr_mul_acc(a: &mut Elem<R>, squarings: usize, b: &Elem<R>) {
92 elem_sqr_mul_acc(&COMMON_OPS, a, squarings, b)
93 }
94
95 let b_1 = &a;
96 let b_11 = sqr_mul(b_1, 1, b_1);
97 let b_111 = sqr_mul(&b_11, 1, b_1);
98 let f_11 = sqr_mul(&b_111, 3, &b_111);
99 let fff = sqr_mul(&f_11, 6, &f_11);
100 let fff_111 = sqr_mul(&fff, 3, &b_111);
101 let fffffff_11 = sqr_mul(&fff_111, 15, &fff_111);
102
103 let fffffffffffffff = sqr_mul(&fffffff_11, 30, &fffffff_11);
104
105 let ffffffffffffffffffffffffffffff = sqr_mul(&fffffffffffffff, 60, &fffffffffffffff);
106
107 let mut acc = sqr_mul(
109 &ffffffffffffffffffffffffffffff,
110 120,
111 &ffffffffffffffffffffffffffffff,
112 );
113
114 sqr_mul_acc(&mut acc, 15, &fff_111);
116
117 sqr_mul_acc(&mut acc, 1 + 30, &fffffff_11);
119 sqr_mul_acc(&mut acc, 2, &b_11);
120
121 sqr_mul_acc(&mut acc, 64 + 30, &fffffff_11);
124
125 COMMON_OPS.elem_square(&mut acc);
128 COMMON_OPS.elem_square(&mut acc);
129
130 acc
131}
132
133fn p384_point_mul_base_impl(a: &Scalar) -> Point {
134 static GENERATOR: (Elem<R>, Elem<R>) = (
136 Elem {
137 limbs: p384_limbs![
138 0x49c0b528, 0x3dd07566, 0xa0d6ce38, 0x20e378e2, 0x541b4d6e, 0x879c3afc, 0x59a30eff,
139 0x64548684, 0x614ede2b, 0x812ff723, 0x299e1513, 0x4d3aadc2
140 ],
141 m: PhantomData,
142 encoding: PhantomData,
143 },
144 Elem {
145 limbs: p384_limbs![
146 0x4b03a4fe, 0x23043dad, 0x7bb4a9ac, 0xa1bfa8bf, 0x2e83b050, 0x8bade756, 0x68f4ffd9,
147 0xc6c35219, 0x3969a840, 0xdd800226, 0x5a15c5e9, 0x2b78abc2
148 ],
149 m: PhantomData,
150 encoding: PhantomData,
151 },
152 );
153
154 PRIVATE_KEY_OPS.point_mul(a, &GENERATOR)
155}
156
157pub static PUBLIC_KEY_OPS: PublicKeyOps = PublicKeyOps {
158 common: &COMMON_OPS,
159};
160
161pub static SCALAR_OPS: ScalarOps = ScalarOps {
162 common: &COMMON_OPS,
163 scalar_inv_to_mont_impl: p384_scalar_inv_to_mont,
164 scalar_mul_mont: GFp_p384_scalar_mul_mont,
165};
166
167pub static PUBLIC_SCALAR_OPS: PublicScalarOps = PublicScalarOps {
168 scalar_ops: &SCALAR_OPS,
169 public_key_ops: &PUBLIC_KEY_OPS,
170 private_key_ops: &PRIVATE_KEY_OPS,
171
172 q_minus_n: Elem {
173 limbs: p384_limbs![
174 0x333ad68c, 0x1313e696, 0xb74f5885, 0xa7e5f24c, 0x0bc8d21f, 0x389cb27e, 0, 0, 0, 0, 0,
175 0
176 ],
177
178 m: PhantomData,
179 encoding: PhantomData, },
181};
182
183pub static PRIVATE_SCALAR_OPS: PrivateScalarOps = PrivateScalarOps {
184 scalar_ops: &SCALAR_OPS,
185
186 oneRR_mod_n: Scalar {
187 limbs: N_RR_LIMBS,
188 m: PhantomData,
189 encoding: PhantomData, },
191};
192
193fn p384_scalar_inv_to_mont(a: &Scalar<Unencoded>) -> Scalar<R> {
194 fn mul(a: &Scalar<R>, b: &Scalar<R>) -> Scalar<R> {
205 binary_op(GFp_p384_scalar_mul_mont, a, b)
206 }
207
208 fn sqr(a: &Scalar<R>) -> Scalar<R> {
209 binary_op(GFp_p384_scalar_mul_mont, a, a)
210 }
211
212 fn sqr_mut(a: &mut Scalar<R>) {
213 unary_op_from_binary_op_assign(GFp_p384_scalar_mul_mont, a);
214 }
215
216 fn sqr_mul(a: &Scalar<R>, squarings: usize, b: &Scalar<R>) -> Scalar<R> {
218 debug_assert!(squarings >= 1);
219 let mut tmp = sqr(a);
220 for _ in 1..squarings {
221 sqr_mut(&mut tmp);
222 }
223 mul(&tmp, b)
224 }
225
226 fn sqr_mul_acc(acc: &mut Scalar<R>, squarings: usize, b: &Scalar<R>) {
228 debug_assert!(squarings >= 1);
229 for _ in 0..squarings {
230 sqr_mut(acc);
231 }
232 binary_op_assign(GFp_p384_scalar_mul_mont, acc, b)
233 }
234
235 fn to_mont(a: &Scalar<Unencoded>) -> Scalar<R> {
236 static N_RR: Scalar<Unencoded> = Scalar {
237 limbs: N_RR_LIMBS,
238 m: PhantomData,
239 encoding: PhantomData,
240 };
241 binary_op(GFp_p384_scalar_mul_mont, a, &N_RR)
242 }
243
244 const B_1: usize = 0;
246 const B_11: usize = 1;
247 const B_101: usize = 2;
248 const B_111: usize = 3;
249 const B_1001: usize = 4;
250 const B_1011: usize = 5;
251 const B_1101: usize = 6;
252 const B_1111: usize = 7;
253 const DIGIT_COUNT: usize = 8;
254
255 let mut d = [Scalar::zero(); DIGIT_COUNT];
256 d[B_1] = to_mont(a);
257 let b_10 = sqr(&d[B_1]);
258 for i in B_11..DIGIT_COUNT {
259 d[i] = mul(&d[i - 1], &b_10);
260 }
261
262 let ff = sqr_mul(&d[B_1111], 0 + 4, &d[B_1111]);
263 let ffff = sqr_mul(&ff, 0 + 8, &ff);
264 let ffffffff = sqr_mul(&ffff, 0 + 16, &ffff);
265
266 let ffffffffffffffff = sqr_mul(&ffffffff, 0 + 32, &ffffffff);
267
268 let ffffffffffffffffffffffff = sqr_mul(&ffffffffffffffff, 0 + 32, &ffffffff);
269
270 let mut acc = sqr_mul(&ffffffffffffffffffffffff, 0 + 96, &ffffffffffffffffffffffff);
272
273 static REMAINING_WINDOWS: [(u8, u8); 39] = [
280 (2, B_11 as u8),
281 (3 + 3, B_111 as u8),
282 (1 + 2, B_11 as u8),
283 (3 + 2, B_11 as u8),
284 (1 + 4, B_1001 as u8),
285 (4, B_1011 as u8),
286 (6 + 4, B_1111 as u8),
287 (3, B_101 as u8),
288 (4 + 1, B_1 as u8),
289 (4, B_1011 as u8),
290 (4, B_1001 as u8),
291 (1 + 4, B_1101 as u8),
292 (4, B_1101 as u8),
293 (4, B_1111 as u8),
294 (1 + 4, B_1011 as u8),
295 (6 + 4, B_1101 as u8),
296 (5 + 4, B_1101 as u8),
297 (4, B_1011 as u8),
298 (2 + 4, B_1001 as u8),
299 (2 + 1, B_1 as u8),
300 (3 + 4, B_1011 as u8),
301 (4 + 3, B_101 as u8),
302 (2 + 3, B_111 as u8),
303 (1 + 4, B_1111 as u8),
304 (1 + 4, B_1011 as u8),
305 (4, B_1011 as u8),
306 (2 + 3, B_111 as u8),
307 (1 + 2, B_11 as u8),
308 (5 + 2, B_11 as u8),
309 (2 + 4, B_1011 as u8),
310 (1 + 3, B_101 as u8),
311 (1 + 2, B_11 as u8),
312 (2 + 2, B_11 as u8),
313 (2 + 2, B_11 as u8),
314 (3 + 3, B_101 as u8),
315 (2 + 3, B_101 as u8),
316 (2 + 3, B_101 as u8),
317 (2, B_11 as u8),
318 (3 + 1, B_1 as u8),
319 ];
320
321 for &(squarings, digit) in &REMAINING_WINDOWS[..] {
322 sqr_mul_acc(&mut acc, usize::from(squarings), &d[usize::from(digit)]);
323 }
324
325 acc
326}
327
328unsafe extern "C" fn GFp_p384_elem_sqr_mont(
329 r: *mut Limb, a: *const Limb, ) {
332 GFp_p384_elem_mul_mont(r, a, a);
334}
335
336const N_RR_LIMBS: [Limb; MAX_LIMBS] = p384_limbs![
337 0x19b409a9, 0x2d319b24, 0xdf1aa419, 0xff3d81e5, 0xfcb82947, 0xbc3e483a, 0x4aab1cc5, 0xd40d4917,
338 0x28266895, 0x3fb05b7a, 0x2b39bf21, 0x0c84ee01
339];
340
341extern "C" {
342 fn GFp_p384_elem_add(
343 r: *mut Limb, a: *const Limb, b: *const Limb, );
347 fn GFp_p384_elem_mul_mont(
348 r: *mut Limb, a: *const Limb, b: *const Limb, );
352
353 fn GFp_nistz384_point_add(
354 r: *mut Limb, a: *const Limb, b: *const Limb, );
358 fn GFp_nistz384_point_mul(
359 r: *mut Limb, p_scalar: *const Limb, p_x: *const Limb, p_y: *const Limb, );
364
365 fn GFp_p384_scalar_mul_mont(
366 r: *mut Limb, a: *const Limb, b: *const Limb, );
370}