ntrumls/
lib.rs

1#![crate_type = "lib"]
2#![crate_type = "rlib"]
3#![crate_type = "dylib"]
4#![crate_name = "ntrumls"]
5
6// Coding conventions
7#![deny(non_upper_case_globals)]
8#![deny(non_camel_case_types)]
9#![deny(non_snake_case)]
10#![deny(unused_mut)]
11//#![warn(missing_docs)]
12
13#![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//impl Deref for PublicKey {
78//    type Target = [u8];
79//
80//    fn deref(&self) -> &[u8] {
81//        &self.0
82//    }
83//}
84//impl DerefMut for PublicKey {
85//    fn deref_mut(&mut self) -> &mut [u8] {
86//        &mut self.0
87//    }
88//}
89
90#[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//impl Deref for PrivateKey {
108//    type Target = [u8];
109//
110//    fn deref(&self) -> &[u8] {
111//        &self.0
112//    }
113//}
114//impl DerefMut for PrivateKey {
115//    fn deref_mut(&mut self) -> &mut [u8] {
116//        &mut self.0
117//    }
118//}
119
120#[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 {
126//        serializer.serialize_seq()
127        serializer.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
138//impl Deref for Signature {
139//    type Target = [u8];
140//
141//    fn deref(&self) -> &[u8] {
142//        &self.0
143//    }
144//}
145//impl DerefMut for Signature {
146//    fn deref_mut(&mut self) -> &mut [u8] {
147//        &mut self.0
148//    }
149//}
150
151pub enum PQParamSetID {
152   Security82Bit, // XXX_20151024_401
153   Security88Bit, // XXX_20151024_443
154   Security126Bit, // XXX_20151024_563
155   Security179Bit, // XXX_20151024_743
156   Security269Bit, // XXX_20151024_907
157}
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    /**
247    * Calculates keypair from 'fg' (concatenated ring elements 'f' and 'g')
248    */
249    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}