ling_crypto/
asymmetric.rs1use ed25519_dalek::{Signature, Signer, SigningKey, Verifier, VerifyingKey};
4use rand::rngs::OsRng;
5use x25519_dalek::{PublicKey, StaticSecret};
6use zeroize::Zeroizing;
7
8pub struct Ed25519Keypair {
11 signing_key: SigningKey,
12}
13
14impl Ed25519Keypair {
15 pub fn generate() -> Self {
16 Self { signing_key: SigningKey::generate(&mut OsRng) }
17 }
18
19 pub fn from_seed(seed: [u8; 32]) -> Self {
20 Self { signing_key: SigningKey::from_bytes(&seed) }
21 }
22
23 pub fn public_key(&self) -> [u8; 32] {
24 self.signing_key.verifying_key().to_bytes()
25 }
26
27 pub fn sign(&self, msg: &[u8]) -> [u8; 64] {
28 self.signing_key.sign(msg).to_bytes()
29 }
30
31 pub fn verify(pubkey: &[u8; 32], msg: &[u8], sig: &[u8; 64]) -> Result<(), &'static str> {
32 let vk = VerifyingKey::from_bytes(pubkey).map_err(|_| "invalid pubkey")?;
33 let signature = Signature::from_bytes(sig);
34 vk.verify(msg, &signature).map_err(|_| "signature invalid")
35 }
36
37 pub fn to_bytes(&self) -> Zeroizing<[u8; 32]> {
38 Zeroizing::new(self.signing_key.to_bytes())
39 }
40}
41
42pub struct X25519Secret {
45 secret: StaticSecret,
46}
47
48impl X25519Secret {
49 pub fn generate() -> Self {
50 Self { secret: StaticSecret::random_from_rng(OsRng) }
51 }
52
53 pub fn from_bytes(bytes: [u8; 32]) -> Self {
54 Self { secret: StaticSecret::from(bytes) }
55 }
56
57 pub fn public_key(&self) -> [u8; 32] {
58 PublicKey::from(&self.secret).to_bytes()
59 }
60
61 pub fn diffie_hellman(&self, their_pubkey: &[u8; 32]) -> [u8; 32] {
63 let their_pk = PublicKey::from(*their_pubkey);
64 self.secret.diffie_hellman(&their_pk).to_bytes()
65 }
66}