cypheron_core/sig/falcon/falcon1024/
engine.rs1use secrecy::{ExposeSecret, SecretBox};
16use std::ffi::c_void;
17use std::mem::MaybeUninit;
18
19use crate::sig::falcon::bindings::*;
20use crate::sig::falcon::errors::FalconErrors;
21use crate::sig::falcon::falcon1024::constants::*;
22use crate::sig::falcon::falcon1024::types::{
23 Falcon1024PublicKey, Falcon1024SecretKey, Falcon1024Signature, PublicKey, SecretKey, Signature,
24};
25use crate::sig::traits::SignatureEngine;
26use libc::c_int;
27
28#[derive(Debug, Clone, Copy, Default)]
29pub struct Falcon1024Engine;
30
31impl SignatureEngine for Falcon1024Engine {
32 type PublicKey = Falcon1024PublicKey;
33 type SecretKey = Falcon1024SecretKey;
34 type Signature = Falcon1024Signature;
35 type Error = FalconErrors;
36
37 fn keypair() -> Result<(Self::PublicKey, Self::SecretKey), Self::Error> {
38 let mut pk = [0u8; FALCON_PUBLIC];
39 let mut sk = [0u8; FALCON_SECRET];
40 let mut tmp = vec![0u8; FALCON_TMPSIZE_KEYGEN];
41 let mut rng = MaybeUninit::uninit();
42 let rng_result: c_int = unsafe { shake256_init_prng_from_system(rng.as_mut_ptr()) };
43
44 if rng_result != 0 {
45 return Err(FalconErrors::RngInitializationFailed);
46 }
47 let keygen_result: c_int = unsafe {
48 falcon_keygen_make(
49 rng.as_mut_ptr(),
50 FALCON_LOGN as u32,
51 sk.as_mut_ptr() as *mut c_void,
52 sk.len(),
53 pk.as_mut_ptr() as *mut c_void,
54 pk.len(),
55 tmp.as_mut_ptr() as *mut c_void,
56 tmp.len(),
57 )
58 };
59
60 if keygen_result != 0 {
61 return Err(FalconErrors::from_c_code(keygen_result, "keypair"));
62 }
63 Ok((PublicKey(pk), SecretKey(SecretBox::new(Box::from(sk)))))
64 }
65
66 fn sign(msg: &[u8], sk: &Self::SecretKey) -> Result<Self::Signature, Self::Error> {
67 let sk_bytes = sk.0.expose_secret();
68
69 let mut sig = [0u8; FALCON_SIGNATURE];
70 let mut siglen: usize = FALCON_SIGNATURE;
71 let mut tmp = vec![0u8; FALCON_TMPSIZE_SIGNDYN];
72 let mut rng = MaybeUninit::uninit();
73
74 let rng_result: c_int = unsafe { shake256_init_prng_from_system(rng.as_mut_ptr()) };
75 if rng_result != 0 {
76 return Err(FalconErrors::RngInitializationFailed);
77 }
78
79 let sign_result: c_int = unsafe {
80 falcon_sign_dyn(
81 rng.as_mut_ptr(),
82 sig.as_mut_ptr() as *mut _,
83 &mut siglen,
84 FALCON_SIG_COMPRESSED,
85 sk_bytes.as_ptr() as *const c_void,
86 sk_bytes.len(),
87 msg.as_ptr() as *const c_void,
88 msg.len(),
89 tmp.as_mut_ptr() as *mut c_void,
90 tmp.len(),
91 )
92 };
93
94 if sign_result != 0 {
95 return Err(FalconErrors::from_c_code(sign_result, "sign"));
96 }
97
98 let mut actual_sig = [0u8; FALCON_SIGNATURE];
99 actual_sig[..siglen].copy_from_slice(&sig[..siglen]);
100 if siglen < FALCON_SIGNATURE {
101 actual_sig[siglen..].fill(0);
102 }
103 Ok(Signature(actual_sig))
104 }
105
106 fn verify(msg: &[u8], sig: &Self::Signature, pk: &Self::PublicKey) -> bool {
107 let sig_bytes = &sig.0;
108 let pk_bytes = &pk.0;
109
110 let mut actual_sig_len = sig_bytes.len();
111 while actual_sig_len > 0 && sig_bytes[actual_sig_len - 1] == 0 {
112 actual_sig_len -= 1;
113 }
114
115 if actual_sig_len < 40 {
116 actual_sig_len = sig_bytes.len();
117 }
118
119 let mut tmp = vec![0u8; FALCON_TMPSIZE_VERIFY];
120
121 let verify_result: c_int = unsafe {
122 falcon_verify(
123 sig_bytes.as_ptr() as *const c_void,
124 actual_sig_len,
125 FALCON_SIG_COMPRESSED,
126 pk_bytes.as_ptr() as *const c_void,
127 pk_bytes.len(),
128 msg.as_ptr() as *const c_void,
129 msg.len(),
130 tmp.as_mut_ptr() as *mut c_void,
131 tmp.len(),
132 )
133 };
134 verify_result == 0
135 }
136}