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#[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
59const ORDER_HEX: &str = {
61 cpubits! {
62 32 => {
63 "000001fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409"
64 }
65 64 => {
66 "00000000000001fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409"
67 }
68 }
69};
70
71#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, PartialOrd, Ord)]
73pub struct NistP521;
74
75impl elliptic_curve::Curve for NistP521 {
76 type FieldBytesSize = U66;
78
79 type Uint = Uint;
81
82 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 const COMPRESS_POINTS: bool = false;
91}
92
93impl elliptic_curve::point::PointCompaction for NistP521 {
94 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
103pub type CompressedPoint = Array<u8, U67>;
105
106pub type Sec1Point = elliptic_curve::sec1::Sec1Point<NistP521>;
108
109pub type FieldBytes = elliptic_curve::FieldBytes<NistP521>;
114
115#[cfg(feature = "arithmetic")]
117pub type NonZeroScalar = elliptic_curve::NonZeroScalar<NistP521>;
118
119#[cfg(feature = "arithmetic")]
121pub type PublicKey = elliptic_curve::PublicKey<NistP521>;
122
123pub type SecretKey = elliptic_curve::SecretKey<NistP521>;
125
126#[cfg(feature = "oprf")]
127impl hash2curve::OprfParameters for NistP521 {
128 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}