Better Together Rust Devs | f6f0ac8 | 2023-03-27 15:28:41 -0700 | [diff] [blame] | 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 | |
Better Together Rust Devs | e0af43b | 2023-11-07 16:49:36 -0800 | [diff] [blame^] | 15 | use tinyvec::ArrayVec; |
Better Together Rust Devs | f6f0ac8 | 2023-03-27 15:28:41 -0700 | [diff] [blame] | 16 | |
| 17 | use crate::elliptic_curve::{Curve, EcdhProvider, PublicKey}; |
Better Together Rust Devs | f6f0ac8 | 2023-03-27 15:28:41 -0700 | [diff] [blame] | 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 | |
Better Together Rust Devs | e0af43b | 2023-11-07 16:49:36 -0800 | [diff] [blame^] | 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 | |
Better Together Rust Devs | f6f0ac8 | 2023-03-27 15:28:41 -0700 | [diff] [blame] | 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. |
| 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`). |
Better Together Rust Devs | e0af43b | 2023-11-07 16:49:36 -0800 | [diff] [blame^] | 56 | fn to_sec1_bytes( |
| 57 | &self, |
| 58 | point_compression: PointCompression, |
| 59 | ) -> ArrayVec<[u8; P256_PUBLIC_KEY_MAX_LENGTH]>; |
Better Together Rust Devs | f6f0ac8 | 2023-03-27 15:28:41 -0700 | [diff] [blame] | 60 | |
| 61 | /// Converts this public key's x and y coordinates on the elliptic curve to big endian octet |
| 62 | /// strings. |
| 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. |
| 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; |
Better Together Rust Devs | e0af43b | 2023-11-07 16:49:36 -0800 | [diff] [blame^] | 71 | type EncodedPublicKey = ArrayVec<[u8; P256_PUBLIC_KEY_MAX_LENGTH]>; |
Better Together Rust Devs | f6f0ac8 | 2023-03-27 15:28:41 -0700 | [diff] [blame] | 72 | |
| 73 | fn from_bytes(bytes: &[u8]) -> Result<Self, Self::Error> { |
| 74 | Self::from_sec1_bytes(bytes) |
| 75 | } |
| 76 | |
Better Together Rust Devs | e0af43b | 2023-11-07 16:49:36 -0800 | [diff] [blame^] | 77 | fn to_bytes(&self) -> Self::EncodedPublicKey { |
| 78 | Self::to_sec1_bytes(self, PointCompression::Uncompressed) |
Better Together Rust Devs | f6f0ac8 | 2023-03-27 15:28:41 -0700 | [diff] [blame] | 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 | } |