sentc_crypto_std_keys/core/sign/
ed25519.rs

1use 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
128//__________________________________________________________________________________________________
129//internally function
130
131pub(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		//test the other way around
258
259		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}