#![no_std]
extern crate tweetnacl_sys as sys;
#[cfg(test)]
extern crate rand;
pub fn hashblocks_sha512(state: &mut [u8; 64], data: &[u8]) -> usize {
let x = unsafe {
sys::crypto_hashblocks_sha512_tweet(
state.as_mut_ptr(),
data.as_ptr(),
data.len() as sys::c_ulonglong,
)
};
x as usize
}
pub fn hash_sha512(out: &mut [u8; 64], data: &[u8]) {
unsafe {
sys::crypto_hash_sha512_tweet(
out.as_mut_ptr(),
data.as_ptr(),
data.len() as sys::c_ulonglong,
)
};
}
pub fn core_salsa20(out: &mut [u8], inx: &[u8], k: &[u8], c: &[u8]) {
unsafe {
sys::crypto_core_salsa20_tweet(out.as_mut_ptr(), inx.as_ptr(), k.as_ptr(), c.as_ptr());
};
}
pub fn core_hsalsa20(out: &mut [u8], inx: &[u8], k: &[u8], c: &[u8]) {
unsafe {
sys::crypto_core_hsalsa20_tweet(out.as_mut_ptr(), inx.as_ptr(), k.as_ptr(), c.as_ptr());
};
}
pub fn stream_salsa20_xor(c: &mut [u8], m: Option<&[u8]>, n: &[u8], k: &[u8; 32]) {
m.map(|x| assert_eq!(x.len(), c.len()));
unsafe {
sys::crypto_stream_salsa20_tweet_xor(
c.as_mut_ptr(),
match m {
Some(v) => v.as_ptr(),
None => core::ptr::null(),
},
c.len() as sys::c_ulonglong,
n.as_ptr(),
k.as_ptr(),
)
};
}
pub fn onetimeauth(out: &mut [u8; 16], m: &[u8], k: &[u8; 32]) {
unsafe {
sys::crypto_onetimeauth_poly1305_tweet(
out.as_mut_ptr(),
m.as_ptr(),
m.len() as sys::c_ulonglong,
k.as_ptr(),
)
};
}
pub fn onetimeauth_verify(h: &[u8; 16], m: &[u8], k: &[u8; 32]) -> Result<(), ()> {
let x = unsafe {
sys::crypto_onetimeauth_poly1305_tweet_verify(
h.as_ptr(),
m.as_ptr(),
m.len() as sys::c_ulonglong,
k.as_ptr(),
)
};
match x {
0 => Ok(()),
_ => Err(()),
}
}
pub fn secretbox(out: &mut [u8], m: &[u8], n: &[u8; 24], k: &[u8; 32]) -> Result<(), ()> {
assert_eq!(out.len(), m.len());
let x = unsafe {
sys::crypto_secretbox_xsalsa20poly1305_tweet(
out.as_mut_ptr(),
m.as_ptr(),
m.len() as sys::c_ulonglong,
n.as_ptr(),
k.as_ptr(),
)
};
match x {
0 => Ok(()),
_ => Err(()),
}
}
pub fn secretbox_open(m: &mut [u8], c: &[u8], n: &[u8; 24], k: &[u8; 32]) -> Result<(), ()> {
assert_eq!(m.len(), c.len());
let x = unsafe {
sys::crypto_secretbox_xsalsa20poly1305_tweet_open(
m.as_mut_ptr(),
c.as_ptr(),
m.len() as sys::c_ulonglong,
n.as_ptr(),
k.as_ptr(),
)
};
match x {
0 => Ok(()),
_ => Err(()),
}
}
pub fn stream(c: &mut [u8], n: &[u8; 24], k: &[u8; 32]) {
unsafe {
sys::crypto_stream_xsalsa20_tweet(
c.as_mut_ptr(),
c.len() as sys::c_ulonglong,
n.as_ptr(),
k.as_ptr(),
)
};
}
pub fn stream_xor(c: &mut [u8], m: &[u8], n: &[u8; 24], k: &[u8; 32]) {
assert_eq!(c.len(), m.len());
unsafe {
sys::crypto_stream_xsalsa20_tweet_xor(
c.as_mut_ptr(),
m.as_ptr(),
c.len() as sys::c_ulonglong,
n.as_ptr(),
k.as_ptr(),
)
};
}
pub fn box_(c: &mut [u8], m: &[u8], n: &[u8; 24], y: &[u8; 32], x: &[u8; 32]) -> Result<(), ()> {
assert_eq!(c.len(), m.len());
let x = unsafe {
sys::crypto_box_curve25519xsalsa20poly1305_tweet(
c.as_mut_ptr(),
m.as_ptr(),
m.len() as sys::c_ulonglong,
n.as_ptr(),
y.as_ptr(),
x.as_ptr(),
)
};
match x {
0 => Ok(()),
_ => Err(()),
}
}
pub fn box_open(
m: &mut [u8],
c: &[u8],
n: &[u8; 24],
y: &[u8; 32],
x: &[u8; 32],
) -> Result<(), ()> {
assert_eq!(c.len(), m.len());
let x = unsafe {
sys::crypto_box_curve25519xsalsa20poly1305_tweet_open(
m.as_mut_ptr(),
c.as_ptr(),
c.len() as sys::c_ulonglong,
n.as_ptr(),
y.as_ptr(),
x.as_ptr(),
)
};
match x {
0 => Ok(()),
_ => Err(()),
}
}
pub fn scalarmult_base(q: &mut [u8; 32], n: &[u8; 32]) {
unsafe {
sys::crypto_scalarmult_curve25519_tweet_base(q.as_mut_ptr(), n.as_ptr());
};
}
pub fn scalarmult(q: &mut [u8; 32], n: &[u8; 32], p: &[u8; 32]) {
unsafe { sys::crypto_scalarmult_curve25519_tweet(q.as_mut_ptr(), n.as_ptr(), p.as_ptr()) };
}
pub fn sign(sm: &mut [u8], m: &[u8], sk: &[u8; 64]) -> usize {
assert_eq!(sm.len(), m.len() + 64);
let mut smlen: sys::c_ulonglong = sm.len() as sys::c_ulonglong;
unsafe {
sys::crypto_sign_ed25519_tweet(
sm.as_mut_ptr(),
&mut smlen,
m.as_ptr(),
m.len() as sys::c_ulonglong,
sk.as_ptr(),
)
};
smlen as usize
}
pub fn sign_open(m: &mut [u8], sm: &[u8], pk: &[u8; 32]) -> Result<usize, ()> {
assert_eq!(m.len(), sm.len());
let mut mlen = m.len() as sys::c_ulonglong;
let x = unsafe {
sys::crypto_sign_ed25519_tweet_open(
m.as_mut_ptr(),
&mut mlen,
sm.as_ptr(),
sm.len() as sys::c_ulonglong,
pk.as_ptr(),
)
};
match x {
0 => Ok(mlen as usize),
_ => Err(()),
}
}
pub fn sign_keypair(pk: &mut [u8; 32], sk: &mut [u8; 64]) {
unsafe { sys::crypto_sign_ed25519_tweet_keypair(pk.as_mut_ptr(), sk.as_mut_ptr()) };
}
pub fn sign_keypair_seed(pk: &mut [u8; 32], sk: &mut [u8; 64], seed: &[u8; 32]) {
unsafe {
sys::crypto_sign_ed25519_tweet_keypair_seed(pk.as_mut_ptr(), sk.as_mut_ptr(), seed.as_ptr())
};
}
pub fn mod_l(r: &mut [u8; 32], x: &mut [i64; 64]) {
let mut x_sys = [0 as sys::c_longlong; 64];
for (i, v) in x.into_iter().enumerate() {
x_sys[i] = *v as sys::c_longlong;
}
unsafe {
sys::crypto_modL_tweet(r.as_mut_ptr(), x_sys.as_mut_ptr());
};
for (i, v) in x_sys.iter().enumerate() {
x[i] = *v;
}
}
#[test]
fn hashblocks_sha512_twice_eq() {
use rand::{Rng, RngCore};
let mut rng = rand::thread_rng();
let len = rng.gen_range(core::usize::MIN, 1024);
let mut b_buf = [0u8; 1024];
let b = &mut b_buf[..len];
rng.fill_bytes(b);
let mut hash1 = [0u8; 64];
let v1 = hashblocks_sha512(&mut hash1, b);
let mut hash2 = [0u8; 64];
let v2 = hashblocks_sha512(&mut hash2, b);
assert_eq!(&hash1[..], &hash2[..]);
assert_eq!(v1, v2);
}