Skip to main content

p521/
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//!
27//! Please see type-specific documentation for more information.
28
29#[cfg(feature = "ecdh")]
30pub mod ecdh;
31#[cfg(feature = "ecdsa-core")]
32pub mod ecdsa;
33#[cfg(any(feature = "test-vectors", test))]
34pub mod test_vectors;
35
36#[cfg(feature = "arithmetic")]
37mod arithmetic;
38
39pub use elliptic_curve;
40
41#[cfg(feature = "arithmetic")]
42pub use arithmetic::{AffinePoint, ProjectivePoint, scalar::Scalar};
43#[cfg(feature = "pkcs8")]
44pub use elliptic_curve::pkcs8;
45#[cfg(feature = "hash2curve")]
46pub use hash2curve;
47
48use elliptic_curve::{
49    array::Array,
50    bigint::{Odd, cpubits},
51    consts::{U66, U67},
52};
53
54cpubits! {
55    32 => { use elliptic_curve::bigint::U544 as Uint; }
56    64 => { use elliptic_curve::bigint::U576 as Uint; }
57}
58
59/// Order of NIST P-521's elliptic curve group (i.e. scalar modulus) in hexadecimal.
60const ORDER_HEX: &str = {
61    cpubits! {
62        32 => {
63            "000001fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409"
64        }
65        64 => {
66            "00000000000001fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409"
67        }
68    }
69};
70
71/// NIST P-521 elliptic curve.
72#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, PartialOrd, Ord)]
73pub struct NistP521;
74
75impl elliptic_curve::Curve for NistP521 {
76    /// 66-byte serialized field elements.
77    type FieldBytesSize = U66;
78
79    /// 521-bit integer type used for internally representing field elements.
80    type Uint = Uint;
81
82    /// Order of NIST P-521's elliptic curve group (i.e. scalar modulus).
83    const ORDER: Odd<Uint> = Odd::<Uint>::from_be_hex(ORDER_HEX);
84}
85
86impl elliptic_curve::PrimeCurve for NistP521 {}
87
88impl elliptic_curve::point::PointCompression for NistP521 {
89    /// NIST P-521 points are typically uncompressed.
90    const COMPRESS_POINTS: bool = false;
91}
92
93impl elliptic_curve::point::PointCompaction for NistP521 {
94    /// NIST P-521 points are typically uncompacted.
95    const COMPACT_POINTS: bool = false;
96}
97
98#[cfg(feature = "pkcs8")]
99impl pkcs8::AssociatedOid for NistP521 {
100    const OID: pkcs8::ObjectIdentifier = pkcs8::ObjectIdentifier::new_unwrap("1.3.132.0.35");
101}
102
103/// Compressed SEC1-encoded NIST P-521 curve point.
104pub type CompressedPoint = Array<u8, U67>;
105
106/// NIST P-521 SEC1 encoded point.
107pub type Sec1Point = elliptic_curve::sec1::Sec1Point<NistP521>;
108
109/// NIST P-521 field element serialized as bytes.
110///
111/// Byte array containing a serialized field element value (base field or
112/// scalar).
113pub type FieldBytes = elliptic_curve::FieldBytes<NistP521>;
114
115/// Non-zero NIST P-521 scalar field element.
116#[cfg(feature = "arithmetic")]
117pub type NonZeroScalar = elliptic_curve::NonZeroScalar<NistP521>;
118
119/// NIST P-521 public key.
120#[cfg(feature = "arithmetic")]
121pub type PublicKey = elliptic_curve::PublicKey<NistP521>;
122
123/// NIST P-521 secret key.
124pub type SecretKey = elliptic_curve::SecretKey<NistP521>;
125
126#[cfg(feature = "oprf")]
127impl hash2curve::OprfParameters for NistP521 {
128    /// See <https://www.rfc-editor.org/rfc/rfc9497.html#section-4.5-1>.
129    const ID: &'static [u8] = b"P521-SHA512";
130}
131
132#[cfg(test)]
133mod tests {
134    use super::{CompressedPoint, NistP521};
135    use core::mem::size_of;
136    use elliptic_curve::sec1::CompressedPoint as Sec1Compressed;
137
138    #[test]
139    fn compressed_point_size_matches_sec1() {
140        assert_eq!(size_of::<CompressedPoint>(), 67);
141        assert_eq!(
142            size_of::<CompressedPoint>(),
143            size_of::<Sec1Compressed<NistP521>>(),
144        );
145    }
146}