1use sodiumoxide::crypto::sign;
5use sodiumoxide::crypto::sign::ed25519::PublicKey as SodiumPublicKey;
6use sodiumoxide::crypto::sign::ed25519::SecretKey as SodiumPrivateKey;
7
8use sodiumoxide::crypto::secretbox;
9use sodiumoxide::crypto::secretbox::xsalsa20poly1305::Key as SodiumSecretKey;
10use sodiumoxide::crypto::secretbox::xsalsa20poly1305::Nonce as SodiumSecretNonce;
11use sodiumoxide::crypto::secretbox::xsalsa20poly1305::Tag as SodiumSecretTag;
12use sodiumoxide::crypto::secretbox::xsalsa20poly1305::{MACBYTES, NONCEBYTES};
13
14use sodiumoxide::crypto::hash::sha256;
15
16use crate::types::{CryptoHash, PrivateKey, PublicKey, SecretKey, Signature};
17
18pub fn new_pk() -> Result<(PublicKey, PrivateKey), ()> {
20 let (public_key, private_key) = sign::gen_keypair();
21 Ok((public_key.0.into(), private_key.0.into()))
22}
23
24pub fn pk_sign(private_key: &PrivateKey, data: &[u8]) -> Result<Signature, ()> {
26 let private_key = SodiumPrivateKey::from_slice(private_key).unwrap();
28 let sig = sign::sign_detached(data, &private_key);
30 Ok(sig.0.into())
32}
33
34pub fn pk_validate(public_key: &PublicKey, signature: &Signature, data: &[u8]) -> Result<bool, ()> {
36 let public_key = SodiumPublicKey::from_slice(public_key).unwrap();
38 let sig = sign::ed25519::Signature::from_slice(signature).unwrap();
40 Ok(sign::verify_detached(&sig, data, &public_key))
42}
43
44pub const SK_META: usize = MACBYTES + NONCEBYTES;
45
46pub fn new_sk() -> Result<SecretKey, ()> {
48 let key = secretbox::gen_key();
49 Ok(key.0.into())
50}
51
52pub fn sk_encrypt(secret_key: &SecretKey, message: &mut [u8]) -> Result<[u8; SK_META], ()> {
53 let secret_key = SodiumSecretKey::from_slice(secret_key).unwrap();
54 let nonce = secretbox::gen_nonce();
55
56 let tag = secretbox::seal_detached(message, &nonce, &secret_key);
58
59 let mut meta = [0u8; SK_META];
61 (&mut meta[..MACBYTES]).copy_from_slice(&tag.0);
62 (&mut meta[MACBYTES..]).copy_from_slice(&nonce.0);
63
64 Ok(meta)
65}
66
67pub fn sk_decrypt(secret_key: &SecretKey, meta: &[u8], message: &mut [u8]) -> Result<(), ()> {
68 let secret_key = SodiumSecretKey::from_slice(secret_key).unwrap();
69
70 let tag = SodiumSecretTag::from_slice(&meta[..MACBYTES]).unwrap();
72 let nonce = SodiumSecretNonce::from_slice(&meta[MACBYTES..]).unwrap();
73
74 secretbox::open_detached(message, &tag, &nonce, &secret_key)
76}
77
78pub fn sk_encrypt2<T>(secret_key: &SecretKey, mut buff: T, data_len: usize) -> Result<usize, ()>
81where
82 T: AsRef<[u8]> + AsMut<[u8]>,
83{
84 let data = buff.as_mut();
85
86 let secret_key = SodiumSecretKey::from_slice(secret_key).unwrap();
87 let nonce = secretbox::gen_nonce();
88
89 let tag = secretbox::seal_detached(&mut data[..data_len], &nonce, &secret_key);
91
92 let mut i = data_len;
94 (&mut data[i..i + MACBYTES]).copy_from_slice(&tag.0);
95 i += MACBYTES;
96 (&mut data[i..i + NONCEBYTES]).copy_from_slice(&nonce.0);
97
98 Ok(data_len + MACBYTES + NONCEBYTES)
99}
100
101pub fn sk_decrypt2<T>(secret_key: &SecretKey, mut buff: T) -> Result<usize, ()>
104where
105 T: AsRef<[u8]> + AsMut<[u8]>,
106{
107 let data = buff.as_mut();
108 let len = data.len() - NONCEBYTES - MACBYTES;
109
110 let secret_key = SodiumSecretKey::from_slice(secret_key).unwrap();
111
112 let mut i = len;
114 let tag = SodiumSecretTag::from_slice(&data[i..i + MACBYTES]).unwrap();
115 i += MACBYTES;
116 let nonce = SodiumSecretNonce::from_slice(&data[i..i + NONCEBYTES]).unwrap();
117
118 secretbox::open_detached(&mut data[..len], &tag, &nonce, &secret_key)?;
120
121 Ok(len)
122}
123
124pub fn hash(data: &[u8]) -> Result<CryptoHash, ()> {
126 let digest = sha256::hash(data);
127 Ok(digest.0.into())
128}
129
130#[cfg(test)]
131mod test {
132
133 use super::*;
134
135 #[test]
136 fn test_sign_verify() {
137 let (public, private) = new_pk().expect("Error generating public/private keypair");
138 let mut data = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
139
140 let signature = pk_sign(&private, &data).expect("Error generating signature");
141
142 let valid = pk_validate(&public, &signature, &data).expect("Error validating signature");
143 assert_eq!(true, valid);
144
145 data[3] = 100;
146 let valid = pk_validate(&public, &signature, &data).expect("Error validating signature");
147 assert_eq!(false, valid);
148 }
149
150 #[test]
151 fn test_encrypt_decrypt() {
152 let secret = new_sk().expect("Error generating secret key");
153 let data = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
154 let mut message = data.clone();
155
156 let meta = sk_encrypt(&secret, &mut message).expect("Error encrypting data");
157 assert!(data != message);
158
159 sk_decrypt(&secret, &meta, &mut message).expect("Error decrypting data");
160 assert_eq!(data, message);
161 }
162
163 #[test]
164 fn test_encrypt_decrypt2() {
165 let secret = new_sk().expect("Error generating secret key");
166 let data = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
167
168 let mut buff = data.clone();
169 buff.append(&mut vec![0u8; 128]);
170
171 let n = sk_encrypt2(&secret, &mut buff, data.len()).expect("Error encrypting data");
172 assert_eq!(n, data.len() + NONCEBYTES + MACBYTES);
173 assert!(data != &buff[..data.len()]);
174
175 let m = sk_decrypt2(&secret, &mut buff[..n]).expect("Error decrypting data");
176 assert_eq!(m, data.len());
177 assert_eq!(data, &buff[..m]);
178 }
179}