1*e1997b9aSAndroid Build Coastguard Worker // Copyright 2024, The Android Open Source Project 2*e1997b9aSAndroid Build Coastguard Worker // 3*e1997b9aSAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License"); 4*e1997b9aSAndroid Build Coastguard Worker // you may not use this file except in compliance with the License. 5*e1997b9aSAndroid Build Coastguard Worker // You may obtain a copy of the License at 6*e1997b9aSAndroid Build Coastguard Worker // 7*e1997b9aSAndroid Build Coastguard Worker // http://www.apache.org/licenses/LICENSE-2.0 8*e1997b9aSAndroid Build Coastguard Worker // 9*e1997b9aSAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software 10*e1997b9aSAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS, 11*e1997b9aSAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*e1997b9aSAndroid Build Coastguard Worker // See the License for the specific language governing permissions and 13*e1997b9aSAndroid Build Coastguard Worker // limitations under the License. 14*e1997b9aSAndroid Build Coastguard Worker 15*e1997b9aSAndroid Build Coastguard Worker //! Edwards-curve digital signature algorithm. 16*e1997b9aSAndroid Build Coastguard Worker 17*e1997b9aSAndroid Build Coastguard Worker use bssl_crypto::{ed25519, InvalidSignatureError}; 18*e1997b9aSAndroid Build Coastguard Worker use mls_rs_core::crypto::{CipherSuite, SignaturePublicKey, SignatureSecretKey}; 19*e1997b9aSAndroid Build Coastguard Worker use mls_rs_crypto_traits::Curve; 20*e1997b9aSAndroid Build Coastguard Worker 21*e1997b9aSAndroid Build Coastguard Worker use core::array::TryFromSliceError; 22*e1997b9aSAndroid Build Coastguard Worker use thiserror::Error; 23*e1997b9aSAndroid Build Coastguard Worker 24*e1997b9aSAndroid Build Coastguard Worker /// Errors returned from EdDSA. 25*e1997b9aSAndroid Build Coastguard Worker #[derive(Debug, Error)] 26*e1997b9aSAndroid Build Coastguard Worker pub enum EdDsaError { 27*e1997b9aSAndroid Build Coastguard Worker /// Error returned when conversion from slice to array fails. 28*e1997b9aSAndroid Build Coastguard Worker #[error(transparent)] 29*e1997b9aSAndroid Build Coastguard Worker TryFromSliceError(#[from] TryFromSliceError), 30*e1997b9aSAndroid Build Coastguard Worker /// Error returned on an invalid signature. 31*e1997b9aSAndroid Build Coastguard Worker #[error("invalid signature")] 32*e1997b9aSAndroid Build Coastguard Worker InvalidSig(InvalidSignatureError), 33*e1997b9aSAndroid Build Coastguard Worker /// Error returned when the private key length is invalid. 34*e1997b9aSAndroid Build Coastguard Worker #[error("EdDSA private key of invalid length {len}, expected length {expected_len}")] 35*e1997b9aSAndroid Build Coastguard Worker InvalidPrivKeyLen { 36*e1997b9aSAndroid Build Coastguard Worker /// Invalid key length. 37*e1997b9aSAndroid Build Coastguard Worker len: usize, 38*e1997b9aSAndroid Build Coastguard Worker /// Expected key length. 39*e1997b9aSAndroid Build Coastguard Worker expected_len: usize, 40*e1997b9aSAndroid Build Coastguard Worker }, 41*e1997b9aSAndroid Build Coastguard Worker /// Error returned when the public key length is invalid. 42*e1997b9aSAndroid Build Coastguard Worker #[error("EdDSA public key of invalid length {len}, expected length {expected_len}")] 43*e1997b9aSAndroid Build Coastguard Worker InvalidPubKeyLen { 44*e1997b9aSAndroid Build Coastguard Worker /// Invalid key length. 45*e1997b9aSAndroid Build Coastguard Worker len: usize, 46*e1997b9aSAndroid Build Coastguard Worker /// Expected key length. 47*e1997b9aSAndroid Build Coastguard Worker expected_len: usize, 48*e1997b9aSAndroid Build Coastguard Worker }, 49*e1997b9aSAndroid Build Coastguard Worker /// Error returned when the signature length is invalid. 50*e1997b9aSAndroid Build Coastguard Worker #[error("EdDSA signature of invalid length {len}, expected length {expected_len}")] 51*e1997b9aSAndroid Build Coastguard Worker InvalidSigLen { 52*e1997b9aSAndroid Build Coastguard Worker /// Invalid signature length. 53*e1997b9aSAndroid Build Coastguard Worker len: usize, 54*e1997b9aSAndroid Build Coastguard Worker /// Expected signature length. 55*e1997b9aSAndroid Build Coastguard Worker expected_len: usize, 56*e1997b9aSAndroid Build Coastguard Worker }, 57*e1997b9aSAndroid Build Coastguard Worker /// Error returned when unsupported cipher suite is requested. 58*e1997b9aSAndroid Build Coastguard Worker #[error("unsupported cipher suite")] 59*e1997b9aSAndroid Build Coastguard Worker UnsupportedCipherSuite, 60*e1997b9aSAndroid Build Coastguard Worker } 61*e1997b9aSAndroid Build Coastguard Worker 62*e1997b9aSAndroid Build Coastguard Worker // Explicitly implemented as InvalidSignatureError's as_dyn_error does not satisfy trait bounds. 63*e1997b9aSAndroid Build Coastguard Worker impl From<InvalidSignatureError> for EdDsaError { from(e: InvalidSignatureError) -> Self64*e1997b9aSAndroid Build Coastguard Worker fn from(e: InvalidSignatureError) -> Self { 65*e1997b9aSAndroid Build Coastguard Worker EdDsaError::InvalidSig(e) 66*e1997b9aSAndroid Build Coastguard Worker } 67*e1997b9aSAndroid Build Coastguard Worker } 68*e1997b9aSAndroid Build Coastguard Worker 69*e1997b9aSAndroid Build Coastguard Worker /// EdDSA implementation backed by BoringSSL. 70*e1997b9aSAndroid Build Coastguard Worker #[derive(Clone, Debug, Copy, PartialEq, Eq)] 71*e1997b9aSAndroid Build Coastguard Worker pub struct EdDsa(Curve); 72*e1997b9aSAndroid Build Coastguard Worker 73*e1997b9aSAndroid Build Coastguard Worker impl EdDsa { 74*e1997b9aSAndroid Build Coastguard Worker /// Creates a new EdDsa. new(cipher_suite: CipherSuite) -> Option<Self>75*e1997b9aSAndroid Build Coastguard Worker pub fn new(cipher_suite: CipherSuite) -> Option<Self> { 76*e1997b9aSAndroid Build Coastguard Worker Curve::from_ciphersuite(cipher_suite, /*for_sig=*/ true).map(Self) 77*e1997b9aSAndroid Build Coastguard Worker } 78*e1997b9aSAndroid Build Coastguard Worker 79*e1997b9aSAndroid Build Coastguard Worker /// Generates a key pair. signature_key_generate( &self, ) -> Result<(SignatureSecretKey, SignaturePublicKey), EdDsaError>80*e1997b9aSAndroid Build Coastguard Worker pub fn signature_key_generate( 81*e1997b9aSAndroid Build Coastguard Worker &self, 82*e1997b9aSAndroid Build Coastguard Worker ) -> Result<(SignatureSecretKey, SignaturePublicKey), EdDsaError> { 83*e1997b9aSAndroid Build Coastguard Worker if self.0 != Curve::Ed25519 { 84*e1997b9aSAndroid Build Coastguard Worker return Err(EdDsaError::UnsupportedCipherSuite); 85*e1997b9aSAndroid Build Coastguard Worker } 86*e1997b9aSAndroid Build Coastguard Worker 87*e1997b9aSAndroid Build Coastguard Worker let private_key = ed25519::PrivateKey::generate(); 88*e1997b9aSAndroid Build Coastguard Worker let public_key = private_key.to_public(); 89*e1997b9aSAndroid Build Coastguard Worker Ok((private_key.to_seed().to_vec().into(), public_key.as_bytes().to_vec().into())) 90*e1997b9aSAndroid Build Coastguard Worker } 91*e1997b9aSAndroid Build Coastguard Worker 92*e1997b9aSAndroid Build Coastguard Worker /// Derives the public key from the private key. signature_key_derive_public( &self, secret_key: &SignatureSecretKey, ) -> Result<SignaturePublicKey, EdDsaError>93*e1997b9aSAndroid Build Coastguard Worker pub fn signature_key_derive_public( 94*e1997b9aSAndroid Build Coastguard Worker &self, 95*e1997b9aSAndroid Build Coastguard Worker secret_key: &SignatureSecretKey, 96*e1997b9aSAndroid Build Coastguard Worker ) -> Result<SignaturePublicKey, EdDsaError> { 97*e1997b9aSAndroid Build Coastguard Worker if self.0 != Curve::Ed25519 { 98*e1997b9aSAndroid Build Coastguard Worker return Err(EdDsaError::UnsupportedCipherSuite); 99*e1997b9aSAndroid Build Coastguard Worker } 100*e1997b9aSAndroid Build Coastguard Worker if secret_key.len() != ed25519::SEED_LEN { 101*e1997b9aSAndroid Build Coastguard Worker return Err(EdDsaError::InvalidPrivKeyLen { 102*e1997b9aSAndroid Build Coastguard Worker len: secret_key.len(), 103*e1997b9aSAndroid Build Coastguard Worker expected_len: ed25519::SEED_LEN, 104*e1997b9aSAndroid Build Coastguard Worker }); 105*e1997b9aSAndroid Build Coastguard Worker } 106*e1997b9aSAndroid Build Coastguard Worker 107*e1997b9aSAndroid Build Coastguard Worker let private_key = 108*e1997b9aSAndroid Build Coastguard Worker ed25519::PrivateKey::from_seed(secret_key[..ed25519::SEED_LEN].try_into()?); 109*e1997b9aSAndroid Build Coastguard Worker Ok(private_key.to_public().as_bytes().to_vec().into()) 110*e1997b9aSAndroid Build Coastguard Worker } 111*e1997b9aSAndroid Build Coastguard Worker 112*e1997b9aSAndroid Build Coastguard Worker /// Signs `data` using `secret_key`. sign( &self, secret_key: &SignatureSecretKey, data: &[u8], ) -> Result<Vec<u8>, EdDsaError>113*e1997b9aSAndroid Build Coastguard Worker pub fn sign( 114*e1997b9aSAndroid Build Coastguard Worker &self, 115*e1997b9aSAndroid Build Coastguard Worker secret_key: &SignatureSecretKey, 116*e1997b9aSAndroid Build Coastguard Worker data: &[u8], 117*e1997b9aSAndroid Build Coastguard Worker ) -> Result<Vec<u8>, EdDsaError> { 118*e1997b9aSAndroid Build Coastguard Worker if self.0 != Curve::Ed25519 { 119*e1997b9aSAndroid Build Coastguard Worker return Err(EdDsaError::UnsupportedCipherSuite); 120*e1997b9aSAndroid Build Coastguard Worker } 121*e1997b9aSAndroid Build Coastguard Worker if secret_key.len() != ed25519::SEED_LEN { 122*e1997b9aSAndroid Build Coastguard Worker return Err(EdDsaError::InvalidPrivKeyLen { 123*e1997b9aSAndroid Build Coastguard Worker len: secret_key.len(), 124*e1997b9aSAndroid Build Coastguard Worker expected_len: ed25519::SEED_LEN, 125*e1997b9aSAndroid Build Coastguard Worker }); 126*e1997b9aSAndroid Build Coastguard Worker } 127*e1997b9aSAndroid Build Coastguard Worker 128*e1997b9aSAndroid Build Coastguard Worker let private_key = 129*e1997b9aSAndroid Build Coastguard Worker ed25519::PrivateKey::from_seed(secret_key[..ed25519::SEED_LEN].try_into()?); 130*e1997b9aSAndroid Build Coastguard Worker Ok(private_key.sign(data).to_vec()) 131*e1997b9aSAndroid Build Coastguard Worker } 132*e1997b9aSAndroid Build Coastguard Worker 133*e1997b9aSAndroid Build Coastguard Worker /// Verifies `signature` is a valid signature of `data` using `public_key`. verify( &self, public_key: &SignaturePublicKey, signature: &[u8], data: &[u8], ) -> Result<(), EdDsaError>134*e1997b9aSAndroid Build Coastguard Worker pub fn verify( 135*e1997b9aSAndroid Build Coastguard Worker &self, 136*e1997b9aSAndroid Build Coastguard Worker public_key: &SignaturePublicKey, 137*e1997b9aSAndroid Build Coastguard Worker signature: &[u8], 138*e1997b9aSAndroid Build Coastguard Worker data: &[u8], 139*e1997b9aSAndroid Build Coastguard Worker ) -> Result<(), EdDsaError> { 140*e1997b9aSAndroid Build Coastguard Worker if self.0 != Curve::Ed25519 { 141*e1997b9aSAndroid Build Coastguard Worker return Err(EdDsaError::UnsupportedCipherSuite); 142*e1997b9aSAndroid Build Coastguard Worker } 143*e1997b9aSAndroid Build Coastguard Worker if public_key.len() != ed25519::PUBLIC_KEY_LEN { 144*e1997b9aSAndroid Build Coastguard Worker return Err(EdDsaError::InvalidPubKeyLen { 145*e1997b9aSAndroid Build Coastguard Worker len: public_key.len(), 146*e1997b9aSAndroid Build Coastguard Worker expected_len: ed25519::PUBLIC_KEY_LEN, 147*e1997b9aSAndroid Build Coastguard Worker }); 148*e1997b9aSAndroid Build Coastguard Worker } 149*e1997b9aSAndroid Build Coastguard Worker if signature.len() != ed25519::SIGNATURE_LEN { 150*e1997b9aSAndroid Build Coastguard Worker return Err(EdDsaError::InvalidSigLen { 151*e1997b9aSAndroid Build Coastguard Worker len: signature.len(), 152*e1997b9aSAndroid Build Coastguard Worker expected_len: ed25519::SIGNATURE_LEN, 153*e1997b9aSAndroid Build Coastguard Worker }); 154*e1997b9aSAndroid Build Coastguard Worker } 155*e1997b9aSAndroid Build Coastguard Worker 156*e1997b9aSAndroid Build Coastguard Worker let public_key = ed25519::PublicKey::from_bytes( 157*e1997b9aSAndroid Build Coastguard Worker public_key.as_bytes()[..ed25519::PUBLIC_KEY_LEN].try_into()?, 158*e1997b9aSAndroid Build Coastguard Worker ); 159*e1997b9aSAndroid Build Coastguard Worker match public_key.verify(data, signature[..ed25519::SIGNATURE_LEN].try_into()?) { 160*e1997b9aSAndroid Build Coastguard Worker Ok(_) => Ok(()), 161*e1997b9aSAndroid Build Coastguard Worker Err(e) => Err(EdDsaError::InvalidSig(e)), 162*e1997b9aSAndroid Build Coastguard Worker } 163*e1997b9aSAndroid Build Coastguard Worker } 164*e1997b9aSAndroid Build Coastguard Worker } 165*e1997b9aSAndroid Build Coastguard Worker 166*e1997b9aSAndroid Build Coastguard Worker #[cfg(all(not(mls_build_async), test))] 167*e1997b9aSAndroid Build Coastguard Worker mod test { 168*e1997b9aSAndroid Build Coastguard Worker use super::{EdDsa, EdDsaError}; 169*e1997b9aSAndroid Build Coastguard Worker use crate::test_helpers::decode_hex; 170*e1997b9aSAndroid Build Coastguard Worker use assert_matches::assert_matches; 171*e1997b9aSAndroid Build Coastguard Worker use mls_rs_core::crypto::{CipherSuite, SignaturePublicKey, SignatureSecretKey}; 172*e1997b9aSAndroid Build Coastguard Worker 173*e1997b9aSAndroid Build Coastguard Worker #[test] signature_key_generate()174*e1997b9aSAndroid Build Coastguard Worker fn signature_key_generate() { 175*e1997b9aSAndroid Build Coastguard Worker let ed25519 = EdDsa::new(CipherSuite::CURVE25519_AES128).unwrap(); 176*e1997b9aSAndroid Build Coastguard Worker assert!(ed25519.signature_key_generate().is_ok()); 177*e1997b9aSAndroid Build Coastguard Worker } 178*e1997b9aSAndroid Build Coastguard Worker 179*e1997b9aSAndroid Build Coastguard Worker #[test] signature_key_derive_public()180*e1997b9aSAndroid Build Coastguard Worker fn signature_key_derive_public() { 181*e1997b9aSAndroid Build Coastguard Worker // Test 1 from https://www.rfc-editor.org/rfc/rfc8032#section-7.1 182*e1997b9aSAndroid Build Coastguard Worker let private_key = SignatureSecretKey::from( 183*e1997b9aSAndroid Build Coastguard Worker decode_hex::<32>("9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60") 184*e1997b9aSAndroid Build Coastguard Worker .to_vec(), 185*e1997b9aSAndroid Build Coastguard Worker ); 186*e1997b9aSAndroid Build Coastguard Worker let expected_public_key = SignaturePublicKey::from( 187*e1997b9aSAndroid Build Coastguard Worker decode_hex::<32>("d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a") 188*e1997b9aSAndroid Build Coastguard Worker .to_vec(), 189*e1997b9aSAndroid Build Coastguard Worker ); 190*e1997b9aSAndroid Build Coastguard Worker 191*e1997b9aSAndroid Build Coastguard Worker let ed25519 = EdDsa::new(CipherSuite::CURVE25519_CHACHA).unwrap(); 192*e1997b9aSAndroid Build Coastguard Worker assert_eq!(ed25519.signature_key_derive_public(&private_key).unwrap(), expected_public_key); 193*e1997b9aSAndroid Build Coastguard Worker } 194*e1997b9aSAndroid Build Coastguard Worker 195*e1997b9aSAndroid Build Coastguard Worker #[test] signature_key_derive_public_invalid_key()196*e1997b9aSAndroid Build Coastguard Worker fn signature_key_derive_public_invalid_key() { 197*e1997b9aSAndroid Build Coastguard Worker let private_key_short = 198*e1997b9aSAndroid Build Coastguard Worker SignatureSecretKey::from(decode_hex::<16>("9d61b19deffd5a60ba844af492ec2cc4").to_vec()); 199*e1997b9aSAndroid Build Coastguard Worker 200*e1997b9aSAndroid Build Coastguard Worker let ed25519 = EdDsa::new(CipherSuite::CURVE25519_CHACHA).unwrap(); 201*e1997b9aSAndroid Build Coastguard Worker assert_matches!( 202*e1997b9aSAndroid Build Coastguard Worker ed25519.signature_key_derive_public(&private_key_short), 203*e1997b9aSAndroid Build Coastguard Worker Err(EdDsaError::InvalidPrivKeyLen { .. }) 204*e1997b9aSAndroid Build Coastguard Worker ); 205*e1997b9aSAndroid Build Coastguard Worker } 206*e1997b9aSAndroid Build Coastguard Worker 207*e1997b9aSAndroid Build Coastguard Worker #[test] sign_verify()208*e1997b9aSAndroid Build Coastguard Worker fn sign_verify() { 209*e1997b9aSAndroid Build Coastguard Worker // Test 3 from https://www.rfc-editor.org/rfc/rfc8032#section-7.1 210*e1997b9aSAndroid Build Coastguard Worker let private_key = SignatureSecretKey::from( 211*e1997b9aSAndroid Build Coastguard Worker decode_hex::<32>("c5aa8df43f9f837bedb7442f31dcb7b166d38535076f094b85ce3a2e0b4458f7") 212*e1997b9aSAndroid Build Coastguard Worker .to_vec(), 213*e1997b9aSAndroid Build Coastguard Worker ); 214*e1997b9aSAndroid Build Coastguard Worker let data: [u8; 2] = decode_hex("af82"); 215*e1997b9aSAndroid Build Coastguard Worker let expected_sig = decode_hex::<64>("6291d657deec24024827e69c3abe01a30ce548a284743a445e3680d7db5ac3ac18ff9b538d16f290ae67f760984dc6594a7c15e9716ed28dc027beceea1ec40a").to_vec(); 216*e1997b9aSAndroid Build Coastguard Worker 217*e1997b9aSAndroid Build Coastguard Worker let ed25519 = EdDsa::new(CipherSuite::CURVE25519_AES128).unwrap(); 218*e1997b9aSAndroid Build Coastguard Worker let sig = ed25519.sign(&private_key, &data).unwrap(); 219*e1997b9aSAndroid Build Coastguard Worker assert_eq!(sig, expected_sig); 220*e1997b9aSAndroid Build Coastguard Worker 221*e1997b9aSAndroid Build Coastguard Worker let public_key = ed25519.signature_key_derive_public(&private_key).unwrap(); 222*e1997b9aSAndroid Build Coastguard Worker assert!(ed25519.verify(&public_key, &sig, &data).is_ok()); 223*e1997b9aSAndroid Build Coastguard Worker } 224*e1997b9aSAndroid Build Coastguard Worker 225*e1997b9aSAndroid Build Coastguard Worker #[test] sign_invalid_key()226*e1997b9aSAndroid Build Coastguard Worker fn sign_invalid_key() { 227*e1997b9aSAndroid Build Coastguard Worker let private_key_short = 228*e1997b9aSAndroid Build Coastguard Worker SignatureSecretKey::from(decode_hex::<16>("c5aa8df43f9f837bedb7442f31dcb7b1").to_vec()); 229*e1997b9aSAndroid Build Coastguard Worker 230*e1997b9aSAndroid Build Coastguard Worker let ed25519 = EdDsa::new(CipherSuite::CURVE25519_AES128).unwrap(); 231*e1997b9aSAndroid Build Coastguard Worker assert_matches!( 232*e1997b9aSAndroid Build Coastguard Worker ed25519.sign(&private_key_short, &decode_hex::<2>("af82")), 233*e1997b9aSAndroid Build Coastguard Worker Err(EdDsaError::InvalidPrivKeyLen { .. }) 234*e1997b9aSAndroid Build Coastguard Worker ); 235*e1997b9aSAndroid Build Coastguard Worker } 236*e1997b9aSAndroid Build Coastguard Worker 237*e1997b9aSAndroid Build Coastguard Worker #[test] verify_invalid_key()238*e1997b9aSAndroid Build Coastguard Worker fn verify_invalid_key() { 239*e1997b9aSAndroid Build Coastguard Worker let public_key_short = 240*e1997b9aSAndroid Build Coastguard Worker SignaturePublicKey::from(decode_hex::<16>("fc51cd8e6218a1a38da47ed00230f058").to_vec()); 241*e1997b9aSAndroid Build Coastguard Worker let sig = decode_hex::<64>("6291d657deec24024827e69c3abe01a30ce548a284743a445e3680d7db5ac3ac18ff9b538d16f290ae67f760984dc6594a7c15e9716ed28dc027beceea1ec40a").to_vec(); 242*e1997b9aSAndroid Build Coastguard Worker let data: [u8; 2] = decode_hex("af82"); 243*e1997b9aSAndroid Build Coastguard Worker 244*e1997b9aSAndroid Build Coastguard Worker let ed25519 = EdDsa::new(CipherSuite::CURVE25519_AES128).unwrap(); 245*e1997b9aSAndroid Build Coastguard Worker assert_matches!( 246*e1997b9aSAndroid Build Coastguard Worker ed25519.verify(&public_key_short, &sig, &data), 247*e1997b9aSAndroid Build Coastguard Worker Err(EdDsaError::InvalidPubKeyLen { .. }) 248*e1997b9aSAndroid Build Coastguard Worker ); 249*e1997b9aSAndroid Build Coastguard Worker } 250*e1997b9aSAndroid Build Coastguard Worker 251*e1997b9aSAndroid Build Coastguard Worker #[test] verify_invalid_sig()252*e1997b9aSAndroid Build Coastguard Worker fn verify_invalid_sig() { 253*e1997b9aSAndroid Build Coastguard Worker let public_key = SignaturePublicKey::from( 254*e1997b9aSAndroid Build Coastguard Worker decode_hex::<32>("fc51cd8e6218a1a38da47ed00230f0580816ed13ba3303ac5deb911548908025") 255*e1997b9aSAndroid Build Coastguard Worker .to_vec(), 256*e1997b9aSAndroid Build Coastguard Worker ); 257*e1997b9aSAndroid Build Coastguard Worker let sig_short = 258*e1997b9aSAndroid Build Coastguard Worker decode_hex::<32>("6291d657deec24024827e69c3abe01a30ce548a284743a445e3680d7db5ac3ac") 259*e1997b9aSAndroid Build Coastguard Worker .to_vec(); 260*e1997b9aSAndroid Build Coastguard Worker let data: [u8; 2] = decode_hex("af82"); 261*e1997b9aSAndroid Build Coastguard Worker 262*e1997b9aSAndroid Build Coastguard Worker let ed25519 = EdDsa::new(CipherSuite::CURVE25519_AES128).unwrap(); 263*e1997b9aSAndroid Build Coastguard Worker assert_matches!( 264*e1997b9aSAndroid Build Coastguard Worker ed25519.verify(&public_key, &sig_short, &data), 265*e1997b9aSAndroid Build Coastguard Worker Err(EdDsaError::InvalidSigLen { .. }) 266*e1997b9aSAndroid Build Coastguard Worker ); 267*e1997b9aSAndroid Build Coastguard Worker } 268*e1997b9aSAndroid Build Coastguard Worker 269*e1997b9aSAndroid Build Coastguard Worker #[test] unsupported_cipher_suites()270*e1997b9aSAndroid Build Coastguard Worker fn unsupported_cipher_suites() { 271*e1997b9aSAndroid Build Coastguard Worker for suite in vec![ 272*e1997b9aSAndroid Build Coastguard Worker CipherSuite::P256_AES128, 273*e1997b9aSAndroid Build Coastguard Worker CipherSuite::P384_AES256, 274*e1997b9aSAndroid Build Coastguard Worker CipherSuite::P521_AES256, 275*e1997b9aSAndroid Build Coastguard Worker CipherSuite::CURVE448_CHACHA, 276*e1997b9aSAndroid Build Coastguard Worker CipherSuite::CURVE448_AES256, 277*e1997b9aSAndroid Build Coastguard Worker ] { 278*e1997b9aSAndroid Build Coastguard Worker assert_matches!( 279*e1997b9aSAndroid Build Coastguard Worker EdDsa::new(suite).unwrap().signature_key_generate(), 280*e1997b9aSAndroid Build Coastguard Worker Err(EdDsaError::UnsupportedCipherSuite) 281*e1997b9aSAndroid Build Coastguard Worker ); 282*e1997b9aSAndroid Build Coastguard Worker } 283*e1997b9aSAndroid Build Coastguard Worker } 284*e1997b9aSAndroid Build Coastguard Worker } 285