use serde::{Deserialize, Serialize};
use crate::crypto::Rng;
use crate::crypto::x25519::{PUBLIC_KEY_SIZE, PublicKey, SecretKey};
use crate::crypto::xeddsa::{XEdDSAError, XSignature, xeddsa_sign};
use crate::key_bundle::{Lifetime, LifetimeError};
#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct PreKey(PublicKey, Lifetime);
pub type PreKeyId = PublicKey;
impl PreKey {
pub fn new(prekey: PublicKey, lifetime: Lifetime) -> Self {
Self(prekey, lifetime)
}
pub fn key(&self) -> &PublicKey {
&self.0
}
pub fn as_bytes(&self) -> &[u8; PUBLIC_KEY_SIZE] {
self.0.as_bytes()
}
pub fn to_bytes(self) -> [u8; PUBLIC_KEY_SIZE] {
self.0.to_bytes()
}
pub fn sign(&self, secret_key: &SecretKey, rng: &Rng) -> Result<XSignature, XEdDSAError> {
xeddsa_sign(self.0.as_bytes(), secret_key, rng)
}
pub fn lifetime(&self) -> &Lifetime {
&self.1
}
pub fn verify_lifetime(&self) -> Result<(), LifetimeError> {
self.1.verify()
}
}
pub type OneTimePreKeyId = u64;
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct OneTimePreKey(PublicKey, OneTimePreKeyId);
impl OneTimePreKey {
pub fn new(onetime_prekey: PublicKey, id: OneTimePreKeyId) -> Self {
Self(onetime_prekey, id)
}
pub fn key(&self) -> &PublicKey {
&self.0
}
pub fn id(&self) -> OneTimePreKeyId {
self.1
}
pub fn as_bytes(&self) -> &[u8; PUBLIC_KEY_SIZE] {
self.0.as_bytes()
}
pub fn to_bytes(&self) -> [u8; PUBLIC_KEY_SIZE] {
self.0.to_bytes()
}
}
pub fn latest_prekey<'a>(prekeys: Vec<&'a PreKey>) -> Option<&'a PreKey> {
let mut latest: Option<&'a PreKey> = None;
for prekey in prekeys {
if prekey.lifetime().verify().is_err() {
continue;
}
match latest {
Some(current_prekey) => {
if prekey.lifetime() > current_prekey.lifetime() {
latest = Some(prekey);
}
}
None => {
latest = Some(prekey);
}
}
}
latest
}