lightning/offers/
nonce.rs

1// This file is Copyright its original authors, visible in version control
2// history.
3//
4// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
5// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
7// You may not use this file except in accordance with one or both of these
8// licenses.
9
10//! A number used only once.
11
12use crate::io::{self, Read};
13use crate::ln::msgs::DecodeError;
14use crate::sign::EntropySource;
15use crate::util::ser::{Readable, Writeable, Writer};
16use core::ops::Deref;
17
18#[allow(unused_imports)]
19use crate::prelude::*;
20
21/// A 128-bit number used only once.
22///
23/// Needed when constructing [`Offer::metadata`] and deriving [`Offer::issuer_signing_pubkey`] from
24/// [`ExpandedKey`]. Must not be reused for any other derivation without first hashing.
25///
26/// [`Offer::metadata`]: crate::offers::offer::Offer::metadata
27/// [`Offer::issuer_signing_pubkey`]: crate::offers::offer::Offer::issuer_signing_pubkey
28/// [`ExpandedKey`]: crate::ln::inbound_payment::ExpandedKey
29#[derive(Clone, Copy, Debug, Eq, PartialEq)]
30pub struct Nonce(pub(crate) [u8; Self::LENGTH]);
31
32impl Nonce {
33	/// Number of bytes in the nonce.
34	pub const LENGTH: usize = 16;
35
36	/// Creates a `Nonce` from the given [`EntropySource`].
37	pub fn from_entropy_source<ES: Deref>(entropy_source: ES) -> Self
38	where
39		ES::Target: EntropySource,
40	{
41		let mut bytes = [0u8; Self::LENGTH];
42		let rand_bytes = entropy_source.get_secure_random_bytes();
43		bytes.copy_from_slice(&rand_bytes[..Self::LENGTH]);
44
45		Nonce(bytes)
46	}
47
48	/// Returns a slice of the underlying bytes of size [`Nonce::LENGTH`].
49	pub fn as_slice(&self) -> &[u8] {
50		&self.0
51	}
52}
53
54impl TryFrom<&[u8]> for Nonce {
55	type Error = ();
56
57	fn try_from(bytes: &[u8]) -> Result<Self, ()> {
58		if bytes.len() != Self::LENGTH {
59			return Err(());
60		}
61
62		let mut copied_bytes = [0u8; Self::LENGTH];
63		copied_bytes.copy_from_slice(bytes);
64
65		Ok(Self(copied_bytes))
66	}
67}
68
69impl Writeable for Nonce {
70	fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
71		self.0.write(w)
72	}
73}
74
75impl Readable for Nonce {
76	fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
77		Ok(Nonce(Readable::read(r)?))
78	}
79}