1use base64::{engine::general_purpose, Engine as _};
2use data_encoding::BASE32;
3use ed25519_dalek::{Signature, SignatureError, Signer, SigningKey, Verifier, VerifyingKey};
4use serde::Serialize;
5
6pub fn sign_struct<T: Serialize>(message: T, signing_key: &SigningKey) -> Signature {
7 let mut data_to_sign = Vec::new();
8 ciborium::ser::into_writer(&message, &mut data_to_sign).expect("Serialization should not fail");
9 signing_key.sign(&data_to_sign)
10}
11
12pub fn verify_struct<T: Serialize>(
13 message: &T,
14 signature: &Signature,
15 verifying_key: &VerifyingKey,
16) -> Result<(), SignatureError> {
17 let mut data_to_sign = Vec::new();
18 ciborium::ser::into_writer(message, &mut data_to_sign).expect("Serialization should not fail");
19 verifying_key.verify(&data_to_sign, signature)
20}
21
22pub fn truncated_base64<T: AsRef<[u8]>>(data: T) -> String {
23 let encoded = general_purpose::STANDARD_NO_PAD.encode(data);
24 encoded.chars().take(10).collect()
25}
26
27pub fn truncated_base32(bytes: &[u8]) -> String {
28 let encoded = BASE32.encode(bytes);
29 encoded.chars().take(8).collect()
30}
31
32#[cfg(test)]
33mod tests {
34 use super::*;
35 use rand::rngs::OsRng;
36
37 #[test]
38 fn test_sign_verify_struct() {
39 let mut csprng = OsRng;
40 let signing_key = SigningKey::generate(&mut csprng);
41 let verifying_key = signing_key.verifying_key();
42
43 let message = "Hello, World!";
44 let signature = sign_struct(message, &signing_key);
45 assert!(verify_struct(&message, &signature, &verifying_key).is_ok());
46 }
47}