1use super::crypto_sign_ed25519::*;
57pub use super::crypto_sign_ed25519::{PublicKey, SecretKey};
58use crate::constants::CRYPTO_SIGN_BYTES;
59use crate::error::Error;
60
61pub fn crypto_sign_keypair_inplace(public_key: &mut PublicKey, secret_key: &mut SecretKey) {
63 crypto_sign_ed25519_keypair_inplace(public_key, secret_key)
64}
65
66pub fn crypto_sign_seed_keypair_inplace(
68 public_key: &mut PublicKey,
69 secret_key: &mut SecretKey,
70 seed: &[u8; 32],
71) {
72 crypto_sign_ed25519_seed_keypair_inplace(public_key, secret_key, seed)
73}
74
75pub fn crypto_sign_keypair() -> (PublicKey, SecretKey) {
78 crypto_sign_ed25519_keypair()
79}
80
81pub fn crypto_sign_seed_keypair(seed: &[u8; 32]) -> (PublicKey, SecretKey) {
84 crypto_sign_ed25519_seed_keypair(seed)
85}
86
87pub fn crypto_sign(
94 signed_message: &mut [u8],
95 message: &[u8],
96 secret_key: &SecretKey,
97) -> Result<(), Error> {
98 if signed_message.len() != message.len() + CRYPTO_SIGN_BYTES {
99 Err(dryoc_error!(format!(
100 "signed_message length incorrect (expect {}, got {})",
101 message.len() + CRYPTO_SIGN_BYTES,
102 signed_message.len()
103 )))
104 } else {
105 crypto_sign_ed25519(signed_message, message, secret_key)
106 }
107}
108
109pub fn crypto_sign_open(
116 message: &mut [u8],
117 signed_message: &[u8],
118 public_key: &PublicKey,
119) -> Result<(), Error> {
120 if signed_message.len() < CRYPTO_SIGN_BYTES {
121 Err(dryoc_error!(format!(
122 "signed_message length invalid ({} < {})",
123 signed_message.len(),
124 CRYPTO_SIGN_BYTES,
125 )))
126 } else if message.len() != signed_message.len() - CRYPTO_SIGN_BYTES {
127 Err(dryoc_error!(format!(
128 "message length incorrect (expect {}, got {})",
129 signed_message.len() - CRYPTO_SIGN_BYTES,
130 message.len()
131 )))
132 } else {
133 crypto_sign_ed25519_open(message, signed_message, public_key)
134 }
135}
136
137pub fn crypto_sign_detached(
143 signature: &mut Signature,
144 message: &[u8],
145 secret_key: &SecretKey,
146) -> Result<(), Error> {
147 crypto_sign_ed25519_detached(signature, message, secret_key)
148}
149
150pub fn crypto_sign_verify_detached(
156 signature: &Signature,
157 message: &[u8],
158 public_key: &PublicKey,
159) -> Result<(), Error> {
160 crypto_sign_ed25519_verify_detached(signature, message, public_key)
161}
162
163pub struct SignerState {
165 state: Ed25519SignerState,
166}
167
168pub fn crypto_sign_init() -> SignerState {
170 SignerState {
171 state: crypto_sign_ed25519ph_init(),
172 }
173}
174
175pub fn crypto_sign_update(state: &mut SignerState, message: &[u8]) {
177 crypto_sign_ed25519ph_update(&mut state.state, message)
178}
179
180pub fn crypto_sign_final_create(
183 state: SignerState,
184 signature: &mut Signature,
185 secret_key: &SecretKey,
186) -> Result<(), Error> {
187 crypto_sign_ed25519ph_final_create(state.state, signature, secret_key)
188}
189
190pub fn crypto_sign_final_verify(
193 state: SignerState,
194 signature: &Signature,
195 public_key: &PublicKey,
196) -> Result<(), Error> {
197 crypto_sign_ed25519ph_final_verify(state.state, signature, public_key)
198}
199
200#[cfg(test)]
201mod tests {
202 use super::*;
203
204 #[test]
205 fn test_crypto_sign() {
206 use base64::Engine as _;
207 use base64::engine::general_purpose;
208 use sodiumoxide::crypto::sign;
209
210 for _ in 0..10 {
211 let (public_key, secret_key) = crypto_sign_keypair();
212 let message = b"important message";
213 let mut signed_message = vec![0u8; message.len() + CRYPTO_SIGN_BYTES];
214 crypto_sign(&mut signed_message, message, &secret_key).expect("sign failed");
215
216 let so_signed_message = sign::sign(
217 message,
218 &sign::SecretKey::from_slice(&secret_key).expect("secret key failed"),
219 );
220
221 assert_eq!(
222 general_purpose::STANDARD.encode(&signed_message),
223 general_purpose::STANDARD.encode(&so_signed_message)
224 );
225
226 let so_m = sign::verify(
227 &signed_message,
228 &sign::PublicKey::from_slice(&public_key).expect("public key failed"),
229 )
230 .expect("verify failed");
231
232 assert_eq!(so_m, message);
233 }
234 }
235
236 #[test]
237 fn test_crypto_sign_open() {
238 use base64::Engine as _;
239 use base64::engine::general_purpose;
240 use sodiumoxide::crypto::sign;
241
242 for _ in 0..10 {
243 let (public_key, secret_key) = crypto_sign_keypair();
244 let message = b"important message";
245 let mut signed_message = vec![0u8; message.len() + CRYPTO_SIGN_BYTES];
246 crypto_sign(&mut signed_message, message, &secret_key).expect("sign failed");
247
248 let so_signed_message = sign::sign(
249 message,
250 &sign::SecretKey::from_slice(&secret_key).expect("secret key failed"),
251 );
252
253 assert_eq!(
254 general_purpose::STANDARD.encode(&signed_message),
255 general_purpose::STANDARD.encode(&so_signed_message)
256 );
257
258 let so_m = sign::verify(
259 &signed_message,
260 &sign::PublicKey::from_slice(&public_key).expect("public key failed"),
261 )
262 .expect("verify failed");
263
264 assert_eq!(so_m, message);
265
266 let mut opened_message = vec![0u8; message.len()];
267
268 crypto_sign_open(&mut opened_message, &signed_message, &public_key)
269 .expect("verify failed");
270
271 assert_eq!(opened_message, message);
272 }
273 }
274
275 #[test]
276 fn test_crypto_sign_detached() {
277 use sodiumoxide::crypto::sign;
278
279 for _ in 0..10 {
280 let (public_key, secret_key) = crypto_sign_keypair();
281 let message = b"important message";
282 let mut signature = [0u8; CRYPTO_SIGN_BYTES];
283 crypto_sign_detached(&mut signature, message, &secret_key).expect("sign failed");
284
285 assert!(sign::verify_detached(
286 &sign::ed25519::Signature::from_bytes(&signature).expect("secret key failed"),
287 message,
288 &sign::PublicKey::from_slice(&public_key).expect("public key failed"),
289 ));
290
291 crypto_sign_verify_detached(&signature, message, &public_key).expect("verify failed");
292 }
293 }
294
295 #[test]
296 fn test_crypto_sign_incremental() {
297 use sodiumoxide::crypto::sign;
298
299 use crate::rng::copy_randombytes;
300
301 for _ in 0..10 {
302 let (public_key, secret_key) = crypto_sign_keypair();
303 let mut signer = crypto_sign_init();
304 let mut verifier = crypto_sign_init();
305
306 let mut so_signer = sign::State::init();
307 let mut so_verifier = sign::State::init();
308
309 for _ in 0..3 {
310 let mut randos = vec![0u8; 100];
311 copy_randombytes(&mut randos);
312
313 crypto_sign_update(&mut signer, &randos);
314 crypto_sign_update(&mut verifier, &randos);
315
316 so_signer.update(&randos);
317 so_verifier.update(&randos);
318 }
319
320 let mut signature = [0u8; CRYPTO_SIGN_BYTES];
321 crypto_sign_final_create(signer, &mut signature, &secret_key)
322 .expect("final create failed");
323
324 let so_signature = so_signer
325 .finalize(&sign::SecretKey::from_slice(&secret_key).expect("secret key failed"));
326
327 assert_eq!(signature, so_signature.to_bytes());
328
329 crypto_sign_final_verify(verifier, &so_signature.to_bytes(), &public_key)
330 .expect("verify failed");
331
332 assert!(so_signer.verify(
333 &sign::ed25519::Signature::from_bytes(&signature).expect("secret key failed"),
334 &sign::PublicKey::from_slice(&public_key).expect("public key failed"),
335 ));
336 }
337 }
338}