sentc_crypto_std_keys/core/sign/
ed25519.rs1use alloc::vec::Vec;
2
3use ed25519_dalek::{Signature, Signer, SigningKey, Verifier, VerifyingKey};
4use hmac::digest::Digest;
5use rand_core::{CryptoRng, RngCore};
6use sentc_crypto_core::cryptomat::{Sig, SignK, SignKeyPair, SymKey, VerifyK};
7use sentc_crypto_core::{as_ref_bytes_single_value, crypto_alg_str_impl, into_bytes_single_value, try_from_bytes_owned_single_value, Error};
8
9use crate::core::sign::{SignKey, VerifyKey};
10use crate::get_rand;
11
12pub const SIG_LENGTH: usize = 64;
13
14pub const ED25519_OUTPUT: &str = "ED25519";
15
16pub struct Ed25519Sig([u8; 64]);
17crypto_alg_str_impl!(Ed25519Sig, ED25519_OUTPUT);
18try_from_bytes_owned_single_value!(Ed25519Sig);
19as_ref_bytes_single_value!(Ed25519Sig);
20into_bytes_single_value!(Ed25519Sig);
21
22impl Into<crate::core::sign::Signature> for Ed25519Sig
23{
24 fn into(self) -> crate::core::sign::Signature
25 {
26 crate::core::sign::Signature::Ed25519(self)
27 }
28}
29
30impl Sig for Ed25519Sig {}
31
32pub struct Ed25519VerifyK([u8; 32]);
33try_from_bytes_owned_single_value!(Ed25519VerifyK);
34crypto_alg_str_impl!(Ed25519VerifyK, ED25519_OUTPUT);
35as_ref_bytes_single_value!(Ed25519VerifyK);
36
37impl Into<VerifyKey> for Ed25519VerifyK
38{
39 fn into(self) -> VerifyKey
40 {
41 VerifyKey::Ed25519(self)
42 }
43}
44
45impl VerifyK for Ed25519VerifyK
46{
47 type Signature = Ed25519Sig;
48
49 fn verify<'a>(&self, data_with_sig: &'a [u8]) -> Result<(&'a [u8], bool), Error>
50 {
51 let (sig, data) = split_sig_and_data(data_with_sig)?;
52
53 Ok((data, verify_internally(&self.0, sig, data)?))
54 }
55
56 fn verify_only(&self, sig: &Self::Signature, data: &[u8]) -> Result<bool, Error>
57 {
58 verify_internally(&self.0, &sig.0, data)
59 }
60
61 fn create_hash<D: Digest>(&self, hasher: &mut D)
62 {
63 hasher.update(self.0)
64 }
65}
66
67pub struct Ed25519SignK([u8; 32]);
68try_from_bytes_owned_single_value!(Ed25519SignK);
69crypto_alg_str_impl!(Ed25519SignK, ED25519_OUTPUT);
70as_ref_bytes_single_value!(Ed25519SignK);
71
72impl Into<SignKey> for Ed25519SignK
73{
74 fn into(self) -> SignKey
75 {
76 SignKey::Ed25519(self)
77 }
78}
79
80impl SignK for Ed25519SignK
81{
82 type Signature = Ed25519Sig;
83
84 fn encrypt_by_master_key<M: SymKey>(&self, master_key: &M) -> Result<Vec<u8>, Error>
85 {
86 master_key.encrypt(&self.0)
87 }
88
89 fn sign(&self, data: &[u8]) -> Result<Vec<u8>, Error>
90 {
91 let sig = sign_internally(&self.0, data)?;
92
93 let mut output = Vec::with_capacity(sig.len() + data.len());
94 output.extend_from_slice(&sig);
95 output.extend_from_slice(data);
96
97 Ok(output)
98 }
99
100 fn sign_only<D: AsRef<[u8]>>(&self, data: D) -> Result<Self::Signature, Error>
101 {
102 let sig = sign_internally(&self.0, data.as_ref())?;
103
104 Ok(Ed25519Sig(sig))
105 }
106}
107
108pub struct Ed25519KeyPair;
109
110impl SignKeyPair for Ed25519KeyPair
111{
112 type SignKey = Ed25519SignK;
113 type VerifyKey = Ed25519VerifyK;
114
115 fn generate_key_pair() -> Result<(Self::SignKey, Self::VerifyKey), Error>
116 {
117 let (s, v) = generate_key_pair_internally(&mut get_rand())?;
118
119 Ok((Ed25519SignK(s), Ed25519VerifyK(v)))
120 }
121}
122
123pub(crate) fn split_sig_and_data(data_with_sig: &[u8]) -> Result<(&[u8], &[u8]), Error>
124{
125 sentc_crypto_core::split_sig_and_data(data_with_sig, SIG_LENGTH)
126}
127
128pub(super) fn generate_key_pair_internally<R: CryptoRng + RngCore>(rng: &mut R) -> Result<([u8; 32], [u8; 32]), Error>
132{
133 let sk = SigningKey::generate(rng);
134 let verify_key = sk.verifying_key().to_bytes();
135 let sign_key = sk.to_bytes();
136
137 Ok((sign_key, verify_key))
138}
139
140pub(super) fn sign_internally(sign_key: &[u8; 32], data: &[u8]) -> Result<[u8; 64], Error>
141{
142 let sk = SigningKey::from_bytes(sign_key);
143
144 let sig = sk.sign(data);
145
146 Ok(sig.to_bytes())
147}
148
149pub(super) fn verify_internally(verify_key: &[u8; 32], sig: &[u8], data: &[u8]) -> Result<bool, Error>
150{
151 let vk = VerifyingKey::from_bytes(verify_key).map_err(|_| Error::InitVerifyFailed)?;
152 let sig = Signature::try_from(sig).map_err(|_| Error::InitVerifyFailed)?;
153
154 let result = vk.verify(data, &sig);
155
156 match result {
157 Ok(()) => Ok(true),
158 Err(_e) => Ok(false),
159 }
160}
161
162#[cfg(test)]
163mod test
164{
165 use sentc_crypto_core::user::safety_number;
166 use sentc_crypto_core::Error::DataToSignTooShort;
167
168 use super::*;
169
170 #[test]
171 fn test_generate_keypair()
172 {
173 let _ = Ed25519KeyPair::generate_key_pair().unwrap();
174 }
175
176 #[test]
177 fn test_sign_and_verify()
178 {
179 let (sk, vk) = Ed25519KeyPair::generate_key_pair().unwrap();
180
181 let text = "Hello world üöäéèßê°";
182
183 let data_with_sig = sk.sign(text.as_bytes()).unwrap();
184
185 let (data, check) = vk.verify(&data_with_sig).unwrap();
186
187 assert!(check);
188 assert_eq!(data, text.as_bytes());
189 }
190
191 #[test]
192 fn test_wrong_verify()
193 {
194 let (_sk, vk) = Ed25519KeyPair::generate_key_pair().unwrap();
195 let (sk, _vk) = Ed25519KeyPair::generate_key_pair().unwrap();
196
197 let text = "Hello world üöäéèßê°";
198
199 let data_with_sig = sk.sign(text.as_bytes()).unwrap();
200
201 let (data, check) = vk.verify(&data_with_sig).unwrap();
202
203 assert!(!check);
204 assert_eq!(data, text.as_bytes());
205 }
206
207 #[test]
208 fn test_too_short_sig_bytes()
209 {
210 let (sk, vk) = Ed25519KeyPair::generate_key_pair().unwrap();
211 let text = "Hello world üöäéèßê°";
212
213 let data_with_sig = sk.sign(text.as_bytes()).unwrap();
214
215 let data_with_sig = &data_with_sig[..31];
216
217 let check_result = vk.verify(data_with_sig);
218
219 assert!(matches!(check_result, Err(DataToSignTooShort)));
220 }
221
222 #[test]
223 fn test_wrong_sig_bytes()
224 {
225 let (sk, vk) = Ed25519KeyPair::generate_key_pair().unwrap();
226 let text = "Hello world üöäéèßê°";
227
228 let data_with_sig = sk.sign(text.as_bytes()).unwrap();
229
230 let data_with_sig = &data_with_sig[..SIG_LENGTH + 2];
231
232 let (_data, check) = vk.verify(data_with_sig).unwrap();
233
234 assert!(!check);
235 }
236
237 #[test]
238 fn test_safety_number()
239 {
240 let (_sk, vk) = Ed25519KeyPair::generate_key_pair().unwrap();
241
242 let number = safety_number(&vk, "123", None, None);
243
244 assert_eq!(number.len(), 32);
245 }
246
247 #[test]
248 fn test_combined_safety_number()
249 {
250 let (_sk, vk) = Ed25519KeyPair::generate_key_pair().unwrap();
251 let (_sk1, vk1) = Ed25519KeyPair::generate_key_pair().unwrap();
252
253 let number = safety_number(&vk, "123", Some(&vk1), Some("321"));
254
255 assert_eq!(number.len(), 32);
256
257 let number_2 = safety_number(&vk1, "321", Some(&vk), Some("123"));
260
261 assert_eq!(number_2.len(), 32);
262
263 assert_ne!(number, number_2);
264 }
265}