ockam_identity/secure_channel/
nonce.rs1use crate::IdentityError;
2use core::fmt::{Display, Formatter};
3use ockam_core::Result;
4
5pub const AES_GCM_NONCE_LEN: usize = 12;
7
8pub const NOISE_NONCE_LEN: usize = 8;
10
11pub const MAX_NONCE: Nonce = Nonce { value: u64::MAX };
13
14#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq, Copy)]
16pub struct Nonce {
17 value: u64,
18}
19
20impl Display for Nonce {
21 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
22 write!(f, "{}", self.value)
23 }
24}
25
26impl From<u64> for Nonce {
27 fn from(value: u64) -> Self {
28 Self { value }
29 }
30}
31
32impl From<Nonce> for u64 {
33 fn from(value: Nonce) -> Self {
34 value.value
35 }
36}
37
38impl Nonce {
39 pub fn new(value: u64) -> Self {
41 Self { value }
42 }
43
44 pub fn value(&self) -> u64 {
46 self.value
47 }
48
49 pub fn increment(&mut self) -> Result<()> {
51 if self == &MAX_NONCE {
52 return Err(IdentityError::NonceOverflow)?;
53 }
54
55 self.value += 1;
56
57 Ok(())
58 }
59
60 pub fn to_aes_gcm_nonce(&self) -> [u8; AES_GCM_NONCE_LEN] {
63 let mut n: [u8; AES_GCM_NONCE_LEN] = [0; AES_GCM_NONCE_LEN];
64
65 n[AES_GCM_NONCE_LEN - NOISE_NONCE_LEN..].copy_from_slice(&self.to_noise_nonce());
66
67 n
68 }
69
70 pub fn to_noise_nonce(&self) -> [u8; NOISE_NONCE_LEN] {
73 self.value.to_be_bytes()
74 }
75}
76
77impl From<[u8; NOISE_NONCE_LEN]> for Nonce {
79 fn from(value: [u8; NOISE_NONCE_LEN]) -> Self {
80 let value = u64::from_be_bytes(value);
81
82 Self { value }
83 }
84}
85
86impl TryFrom<&[u8]> for Nonce {
88 type Error = IdentityError;
89
90 fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
91 let bytes: [u8; NOISE_NONCE_LEN] =
92 value.try_into().map_err(|_| IdentityError::InvalidNonce)?;
93
94 Ok(bytes.into())
95 }
96}