1#![cfg_attr(not(feature = "std"), no_std)]
7
8use cty::c_int;
9
10use curve25519_dalek::constants::ED25519_BASEPOINT_TABLE;
11use ed25519_dalek::{Signer, Verifier};
12
13#[cfg(feature = "build_donna")]
14pub mod ffi;
15
16#[cfg(feature = "build_donna")]
17pub mod test;
18
19pub mod consts {
21 pub const PUBLIC_KEY_LENGTH: usize = 32;
22 pub const SECRET_KEY_LENGTH: usize = 32;
23 pub const SIGNATURE_LENGTH: usize = 64;
24 pub const SCALAR_LENGTH: usize = 32;
25
26 static_assertions::const_assert_eq!(PUBLIC_KEY_LENGTH, ed25519_dalek::PUBLIC_KEY_LENGTH);
28 static_assertions::const_assert_eq!(SECRET_KEY_LENGTH, ed25519_dalek::SECRET_KEY_LENGTH);
29 static_assertions::const_assert_eq!(SIGNATURE_LENGTH, ed25519_dalek::SIGNATURE_LENGTH);
30}
31
32use crate::consts::*;
33
34#[cfg(target_pointer_width = "32")]
39pub type UInt = cty::c_uint;
40
41#[cfg(target_pointer_width = "64")]
43pub type UInt = cty::uint64_t;
44
45pub type PublicKey = [u8; PUBLIC_KEY_LENGTH];
47
48pub type SecretKey = [u8; SECRET_KEY_LENGTH];
50
51pub type Signature = [u8; SIGNATURE_LENGTH];
53
54pub type Scalar = [u8; SCALAR_LENGTH];
56
57#[no_mangle]
61pub extern "C" fn dalek_ed25519_publickey(sk: *mut SecretKey, pk: *mut PublicKey) {
62 let (sk, pk) = unsafe { (&(*sk), &mut (*pk)) };
63
64 let secret_key = match ed25519_dalek::SecretKey::from_bytes(sk) {
66 Ok(v) => v,
67 Err(_e) => {
68 pk.iter_mut().for_each(|v| *v = 0);
72
73 return;
74 }
75 };
76
77 let public_key = ed25519_dalek::PublicKey::from(&secret_key);
79 pk.copy_from_slice(public_key.as_bytes());
80}
81
82#[no_mangle]
86pub extern "C" fn dalek_ed25519_sign_open(
87 m: *const u8,
88 mlen: UInt,
89 pk: *mut PublicKey,
90 sig: *mut Signature,
91) -> c_int {
92 let (m, pk, sig) = unsafe {
94 (
95 core::slice::from_raw_parts(m, mlen as usize),
96 &(*pk),
97 &(*sig),
98 )
99 };
100
101 let public_key = match ed25519_dalek::PublicKey::from_bytes(pk) {
103 Ok(v) => v,
104 Err(_e) => {
105 return -1;
106 }
107 };
108 let signature = match ed25519_dalek::Signature::try_from(&sig[..]) {
109 Ok(v) => v,
110 Err(_e) => {
111 return -2;
112 }
113 };
114
115 if let Err(_e) = public_key.verify(m, &signature) {
117 return -3;
118 }
119
120 return 0;
121}
122
123#[no_mangle]
127pub extern "C" fn dalek_ed25519_sign(
128 m: *const u8,
129 mlen: UInt,
130 sk: *mut SecretKey,
131 pk: *mut PublicKey,
132 sig: *mut Signature,
133) {
134 let (m, sk, pk, sig) = unsafe {
136 (
137 core::slice::from_raw_parts(m, mlen as usize),
138 &(*sk),
139 &(*pk),
140 &mut (*sig),
141 )
142 };
143
144 let secret_key = match ed25519_dalek::SecretKey::from_bytes(sk) {
146 Ok(v) => v,
147 Err(_e) => return,
148 };
149 let public_key = match ed25519_dalek::PublicKey::from_bytes(pk) {
150 Ok(v) => v,
151 Err(_e) => return,
152 };
153
154 let keypair = ed25519_dalek::Keypair {
156 public: public_key,
157 secret: secret_key,
158 };
159
160 let signature = match keypair.try_sign(m) {
162 Ok(v) => v,
163 Err(_e) => {
164 sig.iter_mut().for_each(|v| *v = 0);
166 return;
167 }
168 };
169
170 sig.copy_from_slice(signature.as_ref());
172}
173
174#[no_mangle]
179pub extern "C" fn dalek_ed25519_sign_open_batch(
180 m: *mut *const u8,
181 mlen: *mut UInt,
182 pk: *mut *const u8,
183 rs: *mut *const u8,
184 num: UInt,
185 valid: *mut c_int,
186) -> c_int {
187 let (m, mlen, pk, rs, valid) = unsafe {
189 (
190 core::slice::from_raw_parts(m, num as usize),
191 core::slice::from_raw_parts(mlen, num as usize),
192 core::slice::from_raw_parts_mut(pk, num as usize),
193 core::slice::from_raw_parts_mut(rs, num as usize),
194 core::slice::from_raw_parts_mut(valid, num as usize),
195 )
196 };
197
198 let mut all_valid = 0;
199
200 valid.iter_mut().for_each(|v| *v = 1);
202
203 for i in 0..num as usize {
205 let v = dalek_ed25519_sign_open(
206 m[i],
207 mlen[i],
208 pk[i] as *mut PublicKey,
209 rs[i] as *mut Signature,
210 );
211 valid[i] = match v {
212 0 => 1,
213 _ => {
214 all_valid = 1;
215 0
216 }
217 };
218 }
219
220 all_valid
221}
222
223#[no_mangle]
226pub extern "C" fn dalek_ed25519_randombytes_unsafe(out: *mut u8, count: UInt) {
227 let buff = unsafe { core::slice::from_raw_parts_mut(out, count as usize) };
228 let _ = getrandom::getrandom(buff);
229}
230
231#[no_mangle]
235pub extern "C" fn dalek_curved25519_scalarmult_basepoint(pk: *mut Scalar, e: *mut Scalar) {
236 let (pk, e) = unsafe { (&mut (*pk), &(*e)) };
237
238 let mut ec = [0u8; 32];
240 ec.copy_from_slice(e);
241
242 ec[0] &= 248;
244 ec[31] &= 127;
245 ec[31] |= 64;
246
247 let s = curve25519_dalek::scalar::Scalar::from_bytes_mod_order(ec);
249
250 let p = &ED25519_BASEPOINT_TABLE * &s;
252
253 let u = p.to_montgomery();
256
257 pk.copy_from_slice(u.as_bytes());
259}
260
261#[no_mangle]
263pub extern "C" fn dalek_curve25519_scalarmult(
264 o: *mut PublicKey,
265 e: *mut SecretKey,
266 bp: *mut PublicKey,
267) {
268 let (o, e, bp) = unsafe { (&mut (*o), &(*e), &(*bp)) };
269
270 let mut ec = [0u8; 32];
272 ec.copy_from_slice(e);
273
274 let mut bpc = [0u8; 32];
276 bpc.copy_from_slice(bp);
277
278 ec[0] &= 248;
280 ec[31] &= 127;
281 ec[31] |= 64;
282
283 let p = { x25519_dalek::x25519(ec, bpc) };
285
286 o.copy_from_slice(&p);
288}
289
290#[no_mangle]
292pub extern "C" fn dalek_ed25519_publickey_ext(
293 sk: *mut SecretKey,
294 sk_ext: *mut SecretKey,
295 pk: *mut PublicKey,
296) {
297 let (sk, sk_ext, pk) = unsafe { (&(*sk), &(*sk_ext), &mut (*pk)) };
298
299 let mut sk_full = [0u8; 64];
301 sk_full[..32].copy_from_slice(sk);
302 sk_full[32..].copy_from_slice(sk_ext);
303
304 let expanded = match ed25519_dalek::ExpandedSecretKey::from_bytes(&sk_full) {
305 Ok(v) => v,
306 Err(_e) => return,
307 };
308
309 let public = ed25519_dalek::PublicKey::from(&expanded);
311
312 pk.copy_from_slice(public.as_ref());
313}
314
315#[no_mangle]
317pub extern "C" fn dalek_ed25519_sign_ext(
318 m: *const u8,
319 mlen: UInt,
320 sk: *mut SecretKey,
321 sk_ext: *mut SecretKey,
322 pk: *mut PublicKey,
323 sig: *mut Signature,
324) {
325 let (m, sk, sk_ext, pk, sig) = unsafe {
326 (
327 core::slice::from_raw_parts(m, mlen as usize),
328 &(*sk),
329 &(*sk_ext),
330 &(*pk),
331 &mut (*sig),
332 )
333 };
334
335 let mut sk_full = [0u8; 64];
337 sk_full[..32].copy_from_slice(sk);
338 sk_full[32..].copy_from_slice(sk_ext);
339
340 let secret_key = match ed25519_dalek::ExpandedSecretKey::from_bytes(&sk_full) {
341 Ok(k) => k,
342 Err(_e) => return,
343 };
344
345 let public_key = match ed25519_dalek::PublicKey::from_bytes(pk) {
346 Ok(v) => v,
347 Err(_e) => return,
348 };
349
350 let signature = secret_key.sign(m, &public_key);
352
353 sig.copy_from_slice(signature.as_ref());
355}