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 // User-facing, crypto-provider independent structs 18 19 /// The length of a ed25519 `Signature`, in bytes. 20 pub const SIGNATURE_LENGTH: usize = 64; 21 22 /// The length of an ed25519 `PrivateKey`, in bytes. 23 pub const PRIVATE_KEY_LENGTH: usize = 32; 24 25 /// The length of an ed25519 `PrivateKey`, in bytes. 26 pub const PUBLIC_KEY_LENGTH: usize = 32; 27 28 /// A byte buffer the size of a ed25519 `Signature`. 29 pub type RawSignature = [u8; SIGNATURE_LENGTH]; 30 31 /// A byte buffer the size of a ed25519 `PublicKey`. 32 pub type RawPublicKey = [u8; PUBLIC_KEY_LENGTH]; 33 34 /// A byte buffer the size of a ed25519 `PrivateKey`. 35 pub type RawPrivateKey = [u8; PRIVATE_KEY_LENGTH]; 36 37 /// A permission token which may be supplied to methods which allow 38 /// converting private keys to/from raw bytes. 39 /// 40 /// In general, operations of this kind should only be done in 41 /// development-tools, tests, or in credential storage layers 42 /// to prevent accidental exposure of the private key. 43 pub struct RawPrivateKeyPermit { 44 _marker: (), 45 } 46 47 impl RawPrivateKeyPermit { new() -> Self48 pub(crate) fn new() -> Self { 49 Self { _marker: () } 50 } 51 } 52 53 #[cfg(feature = "raw_private_key_permit")] 54 impl core::default::Default for RawPrivateKeyPermit { default() -> Self55 fn default() -> Self { 56 Self::new() 57 } 58 } 59 60 /// A crypto-provider-independent representation of the private 61 /// key of an ed25519 key-pair, kept in such a way that 62 /// it does not permit de-structuring it into raw bytes, 63 /// nor constructing one from raw bytes. 64 /// 65 /// Useful for when you want a data-structure to be 66 /// crypto-provider independent and contain a private key. 67 #[derive(Clone)] 68 pub struct PrivateKey(RawPrivateKey); 69 70 impl PrivateKey { 71 /// Derives the public key corresponding to this private key. derive_public_key<E: Ed25519Provider>(&self) -> PublicKey72 pub fn derive_public_key<E: Ed25519Provider>(&self) -> PublicKey { 73 let key_pair = E::KeyPair::from_private_key(self); 74 key_pair.public_key().to_external() 75 } 76 /// Sign the given message and return a digital signature sign<E: Ed25519Provider>(&self, msg: &[u8]) -> Signature77 pub fn sign<E: Ed25519Provider>(&self, msg: &[u8]) -> Signature { 78 let key_pair = E::KeyPair::from_private_key(self); 79 key_pair.sign(msg).to_external() 80 } 81 /// Generate an ed25519 private key from a CSPRNG 82 /// generate is not available in `no-std`. 83 #[cfg(feature = "std")] generate<E: Ed25519Provider>() -> Self84 pub fn generate<E: Ed25519Provider>() -> Self { 85 let key_pair = E::KeyPair::generate(); 86 key_pair.private_key() 87 } 88 89 /// Returns the raw bytes of this private key. 90 /// This operation is only possible while holding a [`RawPrivateKeyPermit`]. raw_private_key(&self, _permit: &RawPrivateKeyPermit) -> RawPrivateKey91 pub fn raw_private_key(&self, _permit: &RawPrivateKeyPermit) -> RawPrivateKey { 92 self.0 93 } 94 /// Constructs a private key from the raw bytes of the key. 95 /// This operation is only possible while holding a [`RawPrivateKeyPermit`]. from_raw_private_key(wrapped: RawPrivateKey, _permit: &RawPrivateKeyPermit) -> Self96 pub fn from_raw_private_key(wrapped: RawPrivateKey, _permit: &RawPrivateKeyPermit) -> Self { 97 PrivateKey(wrapped) 98 } 99 } 100 101 /// error returned when bad bytes are provided to generate keypair 102 #[derive(Debug)] 103 pub struct InvalidPublicKeyBytes; 104 105 /// Error returned if the verification on the signature + message fails 106 #[derive(Debug)] 107 pub struct SignatureError; 108 109 /// A crypto-provider-independent representation of a valid 110 /// public key for an ed25519 key-pair in the Edwards Y-format. 111 /// 112 /// Useful for when you want a data-structure to be crypto-provider 113 /// independent and contain a public key. 114 #[derive(Clone, Debug, PartialEq, Eq)] 115 pub struct PublicKey(RawPublicKey); 116 117 impl PublicKey { 118 /// Attempts to parse a public key from an array of bytes. 119 /// If the input is not in the Edwards Y-format, this method 120 /// will yield an `InvalidPublicKeyBytes` error. from_bytes<E: Ed25519Provider>( wrapped: RawPublicKey, ) -> Result<Self, InvalidPublicKeyBytes>121 pub fn from_bytes<E: Ed25519Provider>( 122 wrapped: RawPublicKey, 123 ) -> Result<Self, InvalidPublicKeyBytes> { 124 // Simply verify that we can construct the crypto-provider-dependent variant. 125 let _ = <E::PublicKey as PublicKeyImpl>::from_bytes(&wrapped)?; 126 Ok(PublicKey(wrapped)) 127 } 128 /// Converts this public-key into the raw bytes of this public-key. into_bytes(self) -> RawPublicKey129 pub fn into_bytes(self) -> RawPublicKey { 130 self.0 131 } 132 133 /// Converts this crypto-provider-independent public key to a crypto-provider's internal rep. 134 #[allow(clippy::expect_used)] as_internal<E: Ed25519Provider>(&self) -> E::PublicKey135 fn as_internal<E: Ed25519Provider>(&self) -> E::PublicKey { 136 <E::PublicKey as PublicKeyImpl>::from_bytes(&self.0) 137 .expect("Public key bytes validated upon construction.") 138 } 139 140 /// Succeeds if the signature on the given message is verified 141 /// by this public key. verify_strict<E: Ed25519Provider>( &self, message: &[u8], signature: Signature, ) -> Result<(), SignatureError>142 pub fn verify_strict<E: Ed25519Provider>( 143 &self, 144 message: &[u8], 145 signature: Signature, 146 ) -> Result<(), SignatureError> { 147 let public_key = self.as_internal::<E>(); 148 let signature = signature.as_internal::<E>(); 149 public_key.verify_strict(message, &signature) 150 } 151 } 152 153 /// A crypto-provider-independent representation of an Ed25519 signature. 154 /// The underlying representation here can be any arbitrary bytes - verifying 155 /// code handles determining whether/not the signature actually corresponds 156 /// to a real Ed25519 signature and matches the given public key. 157 #[derive(Clone)] 158 pub struct Signature(RawSignature); 159 160 impl From<RawSignature> for Signature { from(wrapped: RawSignature) -> Self161 fn from(wrapped: RawSignature) -> Self { 162 Signature(wrapped) 163 } 164 } 165 166 impl Signature { 167 /// Constructs a signature from raw bytes. new(wrapped: RawSignature) -> Self168 pub fn new(wrapped: RawSignature) -> Self { 169 Signature(wrapped) 170 } 171 /// Transforms this signature back into raw bytes. to_bytes(self) -> RawSignature172 pub fn to_bytes(self) -> RawSignature { 173 self.0 174 } 175 /// Converts this crypto-provider-independent signature to a crypto-provider's internal rep. as_internal<E: Ed25519Provider>(&self) -> E::Signature176 fn as_internal<E: Ed25519Provider>(&self) -> E::Signature { 177 <E::Signature as SignatureImpl>::from_bytes(&self.0) 178 } 179 } 180 181 // Implementor-facing crypto-provider-internal traits. 182 183 /// Collection of types used to provide an implementation of ed25519, the Edwards-curve Digital 184 /// Signature Algorithm scheme using sha-512 (sha2) and Curve25519 185 pub trait Ed25519Provider { 186 /// The internal representation of a keypair which includes both public and secret halves of an asymmetric key. 187 type KeyPair: KeyPairImpl<PublicKey = Self::PublicKey, Signature = Self::Signature>; 188 /// The internal representation of an ed25519 public key, used when verifying a message 189 type PublicKey: PublicKeyImpl<Signature = Self::Signature>; 190 /// The internal representation of an ed25519 signature which is the result of signing a message 191 type Signature: SignatureImpl; 192 } 193 194 /// The keypair which includes both public and secret halves of an asymmetric key. 195 pub trait KeyPairImpl: Sized { 196 /// The ed25519 public key, used when verifying a message 197 type PublicKey: PublicKeyImpl; 198 199 /// The ed25519 signature returned when signing a message 200 type Signature: SignatureImpl; 201 202 /// Returns the private key bytes of the `KeyPair`. 203 /// This operation is only possible while holding a [`RawPrivateKeyPermit`]. raw_private_key(&self, _permit: &RawPrivateKeyPermit) -> RawPrivateKey204 fn raw_private_key(&self, _permit: &RawPrivateKeyPermit) -> RawPrivateKey; 205 206 /// Builds a key-pair from a `RawPrivateKey` array of bytes. 207 /// This operation is only possible while holding a [`RawPrivateKeyPermit`]. from_raw_private_key(bytes: &RawPrivateKey, _permit: &RawPrivateKeyPermit) -> Self where Self: Sized208 fn from_raw_private_key(bytes: &RawPrivateKey, _permit: &RawPrivateKeyPermit) -> Self 209 where 210 Self: Sized; 211 212 /// Returns the private key of the `KeyPair` in an opaque form. private_key(&self) -> PrivateKey213 fn private_key(&self) -> PrivateKey { 214 // We're okay to reach in and grab the bytes of the private key, 215 // since the way that we're exposing it would require a valid 216 // [`RawPrivateKeyPermit`] to extract them again. 217 let wrapped = self.raw_private_key(&RawPrivateKeyPermit::new()); 218 PrivateKey(wrapped) 219 } 220 221 /// Builds a key-pair from a [`PrivateKey`], given in an opaque form. from_private_key(private_key: &PrivateKey) -> Self where Self: Sized,222 fn from_private_key(private_key: &PrivateKey) -> Self 223 where 224 Self: Sized, 225 { 226 // We're okay to reach in and construct an instance from 227 // the bytes of the private key, since the way that they 228 // were originally expressed would still require a valid 229 // [`RawPrivateKeyPermit`] to access them. 230 let raw_private_key = &private_key.0; 231 Self::from_raw_private_key(raw_private_key, &RawPrivateKeyPermit::new()) 232 } 233 234 /// Sign the given message and return a digital signature sign(&self, msg: &[u8]) -> Self::Signature235 fn sign(&self, msg: &[u8]) -> Self::Signature; 236 237 /// Generate an ed25519 keypair from a CSPRNG 238 /// generate is not available in `no-std` 239 #[cfg(feature = "std")] generate() -> Self240 fn generate() -> Self; 241 242 /// getter function for the Public Key of the key pair public_key(&self) -> Self::PublicKey243 fn public_key(&self) -> Self::PublicKey; 244 } 245 246 /// An ed25519 signature 247 pub trait SignatureImpl: Sized { 248 /// Create a new signature from a fixed size byte array. This represents a container for the 249 /// byte serialization of an Ed25519 signature, and does not necessarily represent well-formed 250 /// field or curve elements. 251 /// 252 /// Signature verification libraries are expected to reject invalid field 253 /// elements at the time a signature is verified (not constructed). from_bytes(bytes: &RawSignature) -> Self254 fn from_bytes(bytes: &RawSignature) -> Self; 255 256 /// Returns a slice of the signature bytes to_bytes(&self) -> RawSignature257 fn to_bytes(&self) -> RawSignature; 258 259 /// Returns a crypto-provider-independent `Signature` from this implementation-specific struct. to_external(&self) -> Signature260 fn to_external(&self) -> Signature { 261 let wrapped = self.to_bytes(); 262 Signature(wrapped) 263 } 264 } 265 266 /// An ed25519 public key 267 pub trait PublicKeyImpl { 268 /// the signature type being used by verify 269 type Signature: SignatureImpl; 270 271 /// Builds this public key from an array of bytes in 272 /// the format yielded by `to_bytes`. from_bytes(bytes: &RawPublicKey) -> Result<Self, InvalidPublicKeyBytes> where Self: Sized273 fn from_bytes(bytes: &RawPublicKey) -> Result<Self, InvalidPublicKeyBytes> 274 where 275 Self: Sized; 276 277 /// Yields the bytes of the public key to_bytes(&self) -> RawPublicKey278 fn to_bytes(&self) -> RawPublicKey; 279 280 /// Returns a crypto-provider-independent `PublicKey` from this implementation-specific struct. to_external(&self) -> PublicKey281 fn to_external(&self) -> PublicKey { 282 let wrapped = self.to_bytes(); 283 PublicKey(wrapped) 284 } 285 286 /// Succeeds if the signature was a valid signature created by this Keypair on the prehashed_message. verify_strict( &self, message: &[u8], signature: &Self::Signature, ) -> Result<(), SignatureError>287 fn verify_strict( 288 &self, 289 message: &[u8], 290 signature: &Self::Signature, 291 ) -> Result<(), SignatureError>; 292 } 293