1#[cfg(feature = "curve-ed25519")]
2impl<S> crate::PrivateKey<S>
3where
4 S: crate::Suite<E = generic_ec::curves::Ed25519>,
5{
6 pub fn from_eddsa_pkey_bytes(bytes: &[u8; 32]) -> Option<Self> {
13 use sha2::Digest as _;
14 let scalar_bytes = sha2::Sha512::new().chain_update(bytes).finalize();
15 let mut scalar_bytes = zeroize::Zeroizing::<[u8; 64]>::new(scalar_bytes.into());
16 let scalar_bytes = &mut scalar_bytes[0..32];
17
18 scalar_bytes[0] &= 0b1111_1000;
20 scalar_bytes[31] &= 0b0111_1111;
22 scalar_bytes[31] |= 0b0100_0000;
24
25 let mut scalar = generic_ec::Scalar::<generic_ec::curves::Ed25519>::from_le_bytes_mod_order(
26 scalar_bytes,
27 );
28 let scalar = generic_ec::SecretScalar::new(&mut scalar);
29 let scalar =
30 generic_ec::NonZero::<generic_ec::SecretScalar<generic_ec::curves::Ed25519>>::try_from(
31 scalar,
32 )
33 .ok()?;
34 Some(Self { scalar })
35 }
36}
37
38#[cfg(test)]
39macro_rules! make_tests {
40 ($specific_tests:tt) => {
41 mod common_test {
42 use std::ops::Deref as _;
43 type E = <super::S as crate::Suite>::E;
44
45 #[test]
46 fn encrypt_decrypt() {
47 let mut rng = rand_dev::DevRng::new();
48 let key = super::PrivateKey::generate(&mut rng);
49 let pubkey = key.public_key();
50
51 let original_message = {
52 let mut bytes = vec![0u8; 1337];
53 rand_core::RngCore::fill_bytes(&mut rng, &mut bytes);
54 bytes
55 };
56
57 let mut encrypted_message = pubkey.encrypt(&original_message, &mut rng).unwrap();
58
59 let parsed_message =
60 super::EncryptedMessage::from_bytes(&mut encrypted_message).unwrap();
61 let decrypted_message = key.decrypt_in_place(parsed_message).unwrap();
62
63 assert_eq!(original_message, decrypted_message);
64 }
65
66 #[test]
67 fn message_encode() {
68 let mut rng = rand_dev::DevRng::new();
69
70 let ephemeral_key = generic_ec::Point::generator()
71 * generic_ec::NonZero::<generic_ec::Scalar<E>>::random(&mut rng);
72 let mut message = [0u8; 322];
73 rand_core::RngCore::fill_bytes(&mut rng, &mut message);
74 let mut tag =
75 cipher::generic_array::GenericArray::<u8, crate::MacSize<super::S>>::default();
76 rand_core::RngCore::fill_bytes(&mut rng, &mut tag);
77
78 let message = super::EncryptedMessage {
79 ephemeral_key,
80 message: &mut message,
81 tag,
82 };
83 let mut message_bytes = message.to_bytes();
84 let restored = super::EncryptedMessage::from_bytes(&mut message_bytes).unwrap();
85 assert_eq!(message, restored);
86 }
87
88 #[test]
89 fn key_encode() {
90 let mut rng = rand_dev::DevRng::new();
91
92 let key = super::PrivateKey::generate(&mut rng);
93 let key_bytes = key.to_bytes();
94 let key_ = super::PrivateKey::from_bytes(&key_bytes).unwrap();
95 assert_eq!(key.scalar.deref().as_ref(), key_.scalar.deref().as_ref());
96
97 let pubkey = key.public_key();
98 let key_bytes = pubkey.to_bytes();
99 let pubkey_ = super::PublicKey::from_bytes(&key_bytes).unwrap();
100 assert_eq!(pubkey, pubkey_);
101 }
102
103 #[test]
104 fn from_bytes_too_short() {
105 let point = generic_ec::Point::<E>::generator().to_point();
106 let tag =
107 cipher::generic_array::GenericArray::<u8, crate::MacSize<super::S>>::default();
108
109 let mut buf = point.to_bytes(true).to_vec();
111 let compressed_len = buf.len();
112 buf.extend_from_slice(&tag);
113 for i in 0..buf.len() {
114 let result = super::EncryptedMessage::from_bytes(&mut buf[..i]);
115 assert!(
116 matches!(result, Err(crate::DeserializeError::TooShort)),
117 "expected TooShort for compressed input length {i}, got {result:?}",
118 );
119 }
120
121 let mut buf = point.to_bytes(false).to_vec();
123 buf.extend_from_slice(&tag);
124 for i in compressed_len..buf.len() {
125 let result = super::EncryptedMessage::from_bytes(&mut buf[..i]);
126 assert!(
127 matches!(result, Err(crate::DeserializeError::TooShort)),
128 "expected TooShort for uncompressed input length {i}, got {result:?}",
129 );
130 }
131 }
132
133 internal_make_specific_tests!($specific_tests);
134 }
135 };
136}
137#[cfg(test)]
138pub(crate) use make_tests;
139
140#[cfg(test)]
141macro_rules! internal_make_specific_tests {
142 ("stream") => {
143 #[test]
144 fn encrypt_decrypt_inplace_ornot() {
145 let mut rng = rand_dev::DevRng::new();
146 let key = super::PrivateKey::generate(&mut rng);
147 let pubkey = key.public_key();
148
149 let mut bytes = vec![0u8; 1337];
150 rand_core::RngCore::fill_bytes(&mut rng, &mut bytes);
151 let original = bytes.clone();
152
153 let mut encrypted = pubkey.encrypt(&bytes, &mut rng.clone()).unwrap();
154 let encrypted_ = pubkey
155 .encrypt_in_place(&mut bytes, &mut rng)
156 .unwrap()
157 .to_bytes();
158
159 assert_eq!(encrypted, encrypted_);
160
161 let encrypted = super::EncryptedMessage::from_bytes(&mut encrypted).unwrap();
162 let decrypted = key.decrypt(&encrypted).unwrap();
163 let decrypted_ = key.decrypt_in_place(encrypted).unwrap();
164 assert_eq!(decrypted_, decrypted);
165 assert_eq!(original, decrypted);
166 }
167 };
168 ("block") => {
169 #[test]
170 fn encrypt_decrypt_inplace_ornot() {
171 let mut rng = rand_dev::DevRng::new();
172 let key = super::PrivateKey::generate(&mut rng);
173 let pubkey = key.public_key();
174
175 let mut bytes = vec![0u8; 1337];
176 rand_core::RngCore::fill_bytes(&mut rng, &mut bytes);
177 let original = bytes.clone();
178
179 let mut encrypted = pubkey.encrypt(&bytes, &mut rng.clone()).unwrap();
180
181 let size_with_pad = bytes.len() + crate::pad_size::<super::S>(bytes.len());
182 bytes.resize(size_with_pad, 0);
183 let encrypted_ = pubkey
184 .encrypt_in_place(&mut bytes, original.len(), &mut rng)
185 .unwrap()
186 .to_bytes();
187
188 assert_eq!(encrypted, encrypted_);
189
190 let encrypted = super::EncryptedMessage::from_bytes(&mut encrypted).unwrap();
191 let decrypted = key.decrypt(&encrypted).unwrap();
192 let decrypted_ = key.decrypt_in_place(encrypted).unwrap();
193 assert_eq!(decrypted_, decrypted);
194 assert_eq!(original, decrypted);
195 }
196 };
197 ($($_:tt)*) => {
198 compile_error!("make_tests! macro only supports \"block\" and \"stream\" parameters");
199 };
200}