pub use rust_sodium::crypto::box_::curve25519xsalsa20poly1305 as crypto_box;
pub use rust_sodium::crypto::hash::sha256;
pub use rust_sodium::crypto::scalarmult::curve25519 as scalarmult;
pub use self::crypto_box::{PrecomputedKey, PublicKey, SecretKey};
use auth_failure::AuthFailure;
pub const PASSWORD_DIGEST_BYTES: usize = sha256::DIGESTBYTES;
pub fn shared_secret_from_password(
password: &[u8],
my_perm_sk: &SecretKey,
their_perm_pk: &PublicKey,
) -> PrecomputedKey {
assert_eq!(scalarmult::SCALARBYTES, crypto_box::PUBLICKEYBYTES);
assert_eq!(scalarmult::GROUPELEMENTBYTES, crypto_box::SECRETKEYBYTES);
let product = scalarmult::scalarmult(
&scalarmult::Scalar::from_slice(&my_perm_sk.0).unwrap(),
&scalarmult::GroupElement::from_slice(&their_perm_pk.0).unwrap(),
)
.expect("their_perm_pk should not be zeroed");
let mut shared_secret_preimage = product.0.to_vec();
shared_secret_preimage.extend(&sha256::hash(password).0);
let shared_secret = sha256::hash(&shared_secret_preimage).0;
PrecomputedKey::from_slice(&shared_secret).unwrap()
}
pub fn shared_secret_from_keys(my_sk: &SecretKey, their_pk: &PublicKey) -> PrecomputedKey {
crypto_box::precompute(their_pk, my_sk)
}
pub fn open_packet_end(
packet_end: &[u8],
shared_secret: &PrecomputedKey,
nonce: &crypto_box::Nonce,
) -> Result<(PublicKey, Vec<u8>), AuthFailure> {
if packet_end.len() < crypto_box::MACBYTES {
return Err(AuthFailure::PacketTooShort(format!(
"Packet end: {}",
packet_end.len()
)));
}
match crypto_box::open_precomputed(packet_end, nonce, &shared_secret) {
Err(_) => Err(AuthFailure::CorruptedPacket(
"Could not decrypt handshake packet end.".to_owned(),
)),
Ok(buf) => {
let mut pk = [0u8; crypto_box::PUBLICKEYBYTES];
pk.copy_from_slice(&buf[0..crypto_box::PUBLICKEYBYTES]);
let their_temp_pk = PublicKey::from_slice(&pk).unwrap();
let data = buf[crypto_box::PUBLICKEYBYTES..].to_vec();
Ok((their_temp_pk, data))
}
}
}
pub fn gen_keypair() -> (PublicKey, SecretKey) {
crypto_box::gen_keypair()
}