Basic Crypto
This commit is contained in:
parent
02f94993c7
commit
94f2280570
10 changed files with 568 additions and 79 deletions
|
|
@ -1,5 +1,7 @@
|
|||
use zeroize::{Zeroize, ZeroizeOnDrop};
|
||||
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[cfg_attr(feature = "serde", serde(transparent))]
|
||||
#[derive(Zeroize, ZeroizeOnDrop)]
|
||||
pub struct EncryptionPrivateKey(Vec<u8>);
|
||||
|
||||
|
|
@ -19,6 +21,8 @@ impl From<Vec<u8>> for EncryptionPrivateKey {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[cfg_attr(feature = "serde", serde(transparent))]
|
||||
#[derive(Zeroize, ZeroizeOnDrop)]
|
||||
pub struct SignaturePrivateKey(Vec<u8>);
|
||||
|
||||
|
|
@ -38,6 +42,8 @@ impl From<Vec<u8>> for SignaturePrivateKey {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[cfg_attr(feature = "serde", serde(transparent))]
|
||||
#[derive(Clone)]
|
||||
pub struct EncryptionPublicKey(Vec<u8>);
|
||||
|
||||
|
|
@ -57,6 +63,8 @@ impl From<Vec<u8>> for EncryptionPublicKey {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[cfg_attr(feature = "serde", serde(transparent))]
|
||||
#[derive(Clone)]
|
||||
pub struct SignaturePublicKey(Vec<u8>);
|
||||
|
||||
|
|
@ -102,6 +110,8 @@ impl KeyGroup {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[cfg_attr(feature = "serde", serde(transparent))]
|
||||
#[derive(Zeroize, ZeroizeOnDrop)]
|
||||
pub struct KemPrivateKey(Vec<u8>);
|
||||
|
||||
|
|
@ -121,6 +131,8 @@ impl From<Vec<u8>> for KemPrivateKey {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[cfg_attr(feature = "serde", serde(transparent))]
|
||||
#[derive(Clone)]
|
||||
pub struct KemPublicKey(Vec<u8>);
|
||||
|
||||
|
|
@ -140,6 +152,8 @@ impl From<Vec<u8>> for KemPublicKey {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[cfg_attr(feature = "serde", serde(transparent))]
|
||||
#[derive(Clone)]
|
||||
pub struct SignaturePqPublicKey(Vec<u8>);
|
||||
|
||||
|
|
@ -159,6 +173,8 @@ impl From<Vec<u8>> for SignaturePqPublicKey {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[cfg_attr(feature = "serde", serde(transparent))]
|
||||
#[derive(Zeroize, ZeroizeOnDrop)]
|
||||
pub struct SignaturePqPrivateKey(Vec<u8>);
|
||||
|
||||
|
|
@ -178,6 +194,7 @@ impl From<Vec<u8>> for SignaturePqPrivateKey {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[derive(ZeroizeOnDrop)]
|
||||
pub struct Keyring {
|
||||
#[zeroize(skip)]
|
||||
|
|
@ -209,4 +226,180 @@ impl Keyring {
|
|||
sig_cl_secret_key,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "mlkem-tls", feature = "ml-dsa", feature = "ed25519-dalek"))]
|
||||
pub fn generate() -> Self {
|
||||
let (kem_sk, kem_pk) = crate::kem::HybridKem::generate_keypair();
|
||||
|
||||
let (ed_signer, sig_cl_sk, sig_cl_pk) = crate::sign::Ed25519Signer::generate();
|
||||
let (_ml_signer, sig_pq_sk, sig_pq_pk) = crate::sign::MlDsaSigner::generate();
|
||||
|
||||
drop(ed_signer);
|
||||
|
||||
Self {
|
||||
kem_public_key: kem_pk,
|
||||
kem_secret_key: kem_sk,
|
||||
sig_pq_public_key: sig_pq_pk,
|
||||
sig_pq_secret_key: sig_pq_sk,
|
||||
sig_cl_public_key: sig_cl_pk,
|
||||
sig_cl_secret_key: sig_cl_sk,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[derive(Clone)]
|
||||
pub struct PublicKeyBundle {
|
||||
pub kem_public_key: KemPublicKey,
|
||||
pub sig_pq_public_key: SignaturePqPublicKey,
|
||||
pub sig_cl_public_key: SignaturePublicKey,
|
||||
}
|
||||
|
||||
impl PublicKeyBundle {
|
||||
pub fn new(
|
||||
kem_public_key: KemPublicKey,
|
||||
sig_pq_public_key: SignaturePqPublicKey,
|
||||
sig_cl_public_key: SignaturePublicKey,
|
||||
) -> Self {
|
||||
Self {
|
||||
kem_public_key,
|
||||
sig_pq_public_key,
|
||||
sig_cl_public_key,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_bytes(&self) -> Vec<u8> {
|
||||
let kem = self.kem_public_key.as_bytes();
|
||||
let pq = self.sig_pq_public_key.as_bytes();
|
||||
let cl = self.sig_cl_public_key.as_bytes();
|
||||
|
||||
let mut out = Vec::with_capacity(kem.len() + pq.len() + cl.len() + 6);
|
||||
out.extend_from_slice(&(kem.len() as u16).to_be_bytes());
|
||||
out.extend_from_slice(kem);
|
||||
out.extend_from_slice(&(pq.len() as u16).to_be_bytes());
|
||||
out.extend_from_slice(pq);
|
||||
out.extend_from_slice(&(cl.len() as u16).to_be_bytes());
|
||||
out.extend_from_slice(cl);
|
||||
out
|
||||
}
|
||||
|
||||
pub fn from_bytes(bytes: &[u8]) -> Result<Self, crate::error::CryptoError> {
|
||||
use crate::error::CryptoError;
|
||||
let mut offset = 0;
|
||||
|
||||
let kem_len = u16::from_be_bytes(
|
||||
bytes
|
||||
.get(offset..offset + 2)
|
||||
.ok_or(CryptoError::InvalidKeyLength)?
|
||||
.try_into()
|
||||
.unwrap(),
|
||||
) as usize;
|
||||
offset += 2;
|
||||
let kem = KemPublicKey::new(
|
||||
bytes
|
||||
.get(offset..offset + kem_len)
|
||||
.ok_or(CryptoError::InvalidKeyLength)?
|
||||
.to_vec(),
|
||||
);
|
||||
offset += kem_len;
|
||||
|
||||
let pq_len = u16::from_be_bytes(
|
||||
bytes
|
||||
.get(offset..offset + 2)
|
||||
.ok_or(CryptoError::InvalidKeyLength)?
|
||||
.try_into()
|
||||
.unwrap(),
|
||||
) as usize;
|
||||
offset += 2;
|
||||
let pq = SignaturePqPublicKey::new(
|
||||
bytes
|
||||
.get(offset..offset + pq_len)
|
||||
.ok_or(CryptoError::InvalidKeyLength)?
|
||||
.to_vec(),
|
||||
);
|
||||
offset += pq_len;
|
||||
|
||||
let cl_len = u16::from_be_bytes(
|
||||
bytes
|
||||
.get(offset..offset + 2)
|
||||
.ok_or(CryptoError::InvalidKeyLength)?
|
||||
.try_into()
|
||||
.unwrap(),
|
||||
) as usize;
|
||||
offset += 2;
|
||||
let cl = SignaturePublicKey::new(
|
||||
bytes
|
||||
.get(offset..offset + cl_len)
|
||||
.ok_or(CryptoError::InvalidKeyLength)?
|
||||
.to_vec(),
|
||||
);
|
||||
|
||||
Ok(Self {
|
||||
kem_public_key: kem,
|
||||
sig_pq_public_key: pq,
|
||||
sig_cl_public_key: cl,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Keyring {
|
||||
pub fn public_key_bundle(&self) -> PublicKeyBundle {
|
||||
PublicKeyBundle {
|
||||
kem_public_key: self.kem_public_key.clone(),
|
||||
sig_pq_public_key: self.sig_pq_public_key.clone(),
|
||||
sig_cl_public_key: self.sig_cl_public_key.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Serialize the full keyring (all six keys) into a byte vector.
|
||||
///
|
||||
/// Format: for each key, a 2-byte length prefix followed by the key bytes,
|
||||
/// in the order: kem_pk, kem_sk, sig_pq_pk, sig_pq_sk, sig_cl_pk, sig_cl_sk.
|
||||
pub fn to_bytes(&self) -> Vec<u8> {
|
||||
let fields: &[&[u8]] = &[
|
||||
self.kem_public_key.as_bytes(),
|
||||
self.kem_secret_key.as_bytes(),
|
||||
self.sig_pq_public_key.as_bytes(),
|
||||
self.sig_pq_secret_key.as_bytes(),
|
||||
self.sig_cl_public_key.as_bytes(),
|
||||
self.sig_cl_secret_key.as_bytes(),
|
||||
];
|
||||
let mut out = Vec::new();
|
||||
for f in fields {
|
||||
out.extend_from_slice(&(f.len() as u16).to_be_bytes());
|
||||
out.extend_from_slice(f);
|
||||
}
|
||||
out
|
||||
}
|
||||
|
||||
/// Deserialize a full keyring from bytes produced by [`Keyring::to_bytes`].
|
||||
pub fn from_bytes(bytes: &[u8]) -> Result<Self, crate::error::CryptoError> {
|
||||
use crate::error::CryptoError;
|
||||
let mut offset = 0;
|
||||
let read_key = |offset: &mut usize| -> Result<Vec<u8>, CryptoError> {
|
||||
let len = u16::from_be_bytes(
|
||||
bytes
|
||||
.get(*offset..*offset + 2)
|
||||
.ok_or(CryptoError::InvalidKeyLength)?
|
||||
.try_into()
|
||||
.unwrap(),
|
||||
) as usize;
|
||||
*offset += 2;
|
||||
let key = bytes
|
||||
.get(*offset..*offset + len)
|
||||
.ok_or(CryptoError::InvalidKeyLength)?
|
||||
.to_vec();
|
||||
*offset += len;
|
||||
Ok(key)
|
||||
};
|
||||
|
||||
Ok(Self {
|
||||
kem_public_key: KemPublicKey::new(read_key(&mut offset)?),
|
||||
kem_secret_key: KemPrivateKey::new(read_key(&mut offset)?),
|
||||
sig_pq_public_key: SignaturePqPublicKey::new(read_key(&mut offset)?),
|
||||
sig_pq_secret_key: SignaturePqPrivateKey::new(read_key(&mut offset)?),
|
||||
sig_cl_public_key: SignaturePublicKey::new(read_key(&mut offset)?),
|
||||
sig_cl_secret_key: SignaturePrivateKey::new(read_key(&mut offset)?),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue