Skip to main content

p384/arithmetic/
field.rs

1//! Field arithmetic modulo p = 2^{384} − 2^{128} − 2^{96} + 2^{32} − 1
2//!
3//! Arithmetic implementations have been synthesized using fiat-crypto.
4//!
5//! # License
6//!
7//! Copyright (c) 2015-2020 the fiat-crypto authors
8//!
9//! fiat-crypto is distributed under the terms of the MIT License, the
10//! Apache License (Version 2.0), and the BSD 1-Clause License;
11//! users may pick which license to apply.
12
13use elliptic_curve::{
14    bigint::{U384, cpubits},
15    ff::PrimeField,
16    ops::BatchInvert,
17    subtle::{Choice, ConstantTimeEq, CtOption},
18};
19
20// Default backend: fiat-crypto
21cpubits! {
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
32/// Constant representing the modulus
33/// p = 2^{384} − 2^{128} − 2^{96} + 2^{32} − 1
34const 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}