Skip to content

Commit

Permalink
Rust 1.80
Browse files Browse the repository at this point in the history
Preserves the fn accessors within the Monero crates so that we can use statics
in some cfgs yet not all (in order to provide support for more low-memory
devices) with the exception of `H` (which truly should be cached).
  • Loading branch information
kayabaNerve committed Jul 26, 2024
1 parent 6f34c2f commit f7f6c48
Show file tree
Hide file tree
Showing 38 changed files with 148 additions and 196 deletions.
2 changes: 1 addition & 1 deletion common/std-shims/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ rustdoc-args = ["--cfg", "docsrs"]
workspace = true

[dependencies]
spin = { version = "0.9", default-features = false, features = ["use_ticket_mutex", "once"] }
spin = { version = "0.9", default-features = false, features = ["use_ticket_mutex", "lazy"] }
hashbrown = { version = "0.14", default-features = false, features = ["ahash", "inline-more"] }

[features]
Expand Down
25 changes: 2 additions & 23 deletions common/std-shims/src/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,27 +26,6 @@ mod mutex_shim {
pub use mutex_shim::{ShimMutex as Mutex, MutexGuard};

#[cfg(feature = "std")]
pub use std::sync::OnceLock;
pub use std::sync::LazyLock;
#[cfg(not(feature = "std"))]
mod oncelock_shim {
use spin::Once;

pub struct OnceLock<T>(Once<T>);
impl<T> OnceLock<T> {
pub const fn new() -> OnceLock<T> {
OnceLock(Once::new())
}
pub fn get(&self) -> Option<&T> {
self.0.poll()
}
pub fn get_mut(&mut self) -> Option<&mut T> {
self.0.get_mut()
}

pub fn get_or_init<F: FnOnce() -> T>(&self, f: F) -> &T {
self.0.call_once(f)
}
}
}
#[cfg(not(feature = "std"))]
pub use oncelock_shim::*;
pub use spin::Lazy as LazyLock;
2 changes: 1 addition & 1 deletion networks/bitcoin/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ license = "MIT"
repository = "https://github.com/serai-dex/serai/tree/develop/networks/bitcoin"
authors = ["Luke Parker <[email protected]>", "Vrx <[email protected]>"]
edition = "2021"
rust-version = "1.79"
rust-version = "1.80"

[package.metadata.docs.rs]
all-features = true
Expand Down
11 changes: 4 additions & 7 deletions networks/bitcoin/tests/runner.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
use std::sync::OnceLock;
use std::sync::LazyLock;

use bitcoin_serai::rpc::Rpc;

use tokio::sync::Mutex;

static SEQUENTIAL_CELL: OnceLock<Mutex<()>> = OnceLock::new();
#[allow(non_snake_case)]
pub fn SEQUENTIAL() -> &'static Mutex<()> {
SEQUENTIAL_CELL.get_or_init(|| Mutex::new(()))
}
#[allow(dead_code)]
pub(crate) static SEQUENTIAL: LazyLock<Mutex<()>> = LazyLock::new(|| Mutex::new(()));

#[allow(dead_code)]
pub(crate) async fn rpc() -> Rpc {
Expand All @@ -34,7 +31,7 @@ macro_rules! async_sequential {
$(
#[tokio::test]
async fn $name() {
let guard = runner::SEQUENTIAL().lock().await;
let guard = runner::SEQUENTIAL.lock().await;
let local = tokio::task::LocalSet::new();
local.run_until(async move {
if let Err(err) = tokio::task::spawn_local(async move { $body }).await {
Expand Down
2 changes: 1 addition & 1 deletion networks/monero/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ license = "MIT"
repository = "https://github.com/serai-dex/serai/tree/develop/networks/monero"
authors = ["Luke Parker <[email protected]>"]
edition = "2021"
rust-version = "1.79"
rust-version = "1.80"

[package.metadata.docs.rs]
all-features = true
Expand Down
35 changes: 16 additions & 19 deletions networks/monero/generators/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#![deny(missing_docs)]
#![cfg_attr(not(feature = "std"), no_std)]

use std_shims::{sync::OnceLock, vec::Vec};
use std_shims::{sync::LazyLock, vec::Vec};

use sha3::{Digest, Keccak256};

Expand All @@ -21,33 +21,30 @@ fn keccak256(data: &[u8]) -> [u8; 32] {
Keccak256::digest(data).into()
}

static H_CELL: OnceLock<EdwardsPoint> = OnceLock::new();
/// Monero's `H` generator.
///
/// Contrary to convention (`G` for values, `H` for randomness), `H` is used by Monero for amounts
/// within Pedersen commitments.
#[allow(non_snake_case)]
pub fn H() -> EdwardsPoint {
*H_CELL.get_or_init(|| {
decompress_point(keccak256(&ED25519_BASEPOINT_POINT.compress().to_bytes()))
.unwrap()
.mul_by_cofactor()
})
}

static H_POW_2_CELL: OnceLock<[EdwardsPoint; 64]> = OnceLock::new();
pub static H: LazyLock<EdwardsPoint> = LazyLock::new(|| {
decompress_point(keccak256(&ED25519_BASEPOINT_POINT.compress().to_bytes()))
.unwrap()
.mul_by_cofactor()
});

static H_POW_2_CELL: LazyLock<[EdwardsPoint; 64]> = LazyLock::new(|| {
let mut res = [*H; 64];
for i in 1 .. 64 {
res[i] = res[i - 1] + res[i - 1];
}
res
});
/// Monero's `H` generator, multiplied by 2**i for i in 1 ..= 64.
///
/// This table is useful when working with amounts, which are u64s.
#[allow(non_snake_case)]
pub fn H_pow_2() -> &'static [EdwardsPoint; 64] {
H_POW_2_CELL.get_or_init(|| {
let mut res = [H(); 64];
for i in 1 .. 64 {
res[i] = res[i - 1] + res[i - 1];
}
res
})
&H_POW_2_CELL
}

/// The maximum amount of commitments provable for within a single range proof.
Expand All @@ -74,7 +71,7 @@ pub fn bulletproofs_generators(dst: &'static [u8]) -> Generators {
// The maximum amount of bits used within a single range proof.
const MAX_MN: usize = MAX_COMMITMENTS * COMMITMENT_BITS;

let mut preimage = H().compress().to_bytes().to_vec();
let mut preimage = H.compress().to_bytes().to_vec();
preimage.extend(dst);

let mut res = Generators { G: Vec::with_capacity(MAX_MN), H: Vec::with_capacity(MAX_MN) };
Expand Down
1 change: 1 addition & 0 deletions networks/monero/io/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ license = "MIT"
repository = "https://github.com/serai-dex/serai/tree/develop/networks/monero/io"
authors = ["Luke Parker <[email protected]>"]
edition = "2021"
rust-version = "1.80"

[package.metadata.docs.rs]
all-features = true
Expand Down
2 changes: 1 addition & 1 deletion networks/monero/primitives/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ license = "MIT"
repository = "https://github.com/serai-dex/serai/tree/develop/networks/monero/primitives"
authors = ["Luke Parker <[email protected]>"]
edition = "2021"
rust-version = "1.79"
rust-version = "1.80"

[package.metadata.docs.rs]
all-features = true
Expand Down
17 changes: 9 additions & 8 deletions networks/monero/primitives/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

use std_shims::{io, vec::Vec};
#[cfg(feature = "std")]
use std_shims::sync::OnceLock;
use std_shims::sync::LazyLock;

use zeroize::{Zeroize, ZeroizeOnDrop};

Expand All @@ -28,28 +28,29 @@ mod tests;

// On std, we cache some variables in statics.
#[cfg(feature = "std")]
static INV_EIGHT_CELL: OnceLock<Scalar> = OnceLock::new();
/// The inverse of 8 over l.
static INV_EIGHT_CELL: LazyLock<Scalar> = LazyLock::new(|| Scalar::from(8u8).invert());
/// The inverse of 8 over l, the prime factor of the order of Ed25519.
#[cfg(feature = "std")]
#[allow(non_snake_case)]
pub fn INV_EIGHT() -> Scalar {
*INV_EIGHT_CELL.get_or_init(|| Scalar::from(8u8).invert())
*INV_EIGHT_CELL
}
// In no-std environments, we prefer the reduced memory use and calculate it ad-hoc.
/// The inverse of 8 over l.
/// The inverse of 8 over l, the prime factor of the order of Ed25519.
#[cfg(not(feature = "std"))]
#[allow(non_snake_case)]
pub fn INV_EIGHT() -> Scalar {
Scalar::from(8u8).invert()
}

#[cfg(feature = "std")]
static G_PRECOMP_CELL: OnceLock<VartimeEdwardsPrecomputation> = OnceLock::new();
static G_PRECOMP_CELL: LazyLock<VartimeEdwardsPrecomputation> =
LazyLock::new(|| VartimeEdwardsPrecomputation::new([ED25519_BASEPOINT_POINT]));
/// A cached (if std) pre-computation of the Ed25519 generator, G.
#[cfg(feature = "std")]
#[allow(non_snake_case)]
pub fn G_PRECOMP() -> &'static VartimeEdwardsPrecomputation {
G_PRECOMP_CELL.get_or_init(|| VartimeEdwardsPrecomputation::new([ED25519_BASEPOINT_POINT]))
&G_PRECOMP_CELL
}
/// A cached (if std) pre-computation of the Ed25519 generator, G.
#[cfg(not(feature = "std"))]
Expand Down Expand Up @@ -105,7 +106,7 @@ impl Commitment {

/// Calculate the Pedersen commitment, as a point, from this transparent structure.
pub fn calculate(&self) -> EdwardsPoint {
EdwardsPoint::vartime_double_scalar_mul_basepoint(&Scalar::from(self.amount), &H(), &self.mask)
EdwardsPoint::vartime_double_scalar_mul_basepoint(&Scalar::from(self.amount), &H, &self.mask)
}

/// Write the Commitment.
Expand Down
26 changes: 10 additions & 16 deletions networks/monero/primitives/src/unreduced_scalar.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use core::cmp::Ordering;
use std_shims::{
sync::OnceLock,
sync::LazyLock,
io::{self, *},
};

Expand All @@ -10,18 +10,14 @@ use curve25519_dalek::scalar::Scalar;

use monero_io::*;

static PRECOMPUTED_SCALARS_CELL: OnceLock<[Scalar; 8]> = OnceLock::new();
// Precomputed scalars used to recover an incorrectly reduced scalar.
#[allow(non_snake_case)]
fn PRECOMPUTED_SCALARS() -> [Scalar; 8] {
*PRECOMPUTED_SCALARS_CELL.get_or_init(|| {
let mut precomputed_scalars = [Scalar::ONE; 8];
for (i, scalar) in precomputed_scalars.iter_mut().enumerate().skip(1) {
*scalar = Scalar::from(u8::try_from((i * 2) + 1).unwrap());
}
precomputed_scalars
})
}
static PRECOMPUTED_SCALARS: LazyLock<[Scalar; 8]> = LazyLock::new(|| {
let mut precomputed_scalars = [Scalar::ONE; 8];
for (i, scalar) in precomputed_scalars.iter_mut().enumerate().skip(1) {
*scalar = Scalar::from(u8::try_from((i * 2) + 1).unwrap());
}
precomputed_scalars
});

/// An unreduced scalar.
///
Expand Down Expand Up @@ -127,14 +123,12 @@ impl UnreducedScalar {
return Scalar::from_bytes_mod_order(self.0);
}

let precomputed_scalars = PRECOMPUTED_SCALARS();

let mut recovered = Scalar::ZERO;
for &numb in self.non_adjacent_form().iter().rev() {
recovered += recovered;
match numb.cmp(&0) {
Ordering::Greater => recovered += precomputed_scalars[usize::try_from(numb).unwrap() / 2],
Ordering::Less => recovered -= precomputed_scalars[usize::try_from(-numb).unwrap() / 2],
Ordering::Greater => recovered += PRECOMPUTED_SCALARS[usize::try_from(numb).unwrap() / 2],
Ordering::Less => recovered -= PRECOMPUTED_SCALARS[usize::try_from(-numb).unwrap() / 2],
Ordering::Equal => (),
}
}
Expand Down
2 changes: 1 addition & 1 deletion networks/monero/ringct/borromean/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ license = "MIT"
repository = "https://github.com/serai-dex/serai/tree/develop/networks/monero/ringct/borromean"
authors = ["Luke Parker <[email protected]>"]
edition = "2021"
rust-version = "1.79"
rust-version = "1.80"

[package.metadata.docs.rs]
all-features = true
Expand Down
2 changes: 1 addition & 1 deletion networks/monero/ringct/bulletproofs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ license = "MIT"
repository = "https://github.com/serai-dex/serai/tree/develop/networks/monero/ringct/bulletproofs"
authors = ["Luke Parker <[email protected]>"]
edition = "2021"
rust-version = "1.79"
rust-version = "1.80"

[package.metadata.docs.rs]
all-features = true
Expand Down
28 changes: 11 additions & 17 deletions networks/monero/ringct/bulletproofs/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,17 +40,14 @@ fn generators(prefix: &'static str, path: &str) {
.write_all(
format!(
"
static GENERATORS_CELL: OnceLock<Generators> = OnceLock::new();
pub(crate) fn GENERATORS() -> &'static Generators {{
GENERATORS_CELL.get_or_init(|| Generators {{
G: std_shims::vec![
{G_str}
],
H: std_shims::vec![
{H_str}
],
}})
}}
pub(crate) static GENERATORS: LazyLock<Generators> = LazyLock::new(|| Generators {{
G: std_shims::vec![
{G_str}
],
H: std_shims::vec![
{H_str}
],
}});
",
)
.as_bytes(),
Expand All @@ -67,12 +64,9 @@ fn generators(prefix: &'static str, path: &str) {
.write_all(
format!(
r#"
static GENERATORS_CELL: OnceLock<Generators> = OnceLock::new();
pub(crate) fn GENERATORS() -> &'static Generators {{
GENERATORS_CELL.get_or_init(|| {{
monero_generators::bulletproofs_generators(b"{prefix}")
}})
}}
pub(crate) static GENERATORS: LazyLock<Generators> = LazyLock::new(|| {{
monero_generators::bulletproofs_generators(b"{prefix}")
}});
"#,
)
.as_bytes(),
Expand Down
6 changes: 3 additions & 3 deletions networks/monero/ringct/bulletproofs/src/batch_verifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use curve25519_dalek::{
edwards::EdwardsPoint,
};

use monero_generators::{H, Generators};
use monero_generators::{H as MONERO_H, Generators};

use crate::{original, plus};

Expand Down Expand Up @@ -57,7 +57,7 @@ pub(crate) struct BulletproofsBatchVerifier(pub(crate) InternalBatchVerifier);
impl BulletproofsBatchVerifier {
#[must_use]
pub(crate) fn verify(self) -> bool {
self.0.verify(ED25519_BASEPOINT_POINT, H(), original::GENERATORS())
self.0.verify(ED25519_BASEPOINT_POINT, *MONERO_H, &original::GENERATORS)
}
}

Expand All @@ -68,7 +68,7 @@ impl BulletproofsPlusBatchVerifier {
pub(crate) fn verify(self) -> bool {
// Bulletproofs+ is written as per the paper, with G for the value and H for the mask
// Monero uses H for the value and G for the mask
self.0.verify(H(), ED25519_BASEPOINT_POINT, plus::GENERATORS())
self.0.verify(*MONERO_H, ED25519_BASEPOINT_POINT, &plus::GENERATORS)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,13 +96,13 @@ impl IpStatement {
mut transcript: Scalar,
witness: IpWitness,
) -> Result<IpProof, IpError> {
let generators = crate::original::GENERATORS();
let generators = &crate::original::GENERATORS;
let g_bold_slice = &generators.G[.. witness.a.len()];
let h_bold_slice = &generators.H[.. witness.a.len()];

let (mut g_bold, mut h_bold, u, mut a, mut b) = {
let IpStatement { h_bold_weights, u } = self;
let u = H() * u;
let u = *H * u;

// Ensure we have the exact amount of weights
if h_bold_weights.len() != g_bold_slice.len() {
Expand Down Expand Up @@ -218,7 +218,7 @@ impl IpStatement {
verifier_weight: Scalar,
proof: IpProof,
) -> Result<(), IpError> {
let generators = crate::original::GENERATORS();
let generators = &crate::original::GENERATORS;
let g_bold_slice = &generators.G[.. ip_rows];
let h_bold_slice = &generators.H[.. ip_rows];

Expand Down
Loading

0 comments on commit f7f6c48

Please sign in to comment.