1#![forbid(unsafe_code)]
2
3use ed448_goldilocks::{
10 signature::{Signer as Ed448Signer, Verifier as Ed448Verifier},
11 EdwardsScalarBytes, Signature, SigningKey, VerifyingKey,
12};
13use oxicrypto_core::{CryptoError, Vec};
14
15pub struct Ed448SigningKey {
19 signing_key: SigningKey,
20}
21
22impl Ed448SigningKey {
23 pub fn from_bytes(seed: &[u8]) -> Result<Self, CryptoError> {
25 let sk_bytes: [u8; 57] = seed.try_into().map_err(|_| CryptoError::InvalidKey)?;
26 let scalar = EdwardsScalarBytes::from(sk_bytes);
27 Ok(Self {
28 signing_key: SigningKey::from(scalar),
29 })
30 }
31
32 #[must_use = "signature result must be checked"]
34 pub fn sign(&self, message: &[u8]) -> Result<Vec<u8>, CryptoError> {
35 let sig: Signature = Ed448Signer::sign(&self.signing_key, message);
36 Ok(sig.to_bytes().to_vec())
37 }
38
39 #[must_use]
41 pub fn verifying_key_bytes(&self) -> [u8; 57] {
42 let vk: VerifyingKey = self.signing_key.verifying_key();
43 *vk.as_bytes()
44 }
45}
46
47pub struct Ed448VerifyingKey {
49 verifying_key: VerifyingKey,
50}
51
52impl Ed448VerifyingKey {
53 pub fn from_bytes(bytes: &[u8]) -> Result<Self, CryptoError> {
55 let pk_bytes: &[u8; 57] = bytes.try_into().map_err(|_| CryptoError::InvalidKey)?;
56 let verifying_key =
57 VerifyingKey::from_bytes(pk_bytes).map_err(|_| CryptoError::InvalidKey)?;
58 Ok(Self { verifying_key })
59 }
60
61 #[must_use = "verification result must be checked"]
63 pub fn verify(&self, message: &[u8], signature: &[u8]) -> Result<(), CryptoError> {
64 let sig_bytes: [u8; 114] = signature.try_into().map_err(|_| CryptoError::InvalidTag)?;
65 let sig = Signature::from_bytes(&sig_bytes);
66 Ed448Verifier::verify(&self.verifying_key, message, &sig)
67 .map_err(|_| CryptoError::InvalidTag)
68 }
69}