From d7aeaa0aadaece9921b9317a661bbeb4f2580cb6 Mon Sep 17 00:00:00 2001 From: Jeffrey Czyz Date: Wed, 19 Jun 2024 11:51:53 -0500 Subject: [PATCH] Move Nonce to a separate offers sub-module Nonce is used when constructing Offer::metadata and will soon be need when constructing BlindedPath for use in authentication. Move it to separate module now that it is public and will be more widely used. --- lightning/src/ln/inbound_payment.rs | 48 +------------------ lightning/src/offers/invoice_request.rs | 3 +- lightning/src/offers/mod.rs | 1 + lightning/src/offers/nonce.rs | 64 +++++++++++++++++++++++++ lightning/src/offers/offer.rs | 3 +- lightning/src/offers/refund.rs | 3 +- lightning/src/offers/signer.rs | 3 +- 7 files changed, 74 insertions(+), 51 deletions(-) create mode 100644 lightning/src/offers/nonce.rs diff --git a/lightning/src/ln/inbound_payment.rs b/lightning/src/ln/inbound_payment.rs index b00bf786a..2d807d550 100644 --- a/lightning/src/ln/inbound_payment.rs +++ b/lightning/src/ln/inbound_payment.rs @@ -19,6 +19,7 @@ use crate::crypto::utils::hkdf_extract_expand_5x; use crate::ln::msgs; use crate::ln::msgs::MAX_VALUE_MSAT; use crate::ln::types::{PaymentHash, PaymentPreimage, PaymentSecret}; +use crate::offers::nonce::Nonce; use crate::sign::{KeyMaterial, EntropySource}; use crate::util::errors::APIError; use crate::util::logger::Logger; @@ -97,53 +98,6 @@ impl ExpandedKey { } } -/// A 128-bit number used only once. -/// -/// Needed when constructing [`Offer::metadata`] and deriving [`Offer::signing_pubkey`] from -/// [`ExpandedKey`]. Must not be reused for any other derivation without first hashing. -/// -/// [`Offer::metadata`]: crate::offers::offer::Offer::metadata -/// [`Offer::signing_pubkey`]: crate::offers::offer::Offer::signing_pubkey -#[derive(Clone, Copy, Debug, PartialEq)] -pub struct Nonce(pub(crate) [u8; Self::LENGTH]); - -impl Nonce { - /// Number of bytes in the nonce. - pub const LENGTH: usize = 16; - - /// Creates a `Nonce` from the given [`EntropySource`]. - pub fn from_entropy_source(entropy_source: ES) -> Self - where - ES::Target: EntropySource, - { - let mut bytes = [0u8; Self::LENGTH]; - let rand_bytes = entropy_source.get_secure_random_bytes(); - bytes.copy_from_slice(&rand_bytes[..Self::LENGTH]); - - Nonce(bytes) - } - - /// Returns a slice of the underlying bytes of size [`Nonce::LENGTH`]. - pub fn as_slice(&self) -> &[u8] { - &self.0 - } -} - -impl TryFrom<&[u8]> for Nonce { - type Error = (); - - fn try_from(bytes: &[u8]) -> Result { - if bytes.len() != Self::LENGTH { - return Err(()); - } - - let mut copied_bytes = [0u8; Self::LENGTH]; - copied_bytes.copy_from_slice(bytes); - - Ok(Self(copied_bytes)) - } -} - enum Method { LdkPaymentHash = 0, UserPaymentHash = 1, diff --git a/lightning/src/offers/invoice_request.rs b/lightning/src/offers/invoice_request.rs index cdf94a2e8..b9ccc5f4d 100644 --- a/lightning/src/offers/invoice_request.rs +++ b/lightning/src/offers/invoice_request.rs @@ -68,10 +68,11 @@ use crate::blinded_path::BlindedPath; use crate::ln::types::PaymentHash; use crate::ln::channelmanager::PaymentId; use crate::ln::features::InvoiceRequestFeatures; -use crate::ln::inbound_payment::{ExpandedKey, IV_LEN, Nonce}; +use crate::ln::inbound_payment::{ExpandedKey, IV_LEN}; use crate::ln::msgs::DecodeError; use crate::offers::invoice::BlindedPayInfo; use crate::offers::merkle::{SignError, SignFn, SignatureTlvStream, SignatureTlvStreamRef, TaggedHash, self}; +use crate::offers::nonce::Nonce; use crate::offers::offer::{Offer, OfferContents, OfferId, OfferTlvStream, OfferTlvStreamRef}; use crate::offers::parse::{Bolt12ParseError, ParsedMessage, Bolt12SemanticError}; use crate::offers::payer::{PayerContents, PayerTlvStream, PayerTlvStreamRef}; diff --git a/lightning/src/offers/mod.rs b/lightning/src/offers/mod.rs index e5e894e2a..e4fe7d789 100644 --- a/lightning/src/offers/mod.rs +++ b/lightning/src/offers/mod.rs @@ -20,6 +20,7 @@ pub mod invoice_error; mod invoice_macros; pub mod invoice_request; pub mod merkle; +pub mod nonce; pub mod parse; mod payer; pub mod refund; diff --git a/lightning/src/offers/nonce.rs b/lightning/src/offers/nonce.rs new file mode 100644 index 000000000..965a39d84 --- /dev/null +++ b/lightning/src/offers/nonce.rs @@ -0,0 +1,64 @@ +// This file is Copyright its original authors, visible in version control +// history. +// +// This file is licensed under the Apache License, Version 2.0 or the MIT license +// , at your option. +// You may not use this file except in accordance with one or both of these +// licenses. + +//! A number used only once. + +use crate::sign::EntropySource; +use core::ops::Deref; + +#[allow(unused_imports)] +use crate::prelude::*; + +/// A 128-bit number used only once. +/// +/// Needed when constructing [`Offer::metadata`] and deriving [`Offer::signing_pubkey`] from +/// [`ExpandedKey`]. Must not be reused for any other derivation without first hashing. +/// +/// [`Offer::metadata`]: crate::offers::offer::Offer::metadata +/// [`Offer::signing_pubkey`]: crate::offers::offer::Offer::signing_pubkey +/// [`ExpandedKey`]: crate::ln::inbound_payment::ExpandedKey +#[derive(Clone, Copy, Debug, PartialEq)] +pub struct Nonce(pub(crate) [u8; Self::LENGTH]); + +impl Nonce { + /// Number of bytes in the nonce. + pub const LENGTH: usize = 16; + + /// Creates a `Nonce` from the given [`EntropySource`]. + pub fn from_entropy_source(entropy_source: ES) -> Self + where + ES::Target: EntropySource, + { + let mut bytes = [0u8; Self::LENGTH]; + let rand_bytes = entropy_source.get_secure_random_bytes(); + bytes.copy_from_slice(&rand_bytes[..Self::LENGTH]); + + Nonce(bytes) + } + + /// Returns a slice of the underlying bytes of size [`Nonce::LENGTH`]. + pub fn as_slice(&self) -> &[u8] { + &self.0 + } +} + +impl TryFrom<&[u8]> for Nonce { + type Error = (); + + fn try_from(bytes: &[u8]) -> Result { + if bytes.len() != Self::LENGTH { + return Err(()); + } + + let mut copied_bytes = [0u8; Self::LENGTH]; + copied_bytes.copy_from_slice(bytes); + + Ok(Self(copied_bytes)) + } +} diff --git a/lightning/src/offers/offer.rs b/lightning/src/offers/offer.rs index 253de8652..03e1e92a4 100644 --- a/lightning/src/offers/offer.rs +++ b/lightning/src/offers/offer.rs @@ -90,9 +90,10 @@ use crate::io; use crate::blinded_path::BlindedPath; use crate::ln::channelmanager::PaymentId; use crate::ln::features::OfferFeatures; -use crate::ln::inbound_payment::{ExpandedKey, IV_LEN, Nonce}; +use crate::ln::inbound_payment::{ExpandedKey, IV_LEN}; use crate::ln::msgs::{DecodeError, MAX_VALUE_MSAT}; use crate::offers::merkle::{TaggedHash, TlvStream}; +use crate::offers::nonce::Nonce; use crate::offers::parse::{Bech32Encode, Bolt12ParseError, Bolt12SemanticError, ParsedMessage}; use crate::offers::signer::{Metadata, MetadataMaterial, self}; use crate::util::ser::{HighZeroBytesDroppedBigSize, Readable, WithoutLength, Writeable, Writer}; diff --git a/lightning/src/offers/refund.rs b/lightning/src/offers/refund.rs index 624036d19..6a14d2871 100644 --- a/lightning/src/offers/refund.rs +++ b/lightning/src/offers/refund.rs @@ -95,10 +95,11 @@ use crate::blinded_path::BlindedPath; use crate::ln::types::PaymentHash; use crate::ln::channelmanager::PaymentId; use crate::ln::features::InvoiceRequestFeatures; -use crate::ln::inbound_payment::{ExpandedKey, IV_LEN, Nonce}; +use crate::ln::inbound_payment::{ExpandedKey, IV_LEN}; use crate::ln::msgs::{DecodeError, MAX_VALUE_MSAT}; use crate::offers::invoice::BlindedPayInfo; use crate::offers::invoice_request::{InvoiceRequestTlvStream, InvoiceRequestTlvStreamRef}; +use crate::offers::nonce::Nonce; use crate::offers::offer::{OfferTlvStream, OfferTlvStreamRef}; use crate::offers::parse::{Bech32Encode, Bolt12ParseError, Bolt12SemanticError, ParsedMessage}; use crate::offers::payer::{PayerContents, PayerTlvStream, PayerTlvStreamRef}; diff --git a/lightning/src/offers/signer.rs b/lightning/src/offers/signer.rs index fff051456..50016a051 100644 --- a/lightning/src/offers/signer.rs +++ b/lightning/src/offers/signer.rs @@ -16,8 +16,9 @@ use bitcoin::hashes::sha256::Hash as Sha256; use bitcoin::secp256k1::{Keypair, PublicKey, Secp256k1, SecretKey, self}; use core::fmt; use crate::ln::channelmanager::PaymentId; -use crate::ln::inbound_payment::{ExpandedKey, IV_LEN, Nonce}; +use crate::ln::inbound_payment::{ExpandedKey, IV_LEN}; use crate::offers::merkle::TlvRecord; +use crate::offers::nonce::Nonce; use crate::util::ser::Writeable; use crate::prelude::*; -- 2.39.5