1use elliptic_curve::{
14 bigint::{U384, cpubits},
15 ff::PrimeField,
16 ops::BatchInvert,
17 subtle::{Choice, ConstantTimeEq, CtOption},
18};
19
20cpubits! {
22 32 => {
23 #[cfg(p384_backend = "fiat")]
24 use fiat_crypto::p384_32::*;
25 }
26 64 => {
27 #[cfg(p384_backend = "fiat")]
28 use fiat_crypto::p384_64::*;
29 }
30}
31
32const MODULUS_HEX: &str = "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff";
35
36primefield::monty_field_params! {
37 name: FieldParams,
38 modulus: MODULUS_HEX,
39 uint: U384,
40 byte_order: primefield::ByteOrder::BigEndian,
41 multiplicative_generator: 19,
42 doc: "Montgomery parameters for the NIST P-384 field modulus: `p = 2^{384} − 2^{128} − 2^{96} + 2^{32} − 1`."
43}
44
45primefield::monty_field_element! {
46 name: FieldElement,
47 params: FieldParams,
48 uint: U384,
49 doc: "Element in the finite field modulo `p = 2^{384} − 2^{128} − 2^{96} + 2^{32} − 1`."
50}
51
52#[cfg(not(p384_backend = "fiat"))]
53primefield::monty_field_arithmetic! {
54 name: FieldElement,
55 params: FieldParams,
56 uint: U384
57}
58
59#[cfg(p384_backend = "fiat")]
60primefield::fiat_monty_field_arithmetic! {
61 name: FieldElement,
62 params: FieldParams,
63 uint: U384,
64 non_mont: fiat_p384_non_montgomery_domain_field_element,
65 mont: fiat_p384_montgomery_domain_field_element,
66 from_mont: fiat_p384_from_montgomery,
67 to_mont: fiat_p384_to_montgomery,
68 add: fiat_p384_add,
69 sub: fiat_p384_sub,
70 mul: fiat_p384_mul,
71 neg: fiat_p384_opp,
72 square: fiat_p384_square,
73 divstep_precomp: fiat_p384_divstep_precomp,
74 divstep: fiat_p384_divstep,
75 msat: fiat_p384_msat,
76 selectnz: fiat_p384_selectznz
77}
78
79impl BatchInvert for FieldElement {}
80
81#[cfg(test)]
82mod tests {
83 use super::{FieldElement, U384};
84 #[cfg(p384_backend = "fiat")]
85 use super::{
86 FieldParams, fiat_p384_montgomery_domain_field_element, fiat_p384_msat,
87 fiat_p384_non_montgomery_domain_field_element, fiat_p384_to_montgomery,
88 };
89
90 primefield::test_primefield!(FieldElement, U384);
91
92 #[cfg(p384_backend = "fiat")]
93 primefield::test_fiat_monty_field_arithmetic!(
94 name: FieldElement,
95 params: FieldParams,
96 uint: U384,
97 non_mont: fiat_p384_non_montgomery_domain_field_element,
98 mont: fiat_p384_montgomery_domain_field_element,
99 to_mont: fiat_p384_to_montgomery,
100 msat: fiat_p384_msat
101 );
102}