use aead::{
KeyInit, KeySizeUser,
generic_array::{GenericArray},
};
use curve25519_dalek::digest::generic_array::typenum::{U32};
use curve25519_dalek::{
ristretto::{CompressedRistretto}, };
use super::{SecretKey, PublicKey, Keypair, SignatureResult};
use crate::context::SigningTranscript;
use crate::cert::AdaptorCertPublic;
fn make_aead<T, AEAD>(mut t: T) -> AEAD
where
T: SigningTranscript,
AEAD: KeyInit,
{
let mut key: GenericArray<u8, <AEAD as KeySizeUser>::KeySize> = Default::default();
t.challenge_bytes(b"", key.as_mut_slice());
AEAD::new(&key)
}
impl SecretKey {
#[inline(always)]
pub(crate) fn raw_key_exchange(&self, public: &PublicKey) -> CompressedRistretto {
(self.key * public.as_point()).compress()
}
pub fn commit_raw_key_exchange<T>(&self, t: &mut T, ctx: &'static [u8], public: &PublicKey)
where
T: SigningTranscript,
{
let p = self.raw_key_exchange(public);
t.commit_point(ctx, &p);
}
pub fn aead32_unauthenticated<AEAD>(&self, public: &PublicKey) -> AEAD
where
AEAD: KeyInit<KeySize = U32>,
{
let mut key: GenericArray<u8, <AEAD as KeySizeUser>::KeySize> = Default::default();
key.clone_from_slice(self.raw_key_exchange(public).as_bytes());
AEAD::new(&key)
}
}
impl PublicKey {
pub fn init_aead_unauthenticated<AEAD: KeyInit>(
&self,
ctx: &[u8],
) -> (CompressedRistretto, AEAD) {
let ephemeral = Keypair::generate();
let aead = ephemeral.aead_unauthenticated(ctx, self);
(ephemeral.public.into_compressed(), aead)
}
pub fn init_aead32_unauthenticated<AEAD>(&self) -> (CompressedRistretto, AEAD)
where
AEAD: KeyInit<KeySize = U32>,
{
let secret = SecretKey::generate();
let aead = secret.aead32_unauthenticated(self);
(secret.to_public().into_compressed(), aead)
}
}
impl Keypair {
pub fn commit_key_exchange<T>(&self, t: &mut T, ctx: &'static [u8], public: &PublicKey)
where
T: SigningTranscript,
{
let mut pks = [self.public.as_compressed(), public.as_compressed()];
pks.sort_unstable_by_key(|pk| pk.as_bytes());
for pk in &pks {
t.commit_point(b"pk", pk);
}
self.secret.commit_raw_key_exchange(t, ctx, public);
}
pub fn aead_unauthenticated<AEAD: KeyInit>(&self, ctx: &[u8], public: &PublicKey) -> AEAD {
let mut t = merlin::Transcript::new(b"KEX");
t.append_message(b"ctx", ctx);
self.commit_key_exchange(&mut t, b"kex", public);
make_aead(t)
}
pub fn reciever_aead<T, AEAD>(
&self,
mut t: T,
ephemeral_pk: &PublicKey,
static_pk: &PublicKey,
) -> AEAD
where
T: SigningTranscript,
AEAD: KeyInit,
{
self.commit_key_exchange(&mut t, b"epk", ephemeral_pk);
self.commit_key_exchange(&mut t, b"epk", static_pk);
make_aead(t)
}
pub fn sender_aead<T, AEAD>(&self, mut t: T, public: &PublicKey) -> (CompressedRistretto, AEAD)
where
T: SigningTranscript,
AEAD: KeyInit,
{
let key = t.witness_scalar(b"make_esk", &[&self.secret.nonce]);
let ekey = SecretKey { key, nonce: self.secret.nonce }.to_keypair();
ekey.commit_key_exchange(&mut t, b"epk", public);
self.commit_key_exchange(&mut t, b"epk", public);
(ekey.public.into_compressed(), make_aead(t))
}
pub fn reciever_aead_with_adaptor_cert<T, AEAD>(
&self,
t: T,
cert_public: &AdaptorCertPublic,
public: &PublicKey,
) -> SignatureResult<AEAD>
where
T: SigningTranscript,
AEAD: KeyInit,
{
let epk = public.open_adaptor_cert(t, cert_public)?;
Ok(self.aead_unauthenticated(b"", &epk))
}
pub fn sender_aead_with_adaptor_cert<T, AEAD>(
&self,
t: T,
public: &PublicKey,
) -> (AdaptorCertPublic, AEAD)
where
T: SigningTranscript + Clone,
AEAD: KeyInit,
{
let (cert, secret) = self.issue_self_adaptor_cert(t);
let aead = secret.to_keypair().aead_unauthenticated(b"", public);
(cert, aead)
}
}