trezor_crypto_lib/
test.rs

1//! Helpers to ensure ABI compatibility for use when testing
2
3pub use crate::UInt;
4use crate::{
5    consts::{PUBLIC_KEY_LENGTH, SECRET_KEY_LENGTH, SIGNATURE_LENGTH},
6    ffi, PublicKey, Scalar, SecretKey, Signature,
7};
8
9/// Driver ABI for dalek or donna impls
10#[allow(unused)]
11pub struct Driver {
12    pub ed25519_publickey: unsafe extern "C" fn(*mut SecretKey, *mut PublicKey),
13    pub ed25519_sign:
14        unsafe extern "C" fn(*const u8, UInt, *mut SecretKey, *mut PublicKey, *mut Signature),
15    pub ed25519_sign_open:
16        unsafe extern "C" fn(*const u8, UInt, *mut PublicKey, *mut Signature) -> i32,
17    pub ed25519_sign_open_batch: unsafe extern "C" fn(
18        *mut *const u8,
19        *mut UInt,
20        *mut *const u8,
21        *mut *const u8,
22        UInt,
23        *mut i32,
24    ) -> i32,
25
26    pub curved25519_scalarmult_basepoint: unsafe extern "C" fn(*mut Scalar, *mut Scalar),
27    pub curve25519_scalarmult: unsafe extern "C" fn(*mut Scalar, *mut SecretKey, *mut Scalar),
28
29    pub ed25519_publickey_ext:
30        unsafe extern "C" fn(sk: *mut SecretKey, sk_ext: *mut SecretKey, pk: *mut PublicKey),
31
32    pub ed25519_sign_ext: unsafe extern "C" fn(
33        m: *const u8,
34        mlen: UInt,
35        sk: *mut SecretKey,
36        sk_ext: *mut SecretKey,
37        pk: *mut PublicKey,
38        sig: *mut Signature,
39    ),
40}
41
42/// Donna driver implementation (via FFI)
43#[cfg(feature = "build_donna")]
44pub const DONNA: Driver = Driver {
45    ed25519_publickey: ffi::ed25519_publickey,
46    ed25519_sign_open: ffi::ed25519_sign_open,
47    ed25519_sign: ffi::ed25519_sign,
48    ed25519_sign_open_batch: ffi::ed25519_sign_open_batch,
49    curved25519_scalarmult_basepoint: ffi::curved25519_scalarmult_basepoint,
50    curve25519_scalarmult: ffi::curve25519_scalarmult,
51    ed25519_publickey_ext: ffi::ed25519_publickey_ext,
52    ed25519_sign_ext: ffi::ed25519_sign_ext,
53};
54
55/// Dalek driver implementation (native rust)
56pub const DALEK: Driver = Driver {
57    ed25519_publickey: crate::dalek_ed25519_publickey,
58    ed25519_sign_open: crate::dalek_ed25519_sign_open,
59    ed25519_sign: crate::dalek_ed25519_sign,
60    ed25519_sign_open_batch: crate::dalek_ed25519_sign_open_batch,
61    curved25519_scalarmult_basepoint: crate::dalek_curved25519_scalarmult_basepoint,
62    curve25519_scalarmult: crate::dalek_curve25519_scalarmult,
63    ed25519_publickey_ext: crate::dalek_ed25519_publickey_ext,
64    ed25519_sign_ext: crate::dalek_ed25519_sign_ext,
65};
66
67pub struct Batch<const N: usize, const M: usize = 128> {
68    pub secret_keys: [SecretKey; N],
69    pub public_keys: [PublicKey; N],
70    pub messages: [[u8; M]; N],
71    pub lengths: [UInt; N],
72    pub signatures: [Signature; N],
73}
74
75impl<const N: usize, const M: usize> Batch<N, M> {
76    /// Generate a collection for batch verification
77    pub fn new(signer: &Driver) -> Self {
78        let mut secret_keys = [[0u8; SECRET_KEY_LENGTH]; N];
79        let mut public_keys = [[0u8; PUBLIC_KEY_LENGTH]; N];
80
81        let mut messages = [[0u8; M]; N];
82        let mut signatures = [[0u8; SIGNATURE_LENGTH]; N];
83
84        for i in 0..N {
85            // Generate random secret key
86            getrandom::getrandom(&mut secret_keys[i]).unwrap();
87
88            // Generate matching public key
89            unsafe {
90                (signer.ed25519_publickey)(
91                    secret_keys[i].as_mut_ptr() as *mut SecretKey,
92                    public_keys[i].as_mut_ptr() as *mut PublicKey,
93                )
94            };
95
96            // Generate message
97            getrandom::getrandom(&mut messages[i]).unwrap();
98
99            // Generate signature
100            unsafe {
101                (signer.ed25519_sign)(
102                    messages[i].as_mut_ptr(),
103                    M as UInt,
104                    secret_keys[i].as_mut_ptr() as *mut SecretKey,
105                    public_keys[i].as_mut_ptr() as *mut PublicKey,
106                    signatures[i].as_mut_ptr() as *mut Signature,
107                )
108            };
109        }
110
111        Self {
112            secret_keys,
113            public_keys,
114            messages,
115            lengths: [M as UInt; N],
116            signatures,
117        }
118    }
119}