p256/lib.rs
1#![no_std]
2#![cfg_attr(docsrs, feature(doc_cfg))]
3#![doc = include_str!("../README.md")]
4#![doc(
5 html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg",
6 html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg"
7)]
8#![forbid(unsafe_code)]
9#![warn(
10 clippy::mod_module_files,
11 clippy::unwrap_used,
12 missing_docs,
13 rust_2018_idioms,
14 unused_lifetimes,
15 unused_qualifications
16)]
17
18//! ## `serde` support
19//!
20//! When the `serde` feature of this crate is enabled, `Serialize` and
21//! `Deserialize` are impl'd for the following types:
22//!
23//! - [`AffinePoint`]
24//! - [`ProjectivePoint`]
25//! - [`Scalar`]
26//! - [`ecdsa::VerifyingKey`]
27//!
28//! Please see type-specific documentation for more information.
29
30#[cfg(feature = "ecdh")]
31pub mod ecdh;
32#[cfg(feature = "ecdsa-core")]
33pub mod ecdsa;
34#[cfg(any(feature = "test-vectors", test))]
35pub mod test_vectors;
36
37#[cfg(feature = "arithmetic")]
38mod arithmetic;
39
40pub use elliptic_curve::{self, bigint::U256, consts::U32};
41
42#[cfg(feature = "arithmetic")]
43pub use arithmetic::{AffinePoint, ProjectivePoint, scalar::Scalar};
44#[cfg(feature = "pkcs8")]
45pub use elliptic_curve::pkcs8;
46#[cfg(feature = "hash2curve")]
47pub use hash2curve;
48
49use elliptic_curve::{array::Array, bigint::Odd, consts::U33};
50
51/// Order of NIST P-256's elliptic curve group (i.e. scalar modulus) serialized
52/// as hexadecimal.
53///
54/// ```text
55/// n = FFFFFFFF 00000000 FFFFFFFF FFFFFFFF BCE6FAAD A7179E84 F3B9CAC2 FC632551
56/// ```
57///
58/// # Calculating the order
59/// One way to calculate the order is with `GP/PARI`:
60///
61/// ```text
62/// p = (2^224) * (2^32 - 1) + 2^192 + 2^96 - 1
63/// b = 41058363725152142129326129780047268409114441015993725554835256314039467401291
64/// E = ellinit([Mod(-3, p), Mod(b, p)])
65/// default(parisize, 120000000)
66/// n = ellsea(E)
67/// isprime(n)
68/// ```
69const ORDER_HEX: &str = "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551";
70
71/// NIST P-256 elliptic curve.
72///
73/// This curve is also known as prime256v1 (ANSI X9.62) and secp256r1 (SECG)
74/// and is specified in [NIST SP 800-186]:
75/// Recommendations for Discrete Logarithm-based Cryptography:
76/// Elliptic Curve Domain Parameters.
77///
78/// It's included in the US National Security Agency's "Suite B" and is widely
79/// used in protocols like TLS and the associated X.509 PKI.
80///
81/// Its equation is `y² = x³ - 3x + b` over a ~256-bit prime field where `b` is
82/// the "verifiably random"† constant:
83///
84/// ```text
85/// b = 41058363725152142129326129780047268409114441015993725554835256314039467401291
86/// ```
87///
88/// † *NOTE: the specific origins of this constant have never been fully disclosed
89/// (it is the SHA-1 digest of an unknown NSA-selected constant)*
90///
91/// [NIST SP 800-186]: https://csrc.nist.gov/publications/detail/sp/800-186/final
92#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, PartialOrd, Ord)]
93pub struct NistP256;
94
95impl elliptic_curve::Curve for NistP256 {
96 /// 32-byte serialized field elements.
97 type FieldBytesSize = U32;
98
99 /// 256-bit integer type used for internally representing field elements.
100 type Uint = U256;
101
102 /// Order of NIST P-256's elliptic curve group (i.e. scalar modulus).
103 const ORDER: Odd<U256> = Odd::<U256>::from_be_hex(ORDER_HEX);
104}
105
106impl elliptic_curve::PrimeCurve for NistP256 {}
107
108impl elliptic_curve::point::PointCompression for NistP256 {
109 /// NIST P-256 points are typically uncompressed.
110 const COMPRESS_POINTS: bool = false;
111}
112
113impl elliptic_curve::point::PointCompaction for NistP256 {
114 /// NIST P-256 points are typically uncompressed.
115 const COMPACT_POINTS: bool = false;
116}
117
118#[cfg(feature = "pkcs8")]
119impl pkcs8::AssociatedOid for NistP256 {
120 const OID: pkcs8::ObjectIdentifier = pkcs8::ObjectIdentifier::new_unwrap("1.2.840.10045.3.1.7");
121}
122
123/// Blinded scalar.
124#[cfg(feature = "arithmetic")]
125pub type BlindedScalar = elliptic_curve::scalar::BlindedScalar<NistP256>;
126
127/// Compressed SEC1-encoded NIST P-256 curve point.
128pub type CompressedPoint = Array<u8, U33>;
129
130/// NIST P-256 SEC1 encoded point.
131pub type Sec1Point = elliptic_curve::sec1::Sec1Point<NistP256>;
132
133/// NIST P-256 field element serialized as bytes.
134///
135/// Byte array containing a serialized field element value (base field or scalar).
136pub type FieldBytes = elliptic_curve::FieldBytes<NistP256>;
137
138/// Non-zero NIST P-256 scalar field element.
139#[cfg(feature = "arithmetic")]
140pub type NonZeroScalar = elliptic_curve::NonZeroScalar<NistP256>;
141
142/// NIST P-256 public key.
143#[cfg(feature = "arithmetic")]
144pub type PublicKey = elliptic_curve::PublicKey<NistP256>;
145
146/// NIST P-256 secret key.
147pub type SecretKey = elliptic_curve::SecretKey<NistP256>;
148
149#[cfg(not(feature = "arithmetic"))]
150impl elliptic_curve::sec1::ValidatePublicKey for NistP256 {}
151
152#[cfg(feature = "oprf")]
153impl hash2curve::OprfParameters for NistP256 {
154 /// See <https://www.rfc-editor.org/rfc/rfc9497.html#section-4.3-1>.
155 const ID: &'static [u8] = b"P256-SHA256";
156}