1#![crate_type = "lib"]
2#![crate_type = "rlib"]
3#![crate_type = "dylib"]
4#![crate_name = "ntrumls"]
5
6#![deny(non_upper_case_globals)]
8#![deny(non_camel_case_types)]
9#![deny(non_snake_case)]
10#![deny(unused_mut)]
11#![cfg_attr(all(test, feature = "unstable"), feature(test))]
14
15extern crate libc;
16extern crate serde;
17extern crate serde_json;
18
19use serde::*;
20use serde::de;
21use serde::de::Visitor;
22use std::fmt;
23
24pub mod ffi;
25
26struct BytesVisitor {
27 bytes: Vec<u8>
28}
29
30impl BytesVisitor {
31 pub fn new() -> Self {
32 BytesVisitor {
33 bytes: Vec::new()
34 }
35 }
36}
37
38impl<'de> Visitor<'de> for BytesVisitor {
39 type Value = Vec<u8>;
40
41 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
42 write!(formatter, "failed to parse byte array")
43 }
44
45 fn visit_bytes<E>(self, v: &[u8]) -> Result<<Self as Visitor<'de>>::Value, E> where
46 E: de::Error, {
47 Ok(Vec::from(v))
48 }
49
50 fn visit_seq<A>(self, mut seq: A) -> Result<<Self as Visitor<'de>>::Value, <A as de::SeqAccess<'de>>::Error> where
51 A: de::SeqAccess<'de>, {
52 let mut vec = Vec::<u8>::with_capacity(seq.size_hint().unwrap_or(0));
53 while let Some(e) = seq.next_element()? {
54 vec.push(e);
55 }
56 Ok(vec)
57 }
58}
59
60#[derive(Debug, PartialEq, Eq, Clone)]
61pub struct PublicKey(pub Vec<u8>);
62
63impl Serialize for PublicKey {
64 fn serialize<S>(&self, serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error> where
65 S: Serializer {
66 serializer.serialize_bytes(&self.0)
67 }
68}
69
70impl<'de> Deserialize<'de> for PublicKey {
71 fn deserialize<D>(deserializer: D) -> Result<Self, <D as Deserializer<'de>>::Error> where
72 D: Deserializer<'de> {
73 Ok(PublicKey(deserializer.deserialize_byte_buf(BytesVisitor::new())?))
74 }
75}
76
77#[derive(Debug, PartialEq, Eq, Clone)]
91pub struct PrivateKey(pub Vec<u8>);
92
93impl Serialize for PrivateKey {
94 fn serialize<S>(&self, serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error> where
95 S: Serializer {
96 serializer.serialize_bytes(&self.0)
97 }
98}
99
100impl<'de> Deserialize<'de> for PrivateKey {
101 fn deserialize<D>(deserializer: D) -> Result<Self, <D as Deserializer<'de>>::Error> where
102 D: Deserializer<'de> {
103 Ok(PrivateKey(deserializer.deserialize_byte_buf(BytesVisitor::new())?))
104 }
105}
106
107#[derive(Debug, PartialEq, Eq, Clone)]
121pub struct Signature(pub Vec<u8>);
122
123impl Serialize for Signature {
124 fn serialize<S>(&self, serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error> where
125 S: Serializer {
126serializer.serialize_bytes(&self.0)
128 }
129}
130
131impl<'de> Deserialize<'de> for Signature {
132 fn deserialize<D>(deserializer: D) -> Result<Self, <D as Deserializer<'de>>::Error> where
133 D: Deserializer<'de> {
134 Ok(Signature(deserializer.deserialize_byte_buf(BytesVisitor::new())?))
135 }
136}
137
138pub enum PQParamSetID {
152 Security82Bit, Security88Bit, Security126Bit, Security179Bit, Security269Bit, }
158
159pub type PQParamSet = ffi::PQParamSet;
160
161pub struct NTRUMLS {
162 p: PQParamSet,
163 pubkey_packed_bytes_len: usize,
164 privkey_packed_bytes_len: usize,
165}
166
167impl NTRUMLS {
168 pub fn with_param_set(param_set: PQParamSetID) -> Self {
169 unsafe {
170 let p = match param_set {
171 PQParamSetID::Security82Bit => ffi::PQParamSetID::Xxx20151024n401,
172 PQParamSetID::Security88Bit => ffi::PQParamSetID::Xxx20151024n443,
173 PQParamSetID::Security126Bit => ffi::PQParamSetID::Xxx20151024n563,
174 PQParamSetID::Security179Bit => ffi::PQParamSetID::Xxx20151024n743,
175 PQParamSetID::Security269Bit => ffi::PQParamSetID::Xxx20151024n907,
176 };
177
178 let p = ffi::pq_get_param_set_by_id(p);
179 if p.is_null() {
180 panic!("Invalid PQParamSetID");
181 }
182
183 let p = (*p).clone();
184
185 let oid_bytes_len = std::mem::size_of::<[u8; 3]>();
186 let packed_product_from_bytes_len = ((2 * (p.d1 + p.d2 + p.d3) as usize * p.n_bits as usize + 7) / 8) as usize;
187 let packed_mod3_poly_bytes_len = (p.n + 4)/5;
188 let packed_mod_q_poly_bytes_len = (p.n * p.q_bits as u16 + 7)/8;
189 let hash_bytes_len = 64;
190
191 let pubkey_packed_bytes_len = 2 + oid_bytes_len + packed_mod_q_poly_bytes_len as usize + hash_bytes_len;
192 let privkey_packed_bytes_len = 2 + oid_bytes_len + 2 * packed_product_from_bytes_len as usize + packed_mod3_poly_bytes_len as usize;
193
194 NTRUMLS {
195 p,
196 pubkey_packed_bytes_len,
197 privkey_packed_bytes_len,
198 }
199 }
200 }
201
202 pub fn generate_keypair(&self) -> Option<(PrivateKey, PublicKey)> {
203 unsafe {
204 let p = &self.p;
205
206 let privkey_blob_len = &mut (self.privkey_packed_bytes_len as isize) as *mut isize;
207 let pubkey_blob_len = &mut (self.pubkey_packed_bytes_len as isize) as *mut isize;
208
209 let mut privkey_blob = vec![0u8; *privkey_blob_len as usize];
210 let mut pubkey_blob = vec![0u8; *pubkey_blob_len as usize];
211
212 let rc = ffi::pq_gen_key(p as *const PQParamSet,
213 privkey_blob_len, privkey_blob.as_mut_ptr(),
214 pubkey_blob_len, pubkey_blob.as_mut_ptr());
215 if rc != 0 {
216 return None;
217 }
218
219 return Some((PrivateKey(privkey_blob), PublicKey(pubkey_blob)));
220 }
221 }
222
223 pub fn unpack_fg_from_private_key(&self, sk: &PrivateKey) -> Option<Vec<u16>> {
224 let p = &self.p;
225
226 let product_form_bytes_len = 2*(p.d1 + p.d2 + p.d3) as usize;
227
228 let mut f_blob = vec![0u16; product_form_bytes_len as usize];
229 let mut g_blob = vec![0u16; product_form_bytes_len as usize];
230
231 unsafe {
232 let rc = ffi::unpack_private_key(p as *const PQParamSet, f_blob.as_mut_ptr(), g_blob.as_mut_ptr(),
233 std::ptr::null_mut(), self.privkey_packed_bytes_len as isize, sk.0.as_ptr());
234
235 if rc == 0 {
236 let mut vec = Vec::<u16>::new();
237 vec.splice(.., f_blob.iter().cloned());
238 let offset = vec.len();
239 vec.splice(offset.., g_blob.iter().cloned());
240 return Some(vec);
241 }
242 None
243 }
244 }
245
246 pub fn generate_keypair_from_fg(&self, fg: &[u16]) -> Option<(PrivateKey, PublicKey)> {
250 unsafe {
251 let p = &self.p;
252 let d = ((p.d1 + p.d2 + p.d3) * 4) as usize;
253 assert_eq!(d, fg.len());
254
255 let privkey_blob_len = &mut (self.privkey_packed_bytes_len as isize) as *mut isize;
256 let pubkey_blob_len = &mut (self.pubkey_packed_bytes_len as isize) as *mut isize;
257
258 let mut privkey_blob = vec![0u8; *privkey_blob_len as usize];
259 let mut pubkey_blob = vec![0u8; *pubkey_blob_len as usize];
260
261 let rc = ffi::pq_gen_key_fg(p as *const PQParamSet, fg.as_ptr(),
262 privkey_blob_len, privkey_blob.as_mut_ptr(),
263 pubkey_blob_len, pubkey_blob.as_mut_ptr());
264 if rc != 0 {
265 return None;
266 }
267
268 return Some((PrivateKey(privkey_blob), PublicKey(pubkey_blob)));
269 }
270 }
271
272 pub fn sign(&self, msg: &[u8], sk: &PrivateKey, pk: &PublicKey) -> Option<Signature> {
273 unsafe {
274 let p = &self.p;
275
276 let mut sig_len = (((p.n * (p.q_bits-1) as u16) + 7)/8) as usize;
277 let mut sig = vec![0u8; sig_len];
278
279 let rc = ffi::pq_sign(&mut sig_len as *mut usize, (&mut sig).as_mut_ptr(), sk.0.len(), sk.0.as_ptr(), pk.0.len(), pk.0.as_ptr(), msg.len(), msg.as_ptr());
280 if rc != 0 {
281 return None;
282 }
283
284 return Some(Signature(sig));
285 }
286 }
287
288 pub fn verify(&self, msg: &[u8], sig: &Signature, pk: &PublicKey) -> bool {
289 unsafe {
290 0 == ffi::pq_verify(sig.0.len(), sig.0.as_ptr(), pk.0.len(), pk.0.as_ptr(), msg.len(), msg.as_ptr())
291 }
292 }
293}
294
295#[cfg(test)]
296pub mod tests {
297 use super::NTRUMLS;
298 use serde_json;
299
300 #[test]
301 fn capabilities() {
302 let ntrumls = NTRUMLS::with_param_set(super::PQParamSetID::Security269Bit);
303 let (sk, pk) = ntrumls.generate_keypair().expect("failed to generate keypair");
304 let fg = ntrumls.unpack_fg_from_private_key(&sk).expect("failed to get Fg");
305 let (sk2, pk2) = ntrumls.generate_keypair_from_fg(&fg).expect("failed to generate keypair \
306 from Fg");
307
308 assert_eq!(sk, sk2);
309 assert_eq!(pk, pk2);
310
311 let msg = "TEST MESSAGE";
312 let sig = ntrumls.sign(msg.as_bytes(), &sk, &pk).expect("failed to generate signature");
313 assert!(ntrumls.verify(msg.as_bytes(), &sig, &pk));
314 }
315
316 #[test]
317 fn serde() {
318 let ntrumls = NTRUMLS::with_param_set(super::PQParamSetID::Security269Bit);
319 let (sk, pk) = ntrumls.generate_keypair().expect("failed to generate keypair");
320 let pk_se = serde_json::to_string(&pk).expect("failed to serialize public key");
321 let pk_de = serde_json::from_str::<::PublicKey>(&pk_se).expect("failed to deserialize public key");
322 let sk_se = serde_json::to_string(&sk).expect("failed to serialize private key");
323 let sk_de = serde_json::from_str::<::PrivateKey>(&sk_se).expect("failed to deserialize private key");
324 }
325}