liboxyd 0.1.4

Coldwire's cryptographic library
Documentation
use libsecp256k1::{util::FULL_PUBLIC_KEY_SIZE, Error as SecpError, PublicKey, SecretKey};

use crate::v1::{chacha20::utils::XChaCha20Key, sha256};

/// Calculate a shared XChaCha20 key of our secret key and peer's public key by hkdf
pub fn encapsulate(sk: &SecretKey, peer_pk: &PublicKey) -> Result<XChaCha20Key, SecpError> {
    let mut shared_point = *peer_pk;
    shared_point.tweak_mul_assign(sk)?;

    let mut master = Vec::with_capacity(FULL_PUBLIC_KEY_SIZE * 2);
    master.extend(PublicKey::from_secret_key(sk).serialize().iter());
    master.extend(shared_point.serialize().iter());

    match sha256::hkdf(master.as_slice()) {
        Ok(out) => Ok(out),
        Err(_) => Err(SecpError::InvalidInputLength),
    }
}

/// Calculate a shared XChaCha20 key of our public key and peer's secret key by hkdf
pub fn decapsulate(pk: &PublicKey, peer_sk: &SecretKey) -> Result<XChaCha20Key, SecpError> {
    let mut shared_point = *pk;
    shared_point.tweak_mul_assign(peer_sk)?;

    let mut master = Vec::with_capacity(FULL_PUBLIC_KEY_SIZE * 2);
    master.extend(pk.serialize().iter());
    master.extend(shared_point.serialize().iter());

    match sha256::hkdf(master.as_slice()) {
        Ok(out) => Ok(out),
        Err(_) => Err(SecpError::InvalidInputLength),
    }
}