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