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
use crate::fill_random;

use std::convert::TryInto;

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Nonce {
	bytes: [u8; 24]
}

impl Nonce {
	pub const LEN: usize = 24;

	/// Creates a new random Nonce.
	pub fn new() -> Self {
		let mut this = Self { bytes: [0u8; 24] };
		this.fill_random();
		this
	}

	/// Fills the nonce with new random bytes.
	pub fn fill_random(&mut self) {
		fill_random(&mut self.bytes);
	}

	#[cfg(test)]
	pub fn ones() -> Self {
		Self { bytes: [1u8; 24] }
	}

	/// Creates a nonce from bytes.
	pub fn from_bytes(bytes: [u8; 24]) -> Self {
		Self { bytes }
	}

	/// ## Panics
	/// if the slice is not 24 bytes long.
	pub fn from_slice(slice: &[u8]) -> Self {
		Self::from_bytes(slice.try_into().unwrap())
	}

	pub fn try_from_slice(slice: &[u8]) -> Option<Self> {
		slice.try_into().ok()
			.map(Self::from_bytes)
	}

	pub fn to_bytes(&self) -> [u8; 24] {
		self.bytes
	}

	/// Returns the nonce representation.
	pub fn into_bytes(self) -> [u8; 24] {
		self.bytes
	}

	pub fn as_slice(&self) -> &[u8] {
		&self.bytes
	}

	/// Takes the current nonce, replacing it
	/// with a new random one.
	pub fn take(&mut self) -> Self {
		let n = Nonce::new();
		std::mem::replace(self, n)
	}

}