1use paseto_core::version;
2
3#[cfg(feature = "decrypting")]
4mod local;
5#[cfg(feature = "pie-wrap")]
6mod pie_wrap;
7#[cfg(feature = "pke")]
8mod pke;
9#[cfg(feature = "verifying")]
10mod public;
11#[cfg(feature = "pbkw")]
12mod pw_wrap;
13
14pub struct V4;
15
16#[cfg(feature = "decrypting")]
17#[derive(Clone)]
18pub struct LocalKey([u8; 32]);
19
20#[cfg(feature = "signing")]
21pub struct SecretKey(
22 ed25519_dalek::SecretKey,
23 ed25519_dalek::hazmat::ExpandedSecretKey,
24);
25
26#[cfg(feature = "verifying")]
27#[derive(Clone)]
28pub struct PublicKey(pub(super) ed25519_dalek::VerifyingKey);
29
30impl version::Version for V4 {
31 const HEADER: &'static str = "v4";
32 const PASERK_HEADER: &'static str = "k4";
33}
34
35#[cfg(feature = "id")]
36impl paseto_core::paserk::IdVersion for V4 {
37 fn hash_key(key_header: &'static str, key_data: &[u8]) -> [u8; 33] {
38 use digest::consts::U33;
39 use digest::{FixedOutput, Update};
40
41 let mut ctx = blake2::Blake2b::<U33>::default();
42 ctx.update(b"k4");
43 ctx.update(key_header.as_bytes());
44 ctx.update(key_data);
45 ctx.finalize_fixed().into()
46 }
47}
48
49#[cfg(any(feature = "decrypting", feature = "signing"))]
50struct PreAuthEncodeDigest<'a, M: digest::Update>(pub &'a mut M);
51#[cfg(any(feature = "decrypting", feature = "signing"))]
52impl<M: digest::Update> paseto_core::pae::WriteBytes for PreAuthEncodeDigest<'_, M> {
53 fn write(&mut self, slice: &[u8]) {
54 self.0.update(slice);
55 }
56}
57
58#[cfg(feature = "decrypting")]
59fn kdf<O>(key: &[u8], sep: &'static [u8], nonce: &[u8]) -> generic_array::GenericArray<u8, O>
60where
61 O: generic_array::ArrayLength<u8>
62 + generic_array::typenum::IsLessOrEqual<generic_array::typenum::U64>,
63 generic_array::typenum::LeEq<O, generic_array::typenum::U64>: generic_array::typenum::NonZero,
64{
65 use digest::Mac;
66
67 let mut mac = blake2::Blake2bMac::<O>::new_from_slice(key).expect("key should be valid");
68 mac.update(sep);
69 mac.update(nonce);
70 mac.finalize().into_bytes()
71}