Skip to main content

p384/
lib.rs

1#![no_std]
2#![cfg_attr(docsrs, feature(doc_cfg))]
3#![doc(
4    html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg",
5    html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg"
6)]
7#![forbid(unsafe_code)]
8#![warn(missing_docs, rust_2018_idioms, unused_qualifications)]
9#![doc = include_str!("../README.md")]
10
11//! ## Backends
12//!
13//! This crate has support for two different field arithmetic backends which can be selected using
14//! `cfg(p384_backend)`, e.g. to select the formally verified `fiat` backend:
15//!
16//! ```console
17//! $ RUSTFLAGS='--cfg p384_backend="fiat"' cargo test
18//! ```
19//!
20//! Or it can be set through [`.cargo/config`][buildrustflags]:
21//!
22//! ```toml
23//! [build]
24//! rustflags = ['--cfg', 'p384_backend="fiat"']
25//! ```
26//!
27//! The available backends are:
28//! - `bigint` (default): backend provided by [crypto-bigint], which should provide better
29//!   performance as well as smaller code size and fewer dependencies, but isn't formally verified
30//!   and may contain bugs
31//! - `fiat`: formally verified implementation synthesized by [fiat-crypto] which should
32//!   be correct for all inputs (though there's a possibility of bugs in the code which glues to it)
33//!
34//! [buildrustflags]: https://doc.rust-lang.org/cargo/reference/config.html#buildrustflags
35//! [crypto-bigint]: https://github.com/RustCrypto/crypto-bigint
36//! [fiat-crypto]: https://github.com/mit-plv/fiat-crypto
37//!
38//! ## `serde` support
39//!
40//! When the `serde` feature of this crate is enabled, `Serialize` and
41//! `Deserialize` are impl'd for the following types:
42//!
43//! - [`AffinePoint`]
44//! - [`ProjectivePoint`]
45//! - [`Scalar`]
46//! - [`ecdsa::VerifyingKey`]
47//!
48//! Please see type-specific documentation for more information.
49
50#[cfg(feature = "ecdh")]
51pub mod ecdh;
52#[cfg(feature = "ecdsa-core")]
53pub mod ecdsa;
54#[cfg(any(feature = "test-vectors", test))]
55pub mod test_vectors;
56
57#[cfg(feature = "arithmetic")]
58mod arithmetic;
59
60pub use elliptic_curve::{
61    self,
62    bigint::{Odd, U384},
63    consts::U48,
64};
65
66#[cfg(feature = "arithmetic")]
67pub use arithmetic::{AffinePoint, ProjectivePoint, scalar::Scalar};
68#[cfg(feature = "pkcs8")]
69pub use elliptic_curve::pkcs8;
70#[cfg(feature = "hash2curve")]
71pub use hash2curve;
72
73use elliptic_curve::{array::Array, consts::U49};
74
75/// Order of NIST P-384's elliptic curve group (i.e. scalar modulus) in hexadecimal.
76const ORDER_HEX: &str = "ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52973";
77
78/// NIST P-384 elliptic curve.
79#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, PartialOrd, Ord)]
80pub struct NistP384;
81
82impl elliptic_curve::Curve for NistP384 {
83    /// 48-byte serialized field elements.
84    type FieldBytesSize = U48;
85
86    /// 384-bit integer type used for internally representing field elements.
87    type Uint = U384;
88
89    /// Order of NIST P-384's elliptic curve group (i.e. scalar modulus).
90    const ORDER: Odd<U384> = Odd::<U384>::from_be_hex(ORDER_HEX);
91}
92
93impl elliptic_curve::PrimeCurve for NistP384 {}
94
95impl elliptic_curve::point::PointCompression for NistP384 {
96    /// NIST P-384 points are typically uncompressed.
97    const COMPRESS_POINTS: bool = false;
98}
99
100impl elliptic_curve::point::PointCompaction for NistP384 {
101    /// NIST P-384 points are typically uncompressed.
102    const COMPACT_POINTS: bool = false;
103}
104
105#[cfg(feature = "pkcs8")]
106impl pkcs8::AssociatedOid for NistP384 {
107    const OID: pkcs8::ObjectIdentifier = pkcs8::ObjectIdentifier::new_unwrap("1.3.132.0.34");
108}
109
110/// Compressed SEC1-encoded NIST P-384 curve point.
111pub type CompressedPoint = Array<u8, U49>;
112
113/// NIST P-384 SEC1 encoded point.
114pub type Sec1Point = elliptic_curve::sec1::Sec1Point<NistP384>;
115
116/// NIST P-384 field element serialized as bytes.
117///
118/// Byte array containing a serialized field element value (base field or
119/// scalar).
120pub type FieldBytes = elliptic_curve::FieldBytes<NistP384>;
121
122/// Non-zero NIST P-384 scalar field element.
123#[cfg(feature = "arithmetic")]
124pub type NonZeroScalar = elliptic_curve::NonZeroScalar<NistP384>;
125
126/// NIST P-384 public key.
127#[cfg(feature = "arithmetic")]
128pub type PublicKey = elliptic_curve::PublicKey<NistP384>;
129
130/// NIST P-384 secret key.
131pub type SecretKey = elliptic_curve::SecretKey<NistP384>;
132
133#[cfg(not(feature = "arithmetic"))]
134impl elliptic_curve::sec1::ValidatePublicKey for NistP384 {}
135
136#[cfg(feature = "oprf")]
137impl hash2curve::OprfParameters for NistP384 {
138    /// See <https://www.rfc-editor.org/rfc/rfc9497.html#section-4.4-1>.
139    const ID: &'static [u8] = b"P384-SHA384";
140}