liboxyd 0.1.4

Coldwire's cryptographic library
Documentation
use crate::v1::secp256k1::{
    ecies::utils::{decapsulate, encapsulate},
    keys::generate_keypair,
};

use crate::v1::chacha20::sync::{decrypt as chacha20_decrypt, encrypt as chacha20_encrypt};
use libsecp256k1::{util::FULL_PUBLIC_KEY_SIZE, Error as SecpError, PublicKey, SecretKey};

pub async fn encrypt(receiver_pk: PublicKey, data: &[u8]) -> Result<Vec<u8>, SecpError> {
    let (ephemeral_sk, ephemeral_pk) = generate_keypair();

    let key = encapsulate(&ephemeral_sk, &receiver_pk)?;
    let encrypted = chacha20_encrypt(data, &key)
        .await
        .ok_or(SecpError::InvalidMessage)?;

    let mut cipher_text = Vec::with_capacity(FULL_PUBLIC_KEY_SIZE + encrypted.len());
    cipher_text.extend(ephemeral_pk.serialize().iter());
    cipher_text.extend(encrypted);

    Ok(cipher_text)
}

pub async fn decrypt(receiver_sk: SecretKey, data: &[u8]) -> Result<Vec<u8>, SecpError> {

    if data.len() < FULL_PUBLIC_KEY_SIZE {
        return Err(SecpError::InvalidMessage);
    }

    let ephemeral_pk = PublicKey::parse_slice(&data[..FULL_PUBLIC_KEY_SIZE], None)?;
    let encrypted = &data[FULL_PUBLIC_KEY_SIZE..];

    let key = decapsulate(&ephemeral_pk, &receiver_sk)?;

    chacha20_decrypt(encrypted, &key)
        .await
        .ok_or(SecpError::InvalidMessage)
}