#![deny(deprecated, drop_with_repr_extern, improper_ctypes,
non_shorthand_field_patterns, overflowing_literals, plugin_as_library,
private_no_mangle_fns, private_no_mangle_statics, stable_features, unconditional_recursion,
unknown_lints, unused, unused_allocation, unused_attributes,
unused_comparisons, unused_features, unused_parens, while_true)]
#![warn(missing_docs, trivial_casts, trivial_numeric_casts, unused, unused_extern_crates,
unused_import_braces, unused_qualifications, unused_results, variant_size_differences)]
extern crate libc;
pub mod params;
mod ffi;
use std::ptr;
use params::ParamSet;
pub fn generate_keys(params: &ParamSet) -> Option<(PrivateKey, PublicKey)> {
let (mut privkey_blob_len, mut pubkey_blob_len) = (0usize, 0usize);
let result = unsafe {
ffi::pq_gen_key(params,
&mut privkey_blob_len,
ptr::null_mut(),
&mut pubkey_blob_len,
ptr::null_mut())
};
if result != 0 {
return None;
}
let mut privkey_blob = vec![0u8; privkey_blob_len];
let mut pubkey_blob = vec![0u8; pubkey_blob_len];
let result = unsafe {
ffi::pq_gen_key(params,
&mut privkey_blob_len,
&mut privkey_blob[..][0],
&mut pubkey_blob_len,
&mut pubkey_blob[..][0])
};
if result != 0 {
None
} else {
Some((PrivateKey::import(privkey_blob.into_boxed_slice()),
PublicKey::import(pubkey_blob.into_boxed_slice())))
}
}
pub fn sign(private_key: &PrivateKey, public_key: &PublicKey, message: &[u8]) -> Option<Box<[u8]>> {
let mut sign_len = 0usize;
let result = unsafe {
ffi::pq_sign(&mut sign_len,
ptr::null_mut(),
private_key.get_bytes().len(),
&private_key.get_bytes()[0],
public_key.get_bytes().len(),
&public_key.get_bytes()[0],
message.len(),
&message[0])
};
if result != 0 {
return None;
}
let mut sign = vec![0u8; sign_len];
let result = unsafe {
ffi::pq_sign(&mut sign_len,
&mut sign[0],
private_key.get_bytes().len(),
&private_key.get_bytes()[0],
public_key.get_bytes().len(),
&public_key.get_bytes()[0],
message.len(),
&message[0])
};
if result != 0 {
None
} else {
Some(sign.into_boxed_slice())
}
}
pub fn verify(signature: &[u8], public_key: &PublicKey, message: &[u8]) -> bool {
let result = unsafe {
ffi::pq_verify(signature.len(),
&signature[0],
public_key.get_bytes().len(),
&public_key.get_bytes()[0],
message.len(),
&message[0])
};
result == 0
}
#[derive(PartialEq, Eq, Debug, Clone)]
pub struct PrivateKey {
ffi_key: Box<[u8]>,
}
impl PrivateKey {
fn import(bytes: Box<[u8]>) -> PrivateKey {
PrivateKey { ffi_key: bytes }
}
unsafe fn get_bytes(&self) -> &[u8] {
&self.ffi_key
}
}
#[derive(PartialEq, Eq, Debug, Clone)]
pub struct PublicKey {
ffi_key: Box<[u8]>,
}
impl PublicKey {
fn import(bytes: Box<[u8]>) -> PublicKey {
PublicKey { ffi_key: bytes }
}
unsafe fn get_bytes(&self) -> &[u8] {
&self.ffi_key
}
}