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