Skip to main content

pakery_core/
secret.rs

1//! Zeroizing shared secret type.
2
3use alloc::vec::Vec;
4use subtle::ConstantTimeEq;
5use zeroize::{Zeroize, ZeroizeOnDrop};
6
7/// A shared secret that is automatically zeroized on drop.
8///
9/// Comparisons use constant-time equality to prevent timing side-channels.
10///
11/// # Cloning
12///
13/// This type implements [`Clone`].  Each clone is independently zeroized on
14/// drop, but callers should be mindful that every clone creates an additional
15/// copy of the secret material in memory.  Prefer moving over cloning where
16/// possible.
17#[derive(Clone, Zeroize, ZeroizeOnDrop)]
18pub struct SharedSecret {
19    bytes: Vec<u8>,
20}
21
22impl SharedSecret {
23    /// Create a new `SharedSecret` from raw bytes.
24    pub fn new(bytes: Vec<u8>) -> Self {
25        Self { bytes }
26    }
27
28    /// Access the raw bytes of the shared secret.
29    pub fn as_bytes(&self) -> &[u8] {
30        &self.bytes
31    }
32}
33
34impl ConstantTimeEq for SharedSecret {
35    fn ct_eq(&self, other: &Self) -> subtle::Choice {
36        self.bytes.ct_eq(&other.bytes)
37    }
38}
39
40impl PartialEq for SharedSecret {
41    fn eq(&self, other: &Self) -> bool {
42        self.ct_eq(other).into()
43    }
44}
45
46impl Eq for SharedSecret {}
47
48impl core::fmt::Debug for SharedSecret {
49    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
50        f.debug_struct("SharedSecret")
51            .field("bytes", &"[REDACTED]")
52            .finish()
53    }
54}