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 core::fmt::Debug; 16 17 /// Marker trait for an elliptic curve used for diffie-hellman. 18 pub trait Curve {} 19 20 /// Collection of types used to provide a particular elliptic curve implementation. 21 pub trait EcdhProvider<C: Curve> { 22 /// The public key type. 23 type PublicKey: PublicKey<C>; 24 /// The ephemeral secret type used to perform diffie-hellman and derive a shared secret. 25 type EphemeralSecret: EphemeralSecret<C, Impl = Self>; 26 /// The shared secret type. 27 type SharedSecret: Into<[u8; 32]>; 28 } 29 30 /// Trait for an ephemeral secret used to perform diffie-hellamn and derive a shared secret. 31 pub trait EphemeralSecret<C: Curve>: Send { 32 /// The associated ECDH provider. 33 type Impl: EcdhProvider<C>; 34 35 /// The error type associated with this ephemeral secret implementation. 36 type Error: Debug; 37 38 /// The random number generator to be used for generating a secret 39 type Rng: crate::CryptoRng; 40 41 /// The for encoded public key bytes, for example a `[u8; N]` array if the size is fixed, or 42 /// `ArrayVec<[u8; N]>` if the size is bounded but not fixed. 43 type EncodedPublicKey: AsRef<[u8]> + Debug; 44 45 /// Generates a new random ephemeral secret. generate_random(rng: &mut Self::Rng) -> Self46 fn generate_random(rng: &mut Self::Rng) -> Self; 47 48 /// Returns the bytes of the public key for this ephemeral secret that is suitable for sending 49 /// over the wire for key exchange. public_key_bytes(&self) -> Self::EncodedPublicKey50 fn public_key_bytes(&self) -> Self::EncodedPublicKey; 51 52 /// Performs diffie-hellman key exchange using this ephemeral secret with the given public key 53 /// `other_pub`. diffie_hellman( self, other_pub: &<Self::Impl as EcdhProvider<C>>::PublicKey, ) -> Result<<Self::Impl as EcdhProvider<C>>::SharedSecret, Self::Error>54 fn diffie_hellman( 55 self, 56 other_pub: &<Self::Impl as EcdhProvider<C>>::PublicKey, 57 ) -> Result<<Self::Impl as EcdhProvider<C>>::SharedSecret, Self::Error>; 58 } 59 60 /// Trait for a public key used for elliptic curve diffie hellman. 61 pub trait PublicKey<E: Curve>: Sized + PartialEq + Debug { 62 /// The type for an encoded public key. 63 type EncodedPublicKey: AsRef<[u8]> + Debug; 64 /// The error type associated with Public Key. 65 type Error: Debug; 66 67 /// Creates the public key from the given bytes. The format of the bytes is dependent on the 68 /// curve used, but it must be the inverse of `to_bytes`. from_bytes(bytes: &[u8]) -> Result<Self, Self::Error>69 fn from_bytes(bytes: &[u8]) -> Result<Self, Self::Error>; 70 71 /// Serializes the given public key to bytes. This format of the bytes is dependent on the 72 /// curve, but it must be the inverse of `from_bytes`. Note that some formats, like P256 using 73 /// the sec1 encoding, may return equivalent but different byte-representations due to point 74 /// compression, so it is not necessarily true that `from_bytes(bytes)?.to_bytes() == bytes` 75 /// (but it is always true that `from_bytes(key.to_bytes())? == key`). to_bytes(&self) -> Self::EncodedPublicKey76 fn to_bytes(&self) -> Self::EncodedPublicKey; 77 } 78