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