1 // Copyright 2023 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 use tinyvec::ArrayVec; 16 17 use crate::elliptic_curve::{Curve, EcdhProvider, PublicKey}; 18 use core::fmt::Debug; 19 20 /// Marker type for P256 implementation. This is used by EcdhProvider as its type parameter. 21 #[derive(Debug, PartialEq, Eq)] 22 pub enum P256 {} 23 impl Curve for P256 {} 24 25 /// Longest length for a sec-1 encoded P256 public key, which is the uncompressed format 26 /// `04 || X || Y` as defined in section 2.3.3 of the SECG SEC 1 ("Elliptic Curve Cryptography") 27 /// standard. 28 const P256_PUBLIC_KEY_MAX_LENGTH: usize = 65; 29 30 /// Whether an elliptic curve point should be compressed or not. 31 #[derive(Debug, Clone, Copy, PartialEq, Eq)] 32 pub enum PointCompression { 33 /// The elliptic curve point should be compressed (`02 || X` or `03 || X`), 34 /// as defined in section 2.3.3 of the SECG SEC 1 ("Elliptic Curve 35 /// Cryptography"). 36 Compressed, 37 /// The elliptic curve point should be uncompressed (`04 || X || Y`), as 38 /// defined in section 2.3.3 of the SECG SEC 1 ("Elliptic Curve 39 /// Cryptography"). 40 Uncompressed, 41 } 42 43 /// Trait for a NIST-P256 public key. 44 pub trait P256PublicKey: Sized + PartialEq + Debug { 45 /// The error type associated with this implementation. 46 type Error: Debug; 47 48 /// Creates a public key from the given sec1-encoded bytes, as described in section 2.3.4 of 49 /// the SECG SEC 1 ("Elliptic Curve Cryptography") standard. from_sec1_bytes(bytes: &[u8]) -> Result<Self, Self::Error>50 fn from_sec1_bytes(bytes: &[u8]) -> Result<Self, Self::Error>; 51 52 /// Serializes this key into sec1-encoded bytes, as described in section 2.3.3 of the SECG SEC 1 53 /// ("Elliptic Curve Cryptography") standard. Note that it is not necessarily true that 54 /// `from_sec1_bytes(bytes)?.to_sec1_bytes() == bytes` because of point compression. (But it is 55 /// always true that `from_sec1_bytes(key.to_sec1_bytes())? == key`). to_sec1_bytes( &self, point_compression: PointCompression, ) -> ArrayVec<[u8; P256_PUBLIC_KEY_MAX_LENGTH]>56 fn to_sec1_bytes( 57 &self, 58 point_compression: PointCompression, 59 ) -> ArrayVec<[u8; P256_PUBLIC_KEY_MAX_LENGTH]>; 60 61 /// Converts this public key's x and y coordinates on the elliptic curve to big endian octet 62 /// strings. to_affine_coordinates(&self) -> Result<([u8; 32], [u8; 32]), Self::Error>63 fn to_affine_coordinates(&self) -> Result<([u8; 32], [u8; 32]), Self::Error>; 64 65 /// Creates a public key from the X and Y coordinates on the elliptic curve. from_affine_coordinates(x: &[u8; 32], y: &[u8; 32]) -> Result<Self, Self::Error>66 fn from_affine_coordinates(x: &[u8; 32], y: &[u8; 32]) -> Result<Self, Self::Error>; 67 } 68 69 impl<P: P256PublicKey> PublicKey<P256> for P { 70 type Error = <Self as P256PublicKey>::Error; 71 type EncodedPublicKey = ArrayVec<[u8; P256_PUBLIC_KEY_MAX_LENGTH]>; 72 from_bytes(bytes: &[u8]) -> Result<Self, Self::Error>73 fn from_bytes(bytes: &[u8]) -> Result<Self, Self::Error> { 74 Self::from_sec1_bytes(bytes) 75 } 76 to_bytes(&self) -> Self::EncodedPublicKey77 fn to_bytes(&self) -> Self::EncodedPublicKey { 78 Self::to_sec1_bytes(self, PointCompression::Uncompressed) 79 } 80 } 81 82 /// Equivalent to EcdhProvider<P256, PublicKey: P256PublicKey> if associated type bounds are 83 /// supported. 84 pub trait P256EcdhProvider: 85 EcdhProvider<P256, PublicKey = <Self as P256EcdhProvider>::PublicKey> 86 { 87 /// Same as EcdhProvider::PublicKey. 88 type PublicKey: P256PublicKey; 89 } 90 91 impl<E> P256EcdhProvider for E 92 where 93 E: EcdhProvider<P256>, 94 E::PublicKey: P256PublicKey, 95 { 96 type PublicKey = E::PublicKey; 97 } 98