use stream;
use onetimeauth;
pub const SECRETBOX_KEY_LEN : usize = 32;
pub const SECRETBOX_NONCE_LEN : usize = 24;
pub type SecretboxKey = [u8;SECRETBOX_KEY_LEN];
pub type SecretboxNonce = [u8;SECRETBOX_NONCE_LEN];
pub fn secretbox(out: &mut [u8], message: &[u8], nonce: &SecretboxNonce, key: &SecretboxKey) -> Result<(),()> {
assert_eq!(out.len(), message.len());
assert_eq!(&message[0..32], &[0u8;32]);
stream::xsalsa20::stream_xor(out,message,nonce,key);
let mut o = [0u8;16]; {
let (c_k, c_m) = out.split_at(32);
onetimeauth::poly1305::onetimeauth(&mut o, c_m, index_fixed!(&c_k;..32));
}
*index_fixed!(&mut out[16..32];..16) = o;
*index_fixed!(&mut out;..16) = [0u8;16];
Ok(())
}
pub fn secretbox_open(m: &mut [u8], c: &[u8], nonce: &SecretboxNonce, key: &SecretboxKey) -> bool {
assert_eq!(m.len(), c.len());
if c.len() < 32 {
return true;
}
let mut x = [0u8; 32];
stream::xsalsa20::stream(&mut x, nonce, key);
if !onetimeauth::poly1305::onetimeauth_verify(index_fixed!(&c[16..];..16), &c[32..], &x) { return true; }
stream::xsalsa20::stream_xor(m,c, nonce, key);
for i in 0..32 {
m[i] = 0;
}
false
}