#[cfg(feature = "alloc")]
use zeroize::{
Zeroize,
ZeroizeOnDrop,
};
use crate::error::Result;
#[cfg(feature = "alloc")]
extern crate alloc;
#[cfg(feature = "alloc")]
use alloc::vec::Vec;
#[cfg(feature = "wasm")]
use js_sys::Uint8Array;
#[cfg(feature = "wasm")]
use wasm_bindgen::prelude::*;
pub trait Kem {
fn generate_keypair(&self) -> Result<KemKeypair>;
#[cfg(feature = "alloc")]
fn encapsulate(&self, public_key: &KemPublicKey) -> Result<(Vec<u8>, Vec<u8>)>;
#[cfg(not(feature = "alloc"))]
fn encapsulate(&self, public_key: &KemPublicKey) -> Result<(&'static [u8], &'static [u8])>;
#[cfg(feature = "alloc")]
fn decapsulate(&self, secret_key: &KemSecretKey, ciphertext: &[u8]) -> Result<Vec<u8>>;
#[cfg(not(feature = "alloc"))]
fn decapsulate(&self, secret_key: &KemSecretKey, ciphertext: &[u8]) -> Result<&'static [u8]>;
#[cfg(feature = "alloc")]
fn derive_public_key(&self, secret_key: &KemSecretKey) -> Result<KemPublicKey>;
#[cfg(not(feature = "alloc"))]
fn derive_public_key(&self, secret_key: &KemSecretKey) -> Result<KemPublicKey>;
#[cfg(feature = "alloc")]
fn auth_encapsulate(
&self,
sender_sk: &KemSecretKey,
recipient_pk: &KemPublicKey,
) -> Result<(Vec<u8>, Vec<u8>)>;
#[cfg(not(feature = "alloc"))]
fn auth_encapsulate(
&self,
sender_sk: &KemSecretKey,
recipient_pk: &KemPublicKey,
) -> Result<(&'static [u8], &'static [u8])>;
#[cfg(feature = "alloc")]
fn auth_decapsulate(
&self,
recipient_sk: &KemSecretKey,
ciphertext: &[u8],
sender_pk: &KemPublicKey,
) -> Result<Vec<u8>>;
#[cfg(not(feature = "alloc"))]
fn auth_decapsulate(
&self,
recipient_sk: &KemSecretKey,
ciphertext: &[u8],
sender_pk: &KemPublicKey,
) -> Result<&'static [u8]>;
}
pub trait Signature {
fn generate_keypair(&self) -> Result<SigKeypair>;
#[cfg(feature = "alloc")]
fn sign(&self, secret_key: &SigSecretKey, message: &[u8]) -> Result<Vec<u8>>;
#[cfg(not(feature = "alloc"))]
fn sign(&self, secret_key: &SigSecretKey, message: &[u8]) -> Result<&'static [u8]>;
fn verify(&self, public_key: &SigPublicKey, message: &[u8], signature: &[u8]) -> Result<bool>;
}
pub trait Hash {
#[cfg(feature = "alloc")]
fn hash(&self, data: &[u8]) -> Result<Vec<u8>>;
#[cfg(not(feature = "alloc"))]
fn hash(&self, data: &[u8]) -> Result<&'static [u8]>;
fn output_size(&self) -> usize;
}
pub trait Aead {
#[cfg(feature = "alloc")]
fn encrypt(
&self,
key: &AeadKey,
nonce: &Nonce,
plaintext: &[u8],
associated_data: Option<&[u8]>,
) -> Result<Vec<u8>>;
#[cfg(not(feature = "alloc"))]
fn encrypt(
&self,
key: &AeadKey,
nonce: &Nonce,
plaintext: &[u8],
associated_data: Option<&[u8]>,
) -> Result<&'static [u8]>;
#[cfg(feature = "alloc")]
fn decrypt(
&self,
key: &AeadKey,
nonce: &Nonce,
ciphertext: &[u8],
associated_data: Option<&[u8]>,
) -> Result<Vec<u8>>;
#[cfg(not(feature = "alloc"))]
fn decrypt(
&self,
key: &AeadKey,
nonce: &Nonce,
ciphertext: &[u8],
associated_data: Option<&[u8]>,
) -> Result<&'static [u8]>;
}
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "wasm", wasm_bindgen)]
pub struct KemKeypair {
#[cfg_attr(feature = "wasm", wasm_bindgen(skip))]
pub public_key: KemPublicKey,
#[cfg_attr(feature = "wasm", wasm_bindgen(skip))]
pub secret_key: KemSecretKey,
}
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "wasm", wasm_bindgen)]
pub struct KemPublicKey {
#[cfg_attr(feature = "wasm", wasm_bindgen(skip))]
#[cfg(feature = "alloc")]
pub data: Vec<u8>,
#[cfg(not(feature = "alloc"))]
pub data: &'static [u8],
}
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "wasm", wasm_bindgen)]
pub struct KemSecretKey {
#[cfg_attr(feature = "wasm", wasm_bindgen(skip))]
#[cfg(feature = "alloc")]
pub data: Vec<u8>,
#[cfg_attr(feature = "wasm", wasm_bindgen(skip))]
#[cfg(not(feature = "alloc"))]
pub data: &'static [u8],
}
#[cfg(feature = "alloc")]
impl Zeroize for KemSecretKey {
fn zeroize(&mut self) {
self.data.zeroize();
}
}
#[cfg(feature = "alloc")]
impl ZeroizeOnDrop for KemSecretKey {}
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "wasm", wasm_bindgen)]
pub struct SigKeypair {
#[cfg_attr(feature = "wasm", wasm_bindgen(skip))]
pub public_key: SigPublicKey,
#[cfg_attr(feature = "wasm", wasm_bindgen(skip))]
pub secret_key: SigSecretKey,
}
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "wasm", wasm_bindgen)]
pub struct SigPublicKey {
#[cfg_attr(feature = "wasm", wasm_bindgen(skip))]
#[cfg(feature = "alloc")]
pub data: Vec<u8>,
#[cfg_attr(feature = "wasm", wasm_bindgen(skip))]
#[cfg(not(feature = "alloc"))]
pub data: &'static [u8],
}
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "wasm", wasm_bindgen)]
pub struct SigSecretKey {
#[cfg_attr(feature = "wasm", wasm_bindgen(skip))]
#[cfg(feature = "alloc")]
pub data: Vec<u8>,
#[cfg_attr(feature = "wasm", wasm_bindgen(skip))]
#[cfg(not(feature = "alloc"))]
pub data: &'static [u8],
}
#[cfg(feature = "alloc")]
impl Zeroize for SigSecretKey {
fn zeroize(&mut self) {
self.data.zeroize();
}
}
#[cfg(feature = "alloc")]
impl ZeroizeOnDrop for SigSecretKey {}
pub struct AeadKey {
#[cfg(feature = "alloc")]
pub data: Vec<u8>,
#[cfg(not(feature = "alloc"))]
pub data: &'static [u8],
}
#[cfg(feature = "alloc")]
impl Zeroize for AeadKey {
fn zeroize(&mut self) {
self.data.zeroize();
}
}
#[cfg(feature = "alloc")]
impl ZeroizeOnDrop for AeadKey {}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Nonce {
#[cfg(feature = "alloc")]
pub data: Vec<u8>,
#[cfg(not(feature = "alloc"))]
pub data: &'static [u8],
}
impl KemKeypair {
#[cfg(feature = "alloc")]
pub fn new(public_key: Vec<u8>, secret_key: Vec<u8>) -> Self {
Self {
public_key: KemPublicKey { data: public_key },
secret_key: KemSecretKey { data: secret_key },
}
}
#[cfg(not(feature = "alloc"))]
pub fn new(public_key: &'static [u8], secret_key: &'static [u8]) -> Self {
Self {
public_key: KemPublicKey { data: public_key },
secret_key: KemSecretKey { data: secret_key },
}
}
pub fn public_key(&self) -> &KemPublicKey {
&self.public_key
}
pub fn secret_key(&self) -> &KemSecretKey {
&self.secret_key
}
}
#[cfg(feature = "wasm")]
#[wasm_bindgen]
impl KemKeypair {
#[wasm_bindgen(constructor)]
pub fn new_wasm(public_key: Vec<u8>, secret_key: Vec<u8>) -> KemKeypair {
Self::new(public_key, secret_key)
}
pub fn public_key_bytes(&self) -> Vec<u8> {
self.public_key.data.to_vec()
}
pub fn secret_key_bytes(&self) -> Uint8Array {
let n =
u32::try_from(self.secret_key.data.len()).expect("KEM secret key length fits in u32");
let out = Uint8Array::new_with_length(n);
out.copy_from(&self.secret_key.data);
out
}
}
impl SigKeypair {
#[cfg(feature = "alloc")]
pub fn new(public_key: Vec<u8>, secret_key: Vec<u8>) -> Self {
Self {
public_key: SigPublicKey { data: public_key },
secret_key: SigSecretKey { data: secret_key },
}
}
#[cfg(not(feature = "alloc"))]
pub fn new(public_key: &'static [u8], secret_key: &'static [u8]) -> Self {
Self {
public_key: SigPublicKey { data: public_key },
secret_key: SigSecretKey { data: secret_key },
}
}
pub fn public_key(&self) -> &SigPublicKey {
&self.public_key
}
pub fn secret_key(&self) -> &SigSecretKey {
&self.secret_key
}
}
impl KemPublicKey {
#[cfg(feature = "alloc")]
pub fn new(data: Vec<u8>) -> Self {
Self { data }
}
#[cfg(not(feature = "alloc"))]
pub fn new(data: &'static [u8]) -> Self {
Self { data }
}
pub fn as_bytes(&self) -> &[u8] {
&self.data
}
}
#[cfg(feature = "wasm")]
#[wasm_bindgen]
impl KemPublicKey {
#[wasm_bindgen(constructor)]
pub fn new_from_bytes(data: Vec<u8>) -> KemPublicKey {
Self::new(data)
}
pub fn bytes(&self) -> Vec<u8> {
self.data.to_vec()
}
}
impl KemSecretKey {
#[cfg(feature = "alloc")]
pub fn new(data: Vec<u8>) -> Self {
Self { data }
}
#[cfg(not(feature = "alloc"))]
pub fn new(data: &'static [u8]) -> Self {
Self { data }
}
pub fn as_bytes(&self) -> &[u8] {
&self.data
}
}
#[cfg(feature = "wasm")]
#[wasm_bindgen]
impl KemSecretKey {
#[wasm_bindgen(constructor)]
pub fn new_from_bytes(data: Vec<u8>) -> KemSecretKey {
Self::new(data)
}
pub fn bytes(&self) -> Uint8Array {
let n = u32::try_from(self.data.len()).expect("KEM secret key length fits in u32");
let out = Uint8Array::new_with_length(n);
out.copy_from(&self.data);
out
}
}
impl SigPublicKey {
#[cfg(feature = "alloc")]
pub fn new(data: Vec<u8>) -> Self {
Self { data }
}
#[cfg(not(feature = "alloc"))]
pub fn new(data: &'static [u8]) -> Self {
Self { data }
}
pub fn as_bytes(&self) -> &[u8] {
&self.data
}
}
impl SigSecretKey {
#[cfg(feature = "alloc")]
pub fn new(data: Vec<u8>) -> Self {
Self { data }
}
#[cfg(not(feature = "alloc"))]
pub fn new(data: &'static [u8]) -> Self {
Self { data }
}
pub fn as_bytes(&self) -> &[u8] {
&self.data
}
}
impl AeadKey {
#[cfg(feature = "alloc")]
pub fn new(data: Vec<u8>) -> Self {
Self { data }
}
#[cfg(not(feature = "alloc"))]
pub fn new(data: &'static [u8]) -> Self {
Self { data }
}
pub fn as_bytes(&self) -> &[u8] {
&self.data
}
}
impl Nonce {
#[cfg(feature = "alloc")]
pub fn new(data: Vec<u8>) -> Self {
Self { data }
}
#[cfg(not(feature = "alloc"))]
pub fn new(data: &'static [u8]) -> Self {
Self { data }
}
pub fn as_bytes(&self) -> &[u8] {
&self.data
}
}