1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
pub mod cache;
use super::{AssociatedData, CryptError};
use rand::Rng;
use serde::{Deserialize, Serialize};
pub type Nonce96Bits = [u8; 12];
pub type Nonce128Bits = [u8; 16];
#[derive(Serialize, Deserialize, Debug, Clone, Copy)]
pub enum Nonce {
Nonce96Bits(Nonce96Bits),
Nonce128Bits(Nonce128Bits),
}
impl Nonce {
pub fn from_slice(&self, slice: &[u8]) -> Option<Self> {
use std::convert::TryInto;
if slice.len() == NonceSize::Nonce96Bits.size_in_bytes() {
slice.try_into().map(Self::Nonce96Bits).ok()
} else if slice.len() == NonceSize::Nonce128Bits.size_in_bytes() {
slice.try_into().map(Self::Nonce128Bits).ok()
} else {
None
}
}
pub fn as_slice(&self) -> &[u8] {
match self {
Self::Nonce96Bits(nonce) => nonce,
Self::Nonce128Bits(nonce) => nonce,
}
}
}
impl From<Nonce96Bits> for Nonce {
fn from(buffer: Nonce96Bits) -> Self {
Self::Nonce96Bits(buffer)
}
}
impl From<Nonce128Bits> for Nonce {
fn from(buffer: Nonce128Bits) -> Self {
Self::Nonce128Bits(buffer)
}
}
#[derive(Debug, Copy, Clone, Serialize, Deserialize)]
pub enum NonceSize {
Nonce96Bits,
Nonce128Bits,
}
impl NonceSize {
pub fn size_in_bytes(self) -> usize {
match self {
NonceSize::Nonce96Bits => 12,
NonceSize::Nonce128Bits => 16,
}
}
}
impl From<Nonce> for NonceSize {
fn from(nonce: Nonce) -> Self {
match nonce {
Nonce::Nonce96Bits(_) => Self::Nonce96Bits,
Nonce::Nonce128Bits(_) => Self::Nonce128Bits,
}
}
}
impl From<NonceSize> for Nonce {
fn from(nonce_size: NonceSize) -> Self {
match nonce_size {
NonceSize::Nonce96Bits => Self::Nonce96Bits(new_96bit_nonce()),
NonceSize::Nonce128Bits => Self::Nonce128Bits(new_128bit_nonce()),
}
}
}
pub fn validate_nonce_size(
nonce_size: NonceSize,
desired_size: usize,
) -> Result<(), CryptError> {
if desired_size != nonce_size.size_in_bytes() {
return Err(CryptError::NonceWrongSize {
provided_size: desired_size,
});
}
Ok(())
}
pub fn new_96bit_nonce() -> Nonce96Bits {
rand::thread_rng().gen::<Nonce96Bits>()
}
pub fn new_128bit_nonce() -> Nonce128Bits {
rand::thread_rng().gen::<Nonce128Bits>()
}