mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-08 20:29:23 +00:00
Rust 1.80
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).
This commit is contained in:
@@ -17,7 +17,7 @@ rustdoc-args = ["--cfg", "docsrs"]
|
|||||||
workspace = true
|
workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[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"] }
|
hashbrown = { version = "0.14", default-features = false, features = ["ahash", "inline-more"] }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
|
|||||||
@@ -26,27 +26,6 @@ mod mutex_shim {
|
|||||||
pub use mutex_shim::{ShimMutex as Mutex, MutexGuard};
|
pub use mutex_shim::{ShimMutex as Mutex, MutexGuard};
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
pub use std::sync::OnceLock;
|
pub use std::sync::LazyLock;
|
||||||
#[cfg(not(feature = "std"))]
|
#[cfg(not(feature = "std"))]
|
||||||
mod oncelock_shim {
|
pub use spin::Lazy as LazyLock;
|
||||||
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::*;
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ license = "MIT"
|
|||||||
repository = "https://github.com/serai-dex/serai/tree/develop/networks/bitcoin"
|
repository = "https://github.com/serai-dex/serai/tree/develop/networks/bitcoin"
|
||||||
authors = ["Luke Parker <lukeparker5132@gmail.com>", "Vrx <vrx00@proton.me>"]
|
authors = ["Luke Parker <lukeparker5132@gmail.com>", "Vrx <vrx00@proton.me>"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
rust-version = "1.79"
|
rust-version = "1.80"
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
all-features = true
|
all-features = true
|
||||||
|
|||||||
@@ -1,14 +1,11 @@
|
|||||||
use std::sync::OnceLock;
|
use std::sync::LazyLock;
|
||||||
|
|
||||||
use bitcoin_serai::rpc::Rpc;
|
use bitcoin_serai::rpc::Rpc;
|
||||||
|
|
||||||
use tokio::sync::Mutex;
|
use tokio::sync::Mutex;
|
||||||
|
|
||||||
static SEQUENTIAL_CELL: OnceLock<Mutex<()>> = OnceLock::new();
|
#[allow(dead_code)]
|
||||||
#[allow(non_snake_case)]
|
pub(crate) static SEQUENTIAL: LazyLock<Mutex<()>> = LazyLock::new(|| Mutex::new(()));
|
||||||
pub fn SEQUENTIAL() -> &'static Mutex<()> {
|
|
||||||
SEQUENTIAL_CELL.get_or_init(|| Mutex::new(()))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub(crate) async fn rpc() -> Rpc {
|
pub(crate) async fn rpc() -> Rpc {
|
||||||
@@ -34,7 +31,7 @@ macro_rules! async_sequential {
|
|||||||
$(
|
$(
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn $name() {
|
async fn $name() {
|
||||||
let guard = runner::SEQUENTIAL().lock().await;
|
let guard = runner::SEQUENTIAL.lock().await;
|
||||||
let local = tokio::task::LocalSet::new();
|
let local = tokio::task::LocalSet::new();
|
||||||
local.run_until(async move {
|
local.run_until(async move {
|
||||||
if let Err(err) = tokio::task::spawn_local(async move { $body }).await {
|
if let Err(err) = tokio::task::spawn_local(async move { $body }).await {
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ license = "MIT"
|
|||||||
repository = "https://github.com/serai-dex/serai/tree/develop/networks/monero"
|
repository = "https://github.com/serai-dex/serai/tree/develop/networks/monero"
|
||||||
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
rust-version = "1.79"
|
rust-version = "1.80"
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
all-features = true
|
all-features = true
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
#![deny(missing_docs)]
|
#![deny(missing_docs)]
|
||||||
#![cfg_attr(not(feature = "std"), no_std)]
|
#![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};
|
use sha3::{Digest, Keccak256};
|
||||||
|
|
||||||
@@ -21,33 +21,30 @@ fn keccak256(data: &[u8]) -> [u8; 32] {
|
|||||||
Keccak256::digest(data).into()
|
Keccak256::digest(data).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
static H_CELL: OnceLock<EdwardsPoint> = OnceLock::new();
|
|
||||||
/// Monero's `H` generator.
|
/// Monero's `H` generator.
|
||||||
///
|
///
|
||||||
/// Contrary to convention (`G` for values, `H` for randomness), `H` is used by Monero for amounts
|
/// Contrary to convention (`G` for values, `H` for randomness), `H` is used by Monero for amounts
|
||||||
/// within Pedersen commitments.
|
/// within Pedersen commitments.
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
pub fn H() -> EdwardsPoint {
|
pub static H: LazyLock<EdwardsPoint> = LazyLock::new(|| {
|
||||||
*H_CELL.get_or_init(|| {
|
|
||||||
decompress_point(keccak256(&ED25519_BASEPOINT_POINT.compress().to_bytes()))
|
decompress_point(keccak256(&ED25519_BASEPOINT_POINT.compress().to_bytes()))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.mul_by_cofactor()
|
.mul_by_cofactor()
|
||||||
})
|
});
|
||||||
}
|
|
||||||
|
|
||||||
static H_POW_2_CELL: OnceLock<[EdwardsPoint; 64]> = OnceLock::new();
|
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.
|
/// Monero's `H` generator, multiplied by 2**i for i in 1 ..= 64.
|
||||||
///
|
///
|
||||||
/// This table is useful when working with amounts, which are u64s.
|
/// This table is useful when working with amounts, which are u64s.
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
pub fn H_pow_2() -> &'static [EdwardsPoint; 64] {
|
pub fn H_pow_2() -> &'static [EdwardsPoint; 64] {
|
||||||
H_POW_2_CELL.get_or_init(|| {
|
&H_POW_2_CELL
|
||||||
let mut res = [H(); 64];
|
|
||||||
for i in 1 .. 64 {
|
|
||||||
res[i] = res[i - 1] + res[i - 1];
|
|
||||||
}
|
|
||||||
res
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The maximum amount of commitments provable for within a single range proof.
|
/// The maximum amount of commitments provable for within a single range proof.
|
||||||
@@ -74,7 +71,7 @@ pub fn bulletproofs_generators(dst: &'static [u8]) -> Generators {
|
|||||||
// The maximum amount of bits used within a single range proof.
|
// The maximum amount of bits used within a single range proof.
|
||||||
const MAX_MN: usize = MAX_COMMITMENTS * COMMITMENT_BITS;
|
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);
|
preimage.extend(dst);
|
||||||
|
|
||||||
let mut res = Generators { G: Vec::with_capacity(MAX_MN), H: Vec::with_capacity(MAX_MN) };
|
let mut res = Generators { G: Vec::with_capacity(MAX_MN), H: Vec::with_capacity(MAX_MN) };
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ license = "MIT"
|
|||||||
repository = "https://github.com/serai-dex/serai/tree/develop/networks/monero/io"
|
repository = "https://github.com/serai-dex/serai/tree/develop/networks/monero/io"
|
||||||
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
rust-version = "1.80"
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
all-features = true
|
all-features = true
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ license = "MIT"
|
|||||||
repository = "https://github.com/serai-dex/serai/tree/develop/networks/monero/primitives"
|
repository = "https://github.com/serai-dex/serai/tree/develop/networks/monero/primitives"
|
||||||
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
rust-version = "1.79"
|
rust-version = "1.80"
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
all-features = true
|
all-features = true
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
use std_shims::{io, vec::Vec};
|
use std_shims::{io, vec::Vec};
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use std_shims::sync::OnceLock;
|
use std_shims::sync::LazyLock;
|
||||||
|
|
||||||
use zeroize::{Zeroize, ZeroizeOnDrop};
|
use zeroize::{Zeroize, ZeroizeOnDrop};
|
||||||
|
|
||||||
@@ -28,15 +28,15 @@ mod tests;
|
|||||||
|
|
||||||
// On std, we cache some variables in statics.
|
// On std, we cache some variables in statics.
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
static INV_EIGHT_CELL: OnceLock<Scalar> = OnceLock::new();
|
static INV_EIGHT_CELL: LazyLock<Scalar> = LazyLock::new(|| Scalar::from(8u8).invert());
|
||||||
/// The inverse of 8 over l.
|
/// The inverse of 8 over l, the prime factor of the order of Ed25519.
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
pub fn INV_EIGHT() -> Scalar {
|
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.
|
// 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"))]
|
#[cfg(not(feature = "std"))]
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
pub fn INV_EIGHT() -> Scalar {
|
pub fn INV_EIGHT() -> Scalar {
|
||||||
@@ -44,12 +44,13 @@ pub fn INV_EIGHT() -> Scalar {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[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.
|
/// A cached (if std) pre-computation of the Ed25519 generator, G.
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
pub fn G_PRECOMP() -> &'static VartimeEdwardsPrecomputation {
|
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.
|
/// A cached (if std) pre-computation of the Ed25519 generator, G.
|
||||||
#[cfg(not(feature = "std"))]
|
#[cfg(not(feature = "std"))]
|
||||||
@@ -105,7 +106,7 @@ impl Commitment {
|
|||||||
|
|
||||||
/// Calculate the Pedersen commitment, as a point, from this transparent structure.
|
/// Calculate the Pedersen commitment, as a point, from this transparent structure.
|
||||||
pub fn calculate(&self) -> EdwardsPoint {
|
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.
|
/// Write the Commitment.
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use core::cmp::Ordering;
|
use core::cmp::Ordering;
|
||||||
use std_shims::{
|
use std_shims::{
|
||||||
sync::OnceLock,
|
sync::LazyLock,
|
||||||
io::{self, *},
|
io::{self, *},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -10,18 +10,14 @@ use curve25519_dalek::scalar::Scalar;
|
|||||||
|
|
||||||
use monero_io::*;
|
use monero_io::*;
|
||||||
|
|
||||||
static PRECOMPUTED_SCALARS_CELL: OnceLock<[Scalar; 8]> = OnceLock::new();
|
|
||||||
// Precomputed scalars used to recover an incorrectly reduced scalar.
|
// Precomputed scalars used to recover an incorrectly reduced scalar.
|
||||||
#[allow(non_snake_case)]
|
static PRECOMPUTED_SCALARS: LazyLock<[Scalar; 8]> = LazyLock::new(|| {
|
||||||
fn PRECOMPUTED_SCALARS() -> [Scalar; 8] {
|
|
||||||
*PRECOMPUTED_SCALARS_CELL.get_or_init(|| {
|
|
||||||
let mut precomputed_scalars = [Scalar::ONE; 8];
|
let mut precomputed_scalars = [Scalar::ONE; 8];
|
||||||
for (i, scalar) in precomputed_scalars.iter_mut().enumerate().skip(1) {
|
for (i, scalar) in precomputed_scalars.iter_mut().enumerate().skip(1) {
|
||||||
*scalar = Scalar::from(u8::try_from((i * 2) + 1).unwrap());
|
*scalar = Scalar::from(u8::try_from((i * 2) + 1).unwrap());
|
||||||
}
|
}
|
||||||
precomputed_scalars
|
precomputed_scalars
|
||||||
})
|
});
|
||||||
}
|
|
||||||
|
|
||||||
/// An unreduced scalar.
|
/// An unreduced scalar.
|
||||||
///
|
///
|
||||||
@@ -127,14 +123,12 @@ impl UnreducedScalar {
|
|||||||
return Scalar::from_bytes_mod_order(self.0);
|
return Scalar::from_bytes_mod_order(self.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
let precomputed_scalars = PRECOMPUTED_SCALARS();
|
|
||||||
|
|
||||||
let mut recovered = Scalar::ZERO;
|
let mut recovered = Scalar::ZERO;
|
||||||
for &numb in self.non_adjacent_form().iter().rev() {
|
for &numb in self.non_adjacent_form().iter().rev() {
|
||||||
recovered += recovered;
|
recovered += recovered;
|
||||||
match numb.cmp(&0) {
|
match numb.cmp(&0) {
|
||||||
Ordering::Greater => 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::Less => recovered -= PRECOMPUTED_SCALARS[usize::try_from(-numb).unwrap() / 2],
|
||||||
Ordering::Equal => (),
|
Ordering::Equal => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ license = "MIT"
|
|||||||
repository = "https://github.com/serai-dex/serai/tree/develop/networks/monero/ringct/borromean"
|
repository = "https://github.com/serai-dex/serai/tree/develop/networks/monero/ringct/borromean"
|
||||||
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
rust-version = "1.79"
|
rust-version = "1.80"
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
all-features = true
|
all-features = true
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ license = "MIT"
|
|||||||
repository = "https://github.com/serai-dex/serai/tree/develop/networks/monero/ringct/bulletproofs"
|
repository = "https://github.com/serai-dex/serai/tree/develop/networks/monero/ringct/bulletproofs"
|
||||||
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
rust-version = "1.79"
|
rust-version = "1.80"
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
all-features = true
|
all-features = true
|
||||||
|
|||||||
@@ -40,17 +40,14 @@ fn generators(prefix: &'static str, path: &str) {
|
|||||||
.write_all(
|
.write_all(
|
||||||
format!(
|
format!(
|
||||||
"
|
"
|
||||||
static GENERATORS_CELL: OnceLock<Generators> = OnceLock::new();
|
pub(crate) static GENERATORS: LazyLock<Generators> = LazyLock::new(|| Generators {{
|
||||||
pub(crate) fn GENERATORS() -> &'static Generators {{
|
|
||||||
GENERATORS_CELL.get_or_init(|| Generators {{
|
|
||||||
G: std_shims::vec![
|
G: std_shims::vec![
|
||||||
{G_str}
|
{G_str}
|
||||||
],
|
],
|
||||||
H: std_shims::vec![
|
H: std_shims::vec![
|
||||||
{H_str}
|
{H_str}
|
||||||
],
|
],
|
||||||
}})
|
}});
|
||||||
}}
|
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
.as_bytes(),
|
.as_bytes(),
|
||||||
@@ -67,12 +64,9 @@ fn generators(prefix: &'static str, path: &str) {
|
|||||||
.write_all(
|
.write_all(
|
||||||
format!(
|
format!(
|
||||||
r#"
|
r#"
|
||||||
static GENERATORS_CELL: OnceLock<Generators> = OnceLock::new();
|
pub(crate) static GENERATORS: LazyLock<Generators> = LazyLock::new(|| {{
|
||||||
pub(crate) fn GENERATORS() -> &'static Generators {{
|
|
||||||
GENERATORS_CELL.get_or_init(|| {{
|
|
||||||
monero_generators::bulletproofs_generators(b"{prefix}")
|
monero_generators::bulletproofs_generators(b"{prefix}")
|
||||||
}})
|
}});
|
||||||
}}
|
|
||||||
"#,
|
"#,
|
||||||
)
|
)
|
||||||
.as_bytes(),
|
.as_bytes(),
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ use curve25519_dalek::{
|
|||||||
edwards::EdwardsPoint,
|
edwards::EdwardsPoint,
|
||||||
};
|
};
|
||||||
|
|
||||||
use monero_generators::{H, Generators};
|
use monero_generators::{H as MONERO_H, Generators};
|
||||||
|
|
||||||
use crate::{original, plus};
|
use crate::{original, plus};
|
||||||
|
|
||||||
@@ -57,7 +57,7 @@ pub(crate) struct BulletproofsBatchVerifier(pub(crate) InternalBatchVerifier);
|
|||||||
impl BulletproofsBatchVerifier {
|
impl BulletproofsBatchVerifier {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub(crate) fn verify(self) -> bool {
|
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,7 +68,7 @@ impl BulletproofsPlusBatchVerifier {
|
|||||||
pub(crate) fn verify(self) -> bool {
|
pub(crate) fn verify(self) -> bool {
|
||||||
// Bulletproofs+ is written as per the paper, with G for the value and H for the mask
|
// 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
|
// 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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -96,13 +96,13 @@ impl IpStatement {
|
|||||||
mut transcript: Scalar,
|
mut transcript: Scalar,
|
||||||
witness: IpWitness,
|
witness: IpWitness,
|
||||||
) -> Result<IpProof, IpError> {
|
) -> Result<IpProof, IpError> {
|
||||||
let generators = crate::original::GENERATORS();
|
let generators = &crate::original::GENERATORS;
|
||||||
let g_bold_slice = &generators.G[.. witness.a.len()];
|
let g_bold_slice = &generators.G[.. witness.a.len()];
|
||||||
let h_bold_slice = &generators.H[.. 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 (mut g_bold, mut h_bold, u, mut a, mut b) = {
|
||||||
let IpStatement { h_bold_weights, u } = self;
|
let IpStatement { h_bold_weights, u } = self;
|
||||||
let u = H() * u;
|
let u = *H * u;
|
||||||
|
|
||||||
// Ensure we have the exact amount of weights
|
// Ensure we have the exact amount of weights
|
||||||
if h_bold_weights.len() != g_bold_slice.len() {
|
if h_bold_weights.len() != g_bold_slice.len() {
|
||||||
@@ -218,7 +218,7 @@ impl IpStatement {
|
|||||||
verifier_weight: Scalar,
|
verifier_weight: Scalar,
|
||||||
proof: IpProof,
|
proof: IpProof,
|
||||||
) -> Result<(), IpError> {
|
) -> Result<(), IpError> {
|
||||||
let generators = crate::original::GENERATORS();
|
let generators = &crate::original::GENERATORS;
|
||||||
let g_bold_slice = &generators.G[.. ip_rows];
|
let g_bold_slice = &generators.G[.. ip_rows];
|
||||||
let h_bold_slice = &generators.H[.. ip_rows];
|
let h_bold_slice = &generators.H[.. ip_rows];
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use std_shims::{sync::OnceLock, vec::Vec};
|
use std_shims::{sync::LazyLock, vec::Vec};
|
||||||
|
|
||||||
use rand_core::{RngCore, CryptoRng};
|
use rand_core::{RngCore, CryptoRng};
|
||||||
|
|
||||||
@@ -6,7 +6,7 @@ use zeroize::Zeroize;
|
|||||||
|
|
||||||
use curve25519_dalek::{constants::ED25519_BASEPOINT_POINT, Scalar, EdwardsPoint};
|
use curve25519_dalek::{constants::ED25519_BASEPOINT_POINT, Scalar, EdwardsPoint};
|
||||||
|
|
||||||
use monero_generators::{H, Generators, MAX_COMMITMENTS, COMMITMENT_BITS};
|
use monero_generators::{H as MONERO_H, Generators, MAX_COMMITMENTS, COMMITMENT_BITS};
|
||||||
use monero_primitives::{Commitment, INV_EIGHT, keccak256_to_scalar};
|
use monero_primitives::{Commitment, INV_EIGHT, keccak256_to_scalar};
|
||||||
use crate::{core::multiexp, scalar_vector::ScalarVector, BulletproofsBatchVerifier};
|
use crate::{core::multiexp, scalar_vector::ScalarVector, BulletproofsBatchVerifier};
|
||||||
|
|
||||||
@@ -107,7 +107,7 @@ impl<'a> AggregateRangeStatement<'a> {
|
|||||||
None?
|
None?
|
||||||
};
|
};
|
||||||
|
|
||||||
let generators = GENERATORS();
|
let generators = &GENERATORS;
|
||||||
|
|
||||||
let (mut transcript, _) = self.initial_transcript();
|
let (mut transcript, _) = self.initial_transcript();
|
||||||
|
|
||||||
@@ -186,7 +186,7 @@ impl<'a> AggregateRangeStatement<'a> {
|
|||||||
|
|
||||||
let tau_1 = Scalar::random(&mut *rng);
|
let tau_1 = Scalar::random(&mut *rng);
|
||||||
let T1 = {
|
let T1 = {
|
||||||
let mut T1_terms = [(t1, H()), (tau_1, ED25519_BASEPOINT_POINT)];
|
let mut T1_terms = [(t1, *MONERO_H), (tau_1, ED25519_BASEPOINT_POINT)];
|
||||||
for term in &mut T1_terms {
|
for term in &mut T1_terms {
|
||||||
term.0 *= INV_EIGHT();
|
term.0 *= INV_EIGHT();
|
||||||
}
|
}
|
||||||
@@ -196,7 +196,7 @@ impl<'a> AggregateRangeStatement<'a> {
|
|||||||
};
|
};
|
||||||
let tau_2 = Scalar::random(&mut *rng);
|
let tau_2 = Scalar::random(&mut *rng);
|
||||||
let T2 = {
|
let T2 = {
|
||||||
let mut T2_terms = [(t2, H()), (tau_2, ED25519_BASEPOINT_POINT)];
|
let mut T2_terms = [(t2, *MONERO_H), (tau_2, ED25519_BASEPOINT_POINT)];
|
||||||
for term in &mut T2_terms {
|
for term in &mut T2_terms {
|
||||||
term.0 *= INV_EIGHT();
|
term.0 *= INV_EIGHT();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#![allow(non_snake_case)]
|
#![allow(non_snake_case)]
|
||||||
|
|
||||||
use std_shims::sync::OnceLock;
|
use std_shims::sync::LazyLock;
|
||||||
|
|
||||||
use curve25519_dalek::{constants::ED25519_BASEPOINT_POINT, scalar::Scalar, edwards::EdwardsPoint};
|
use curve25519_dalek::{constants::ED25519_BASEPOINT_POINT, scalar::Scalar, edwards::EdwardsPoint};
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ include!(concat!(env!("OUT_DIR"), "/generators_plus.rs"));
|
|||||||
impl BpPlusGenerators {
|
impl BpPlusGenerators {
|
||||||
#[allow(clippy::new_without_default)]
|
#[allow(clippy::new_without_default)]
|
||||||
pub(crate) fn new() -> Self {
|
pub(crate) fn new() -> Self {
|
||||||
let gens = GENERATORS();
|
let gens = &GENERATORS;
|
||||||
BpPlusGenerators { g_bold: &gens.G, h_bold: &gens.H }
|
BpPlusGenerators { g_bold: &gens.G, h_bold: &gens.H }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@ impl BpPlusGenerators {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn g() -> EdwardsPoint {
|
pub(crate) fn g() -> EdwardsPoint {
|
||||||
H()
|
*H
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn h() -> EdwardsPoint {
|
pub(crate) fn h() -> EdwardsPoint {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use std_shims::{sync::OnceLock, vec::Vec};
|
use std_shims::{sync::LazyLock, vec::Vec};
|
||||||
|
|
||||||
use curve25519_dalek::{scalar::Scalar, edwards::EdwardsPoint};
|
use curve25519_dalek::{scalar::Scalar, edwards::EdwardsPoint};
|
||||||
|
|
||||||
@@ -6,15 +6,12 @@ use monero_generators::hash_to_point;
|
|||||||
use monero_primitives::{keccak256, keccak256_to_scalar};
|
use monero_primitives::{keccak256, keccak256_to_scalar};
|
||||||
|
|
||||||
// Monero starts BP+ transcripts with the following constant.
|
// Monero starts BP+ transcripts with the following constant.
|
||||||
static TRANSCRIPT_CELL: OnceLock<[u8; 32]> = OnceLock::new();
|
|
||||||
pub(crate) fn TRANSCRIPT() -> [u8; 32] {
|
|
||||||
// Why this uses a hash_to_point is completely unknown.
|
// Why this uses a hash_to_point is completely unknown.
|
||||||
*TRANSCRIPT_CELL
|
pub(crate) static TRANSCRIPT: LazyLock<[u8; 32]> =
|
||||||
.get_or_init(|| hash_to_point(keccak256(b"bulletproof_plus_transcript")).compress().to_bytes())
|
LazyLock::new(|| hash_to_point(keccak256(b"bulletproof_plus_transcript")).compress().to_bytes());
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn initial_transcript(commitments: core::slice::Iter<'_, EdwardsPoint>) -> Scalar {
|
pub(crate) fn initial_transcript(commitments: core::slice::Iter<'_, EdwardsPoint>) -> Scalar {
|
||||||
let commitments_hash =
|
let commitments_hash =
|
||||||
keccak256_to_scalar(commitments.flat_map(|V| V.compress().to_bytes()).collect::<Vec<_>>());
|
keccak256_to_scalar(commitments.flat_map(|V| V.compress().to_bytes()).collect::<Vec<_>>());
|
||||||
keccak256_to_scalar([TRANSCRIPT().as_ref(), &commitments_hash.to_bytes()].concat())
|
keccak256_to_scalar([TRANSCRIPT.as_ref(), &commitments_hash.to_bytes()].concat())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,12 +35,12 @@ fn test_zero_inner_product() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_inner_product() {
|
fn test_inner_product() {
|
||||||
// P = sum(g_bold * a, h_bold * b, g * u * <a, b>)
|
// P = sum(g_bold * a, h_bold * b, g * u * <a, b>)
|
||||||
let generators = GENERATORS();
|
let generators = &GENERATORS;
|
||||||
let mut verifier = BulletproofsBatchVerifier::default();
|
let mut verifier = BulletproofsBatchVerifier::default();
|
||||||
verifier.0.g_bold = vec![Scalar::ZERO; 32];
|
verifier.0.g_bold = vec![Scalar::ZERO; 32];
|
||||||
verifier.0.h_bold = vec![Scalar::ZERO; 32];
|
verifier.0.h_bold = vec![Scalar::ZERO; 32];
|
||||||
for i in [1, 2, 4, 8, 16, 32] {
|
for i in [1, 2, 4, 8, 16, 32] {
|
||||||
let g = H();
|
let g = *H;
|
||||||
let mut g_bold = vec![];
|
let mut g_bold = vec![];
|
||||||
let mut h_bold = vec![];
|
let mut h_bold = vec![];
|
||||||
for i in 0 .. i {
|
for i in 0 .. i {
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ license = "MIT"
|
|||||||
repository = "https://github.com/serai-dex/serai/tree/develop/networks/monero/ringct/clsag"
|
repository = "https://github.com/serai-dex/serai/tree/develop/networks/monero/ringct/clsag"
|
||||||
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
rust-version = "1.79"
|
rust-version = "1.80"
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
all-features = true
|
all-features = true
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ license = "MIT"
|
|||||||
repository = "https://github.com/serai-dex/serai/tree/develop/networks/monero/ringct/mlsag"
|
repository = "https://github.com/serai-dex/serai/tree/develop/networks/monero/ringct/mlsag"
|
||||||
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
rust-version = "1.79"
|
rust-version = "1.80"
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
all-features = true
|
all-features = true
|
||||||
|
|||||||
@@ -203,7 +203,7 @@ impl AggregateRingMatrixBuilder {
|
|||||||
AggregateRingMatrixBuilder {
|
AggregateRingMatrixBuilder {
|
||||||
key_ring: vec![],
|
key_ring: vec![],
|
||||||
amounts_ring: vec![],
|
amounts_ring: vec![],
|
||||||
sum_out: commitments.iter().sum::<EdwardsPoint>() + (H() * Scalar::from(fee)),
|
sum_out: commitments.iter().sum::<EdwardsPoint>() + (*H * Scalar::from(fee)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ license = "MIT"
|
|||||||
repository = "https://github.com/serai-dex/serai/tree/develop/networks/monero/rpc"
|
repository = "https://github.com/serai-dex/serai/tree/develop/networks/monero/rpc"
|
||||||
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
rust-version = "1.79"
|
rust-version = "1.80"
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
all-features = true
|
all-features = true
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ license = "MIT"
|
|||||||
repository = "https://github.com/serai-dex/serai/tree/develop/networks/monero/rpc/simple-request"
|
repository = "https://github.com/serai-dex/serai/tree/develop/networks/monero/rpc/simple-request"
|
||||||
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
rust-version = "1.79"
|
rust-version = "1.80"
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
all-features = true
|
all-features = true
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use std::sync::OnceLock;
|
use std::sync::LazyLock;
|
||||||
use tokio::sync::Mutex;
|
use tokio::sync::Mutex;
|
||||||
|
|
||||||
use monero_address::{Network, MoneroAddress};
|
use monero_address::{Network, MoneroAddress};
|
||||||
@@ -8,7 +8,7 @@ use monero_address::{Network, MoneroAddress};
|
|||||||
// Accordingly, we test monero-rpc here (implicitly testing the simple-request transport)
|
// Accordingly, we test monero-rpc here (implicitly testing the simple-request transport)
|
||||||
use monero_simple_request_rpc::*;
|
use monero_simple_request_rpc::*;
|
||||||
|
|
||||||
static SEQUENTIAL: OnceLock<Mutex<()>> = OnceLock::new();
|
static SEQUENTIAL: LazyLock<Mutex<()>> = LazyLock::new(|| Mutex::new(()));
|
||||||
|
|
||||||
const ADDRESS: &str =
|
const ADDRESS: &str =
|
||||||
"4B33mFPMq6mKi7Eiyd5XuyKRVMGVZz1Rqb9ZTyGApXW5d1aT7UBDZ89ewmnWFkzJ5wPd2SFbn313vCT8a4E2Qf4KQH4pNey";
|
"4B33mFPMq6mKi7Eiyd5XuyKRVMGVZz1Rqb9ZTyGApXW5d1aT7UBDZ89ewmnWFkzJ5wPd2SFbn313vCT8a4E2Qf4KQH4pNey";
|
||||||
@@ -17,7 +17,7 @@ const ADDRESS: &str =
|
|||||||
async fn test_rpc() {
|
async fn test_rpc() {
|
||||||
use monero_rpc::Rpc;
|
use monero_rpc::Rpc;
|
||||||
|
|
||||||
let guard = SEQUENTIAL.get_or_init(|| Mutex::new(())).lock().await;
|
let guard = SEQUENTIAL.lock().await;
|
||||||
|
|
||||||
let rpc =
|
let rpc =
|
||||||
SimpleRequestRpc::new("http://serai:seraidex@127.0.0.1:18081".to_string()).await.unwrap();
|
SimpleRequestRpc::new("http://serai:seraidex@127.0.0.1:18081".to_string()).await.unwrap();
|
||||||
@@ -68,7 +68,7 @@ async fn test_rpc() {
|
|||||||
async fn test_decoy_rpc() {
|
async fn test_decoy_rpc() {
|
||||||
use monero_rpc::{Rpc, DecoyRpc};
|
use monero_rpc::{Rpc, DecoyRpc};
|
||||||
|
|
||||||
let guard = SEQUENTIAL.get_or_init(|| Mutex::new(())).lock().await;
|
let guard = SEQUENTIAL.lock().await;
|
||||||
|
|
||||||
let rpc =
|
let rpc =
|
||||||
SimpleRequestRpc::new("http://serai:seraidex@127.0.0.1:18081".to_string()).await.unwrap();
|
SimpleRequestRpc::new("http://serai:seraidex@127.0.0.1:18081".to_string()).await.unwrap();
|
||||||
@@ -122,7 +122,7 @@ async fn test_decoy_rpc() {
|
|||||||
async fn test_zero_out_tx_o_indexes() {
|
async fn test_zero_out_tx_o_indexes() {
|
||||||
use monero_rpc::Rpc;
|
use monero_rpc::Rpc;
|
||||||
|
|
||||||
let guard = SEQUENTIAL.get_or_init(|| Mutex::new(())).lock().await;
|
let guard = SEQUENTIAL.lock().await;
|
||||||
|
|
||||||
let rpc = SimpleRequestRpc::new("https://node.sethforprivacy.com".to_string()).await.unwrap();
|
let rpc = SimpleRequestRpc::new("https://node.sethforprivacy.com".to_string()).await.unwrap();
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ license = "MIT"
|
|||||||
repository = "https://github.com/serai-dex/serai/tree/develop/networks/monero/verify-chain"
|
repository = "https://github.com/serai-dex/serai/tree/develop/networks/monero/verify-chain"
|
||||||
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
rust-version = "1.79"
|
rust-version = "1.80"
|
||||||
publish = false
|
publish = false
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ license = "MIT"
|
|||||||
repository = "https://github.com/serai-dex/serai/tree/develop/networks/monero/wallet"
|
repository = "https://github.com/serai-dex/serai/tree/develop/networks/monero/wallet"
|
||||||
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
rust-version = "1.79"
|
rust-version = "1.80"
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
all-features = true
|
all-features = true
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ license = "MIT"
|
|||||||
repository = "https://github.com/serai-dex/serai/tree/develop/networks/monero/wallet/address"
|
repository = "https://github.com/serai-dex/serai/tree/develop/networks/monero/wallet/address"
|
||||||
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
rust-version = "1.79"
|
rust-version = "1.80"
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
all-features = true
|
all-features = true
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ license = "MIT"
|
|||||||
repository = "https://github.com/serai-dex/serai/tree/develop/networks/monero/wallet/polyseed"
|
repository = "https://github.com/serai-dex/serai/tree/develop/networks/monero/wallet/polyseed"
|
||||||
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
rust-version = "1.79"
|
rust-version = "1.80"
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
all-features = true
|
all-features = true
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
#![cfg_attr(not(feature = "std"), no_std)]
|
#![cfg_attr(not(feature = "std"), no_std)]
|
||||||
|
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
use std_shims::{sync::OnceLock, string::String, collections::HashMap};
|
use std_shims::{sync::LazyLock, string::String, collections::HashMap};
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use std::time::{SystemTime, UNIX_EPOCH};
|
use std::time::{SystemTime, UNIX_EPOCH};
|
||||||
|
|
||||||
@@ -163,10 +163,7 @@ impl WordList {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static LANGUAGES_CELL: OnceLock<HashMap<Language, WordList>> = OnceLock::new();
|
static LANGUAGES: LazyLock<HashMap<Language, WordList>> = LazyLock::new(|| {
|
||||||
#[allow(non_snake_case)]
|
|
||||||
fn LANGUAGES() -> &'static HashMap<Language, WordList> {
|
|
||||||
LANGUAGES_CELL.get_or_init(|| {
|
|
||||||
HashMap::from([
|
HashMap::from([
|
||||||
(Language::Czech, WordList::new(include!("./words/cs.rs"), true, false)),
|
(Language::Czech, WordList::new(include!("./words/cs.rs"), true, false)),
|
||||||
(Language::French, WordList::new(include!("./words/fr.rs"), true, true)),
|
(Language::French, WordList::new(include!("./words/fr.rs"), true, true)),
|
||||||
@@ -185,8 +182,7 @@ fn LANGUAGES() -> &'static HashMap<Language, WordList> {
|
|||||||
WordList::new(include!("./words/zh_traditional.rs"), false, false),
|
WordList::new(include!("./words/zh_traditional.rs"), false, false),
|
||||||
),
|
),
|
||||||
])
|
])
|
||||||
})
|
});
|
||||||
}
|
|
||||||
|
|
||||||
/// A Polyseed.
|
/// A Polyseed.
|
||||||
#[derive(Clone, PartialEq, Eq, Zeroize, ZeroizeOnDrop)]
|
#[derive(Clone, PartialEq, Eq, Zeroize, ZeroizeOnDrop)]
|
||||||
@@ -317,7 +313,7 @@ impl Polyseed {
|
|||||||
let mut poly = [0; POLYSEED_LENGTH];
|
let mut poly = [0; POLYSEED_LENGTH];
|
||||||
|
|
||||||
// Validate words are in the lang word list
|
// Validate words are in the lang word list
|
||||||
let lang_word_list: &WordList = &LANGUAGES()[&lang];
|
let lang_word_list: &WordList = &LANGUAGES[&lang];
|
||||||
for (i, word) in seed.split_whitespace().enumerate() {
|
for (i, word) in seed.split_whitespace().enumerate() {
|
||||||
// Find the word's index
|
// Find the word's index
|
||||||
fn check_if_matches<S: AsRef<str>, I: Iterator<Item = S>>(
|
fn check_if_matches<S: AsRef<str>, I: Iterator<Item = S>>(
|
||||||
@@ -464,7 +460,7 @@ impl Polyseed {
|
|||||||
|
|
||||||
// Output words
|
// Output words
|
||||||
let mut seed = Zeroizing::new(String::new());
|
let mut seed = Zeroizing::new(String::new());
|
||||||
let words = &LANGUAGES()[&self.language].words;
|
let words = &LANGUAGES[&self.language].words;
|
||||||
for i in 0 .. poly.len() {
|
for i in 0 .. poly.len() {
|
||||||
seed.push_str(words[usize::from(poly[i])]);
|
seed.push_str(words[usize::from(poly[i])]);
|
||||||
if i < poly.len() - 1 {
|
if i < poly.len() - 1 {
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ license = "MIT"
|
|||||||
repository = "https://github.com/serai-dex/serai/tree/develop/networks/monero/wallet/seed"
|
repository = "https://github.com/serai-dex/serai/tree/develop/networks/monero/wallet/seed"
|
||||||
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
rust-version = "1.79"
|
rust-version = "1.80"
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
all-features = true
|
all-features = true
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
use core::{ops::Deref, fmt};
|
use core::{ops::Deref, fmt};
|
||||||
use std_shims::{
|
use std_shims::{
|
||||||
sync::OnceLock,
|
sync::LazyLock,
|
||||||
vec,
|
vec,
|
||||||
vec::Vec,
|
vec::Vec,
|
||||||
string::{String, ToString},
|
string::{String, ToString},
|
||||||
@@ -102,10 +102,7 @@ impl WordList {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static LANGUAGES_CELL: OnceLock<HashMap<Language, WordList>> = OnceLock::new();
|
static LANGUAGES: LazyLock<HashMap<Language, WordList>> = LazyLock::new(|| {
|
||||||
#[allow(non_snake_case)]
|
|
||||||
fn LANGUAGES() -> &'static HashMap<Language, WordList> {
|
|
||||||
LANGUAGES_CELL.get_or_init(|| {
|
|
||||||
HashMap::from([
|
HashMap::from([
|
||||||
(Language::Chinese, WordList::new(include!("./words/zh.rs"), 1)),
|
(Language::Chinese, WordList::new(include!("./words/zh.rs"), 1)),
|
||||||
(Language::English, WordList::new(include!("./words/en.rs"), 3)),
|
(Language::English, WordList::new(include!("./words/en.rs"), 3)),
|
||||||
@@ -121,8 +118,7 @@ fn LANGUAGES() -> &'static HashMap<Language, WordList> {
|
|||||||
(Language::Lojban, WordList::new(include!("./words/jbo.rs"), 4)),
|
(Language::Lojban, WordList::new(include!("./words/jbo.rs"), 4)),
|
||||||
(Language::DeprecatedEnglish, WordList::new(include!("./words/ang.rs"), 4)),
|
(Language::DeprecatedEnglish, WordList::new(include!("./words/ang.rs"), 4)),
|
||||||
])
|
])
|
||||||
})
|
});
|
||||||
}
|
|
||||||
|
|
||||||
fn checksum_index(words: &[Zeroizing<String>], lang: &WordList) -> usize {
|
fn checksum_index(words: &[Zeroizing<String>], lang: &WordList) -> usize {
|
||||||
let mut trimmed_words = Zeroizing::new(String::new());
|
let mut trimmed_words = Zeroizing::new(String::new());
|
||||||
@@ -170,7 +166,7 @@ fn key_to_seed(lang: Language, key: Zeroizing<Scalar>) -> Seed {
|
|||||||
let bytes = Zeroizing::new(key.to_bytes());
|
let bytes = Zeroizing::new(key.to_bytes());
|
||||||
|
|
||||||
// get the language words
|
// get the language words
|
||||||
let words = &LANGUAGES()[&lang].word_list;
|
let words = &LANGUAGES[&lang].word_list;
|
||||||
let list_len = u64::try_from(words.len()).unwrap();
|
let list_len = u64::try_from(words.len()).unwrap();
|
||||||
|
|
||||||
// To store the found words & add the checksum word later.
|
// To store the found words & add the checksum word later.
|
||||||
@@ -204,7 +200,7 @@ fn key_to_seed(lang: Language, key: Zeroizing<Scalar>) -> Seed {
|
|||||||
|
|
||||||
// create a checksum word for all languages except old english
|
// create a checksum word for all languages except old english
|
||||||
if lang != Language::DeprecatedEnglish {
|
if lang != Language::DeprecatedEnglish {
|
||||||
let checksum = seed[checksum_index(&seed, &LANGUAGES()[&lang])].clone();
|
let checksum = seed[checksum_index(&seed, &LANGUAGES[&lang])].clone();
|
||||||
seed.push(checksum);
|
seed.push(checksum);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -232,7 +228,7 @@ fn seed_to_bytes(lang: Language, words: &str) -> Result<Zeroizing<[u8; 32]>, See
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Validate words are in the language word list
|
// Validate words are in the language word list
|
||||||
let lang_word_list: &WordList = &LANGUAGES()[&lang];
|
let lang_word_list: &WordList = &LANGUAGES[&lang];
|
||||||
let matched_indices = (|| {
|
let matched_indices = (|| {
|
||||||
let has_checksum = words.len() == SEED_LENGTH_WITH_CHECKSUM;
|
let has_checksum = words.len() == SEED_LENGTH_WITH_CHECKSUM;
|
||||||
let mut matched_indices = Zeroizing::new(vec![]);
|
let mut matched_indices = Zeroizing::new(vec![]);
|
||||||
|
|||||||
@@ -183,7 +183,7 @@ fn test_original_seed() {
|
|||||||
for vector in vectors {
|
for vector in vectors {
|
||||||
fn trim_by_lang(word: &str, lang: Language) -> String {
|
fn trim_by_lang(word: &str, lang: Language) -> String {
|
||||||
if lang != Language::DeprecatedEnglish {
|
if lang != Language::DeprecatedEnglish {
|
||||||
word.chars().take(LANGUAGES()[&lang].unique_prefix_length).collect()
|
word.chars().take(LANGUAGES[&lang].unique_prefix_length).collect()
|
||||||
} else {
|
} else {
|
||||||
word.to_string()
|
word.to_string()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use core::ops::Deref;
|
use core::ops::Deref;
|
||||||
use std_shims::sync::OnceLock;
|
use std_shims::sync::LazyLock;
|
||||||
|
|
||||||
use zeroize::Zeroizing;
|
use zeroize::Zeroizing;
|
||||||
use rand_core::OsRng;
|
use rand_core::OsRng;
|
||||||
@@ -145,7 +145,7 @@ pub async fn rpc() -> SimpleRequestRpc {
|
|||||||
rpc
|
rpc
|
||||||
}
|
}
|
||||||
|
|
||||||
pub static SEQUENTIAL: OnceLock<Mutex<()>> = OnceLock::new();
|
pub(crate) static SEQUENTIAL: LazyLock<Mutex<()>> = LazyLock::new(|| Mutex::new(()));
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! async_sequential {
|
macro_rules! async_sequential {
|
||||||
@@ -153,7 +153,7 @@ macro_rules! async_sequential {
|
|||||||
$(
|
$(
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn $name() {
|
async fn $name() {
|
||||||
let guard = runner::SEQUENTIAL.get_or_init(|| tokio::sync::Mutex::new(())).lock().await;
|
let guard = runner::SEQUENTIAL.lock().await;
|
||||||
let local = tokio::task::LocalSet::new();
|
let local = tokio::task::LocalSet::new();
|
||||||
local.run_until(async move {
|
local.run_until(async move {
|
||||||
if let Err(err) = tokio::task::spawn_local(async move { $body }).await {
|
if let Err(err) = tokio::task::spawn_local(async move { $body }).await {
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ license = "MIT"
|
|||||||
repository = "https://github.com/serai-dex/serai/tree/develop/networks/monero/wallet/util"
|
repository = "https://github.com/serai-dex/serai/tree/develop/networks/monero/wallet/util"
|
||||||
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
rust-version = "1.79"
|
rust-version = "1.80"
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
all-features = true
|
all-features = true
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
# rust:1.79.0-slim-bookworm as of June 14th, 2024 (GMT)
|
# rust:1.80.0-slim-bookworm as of July 27th, 2024 (GMT)
|
||||||
FROM --platform=linux/amd64 rust@sha256:fa189cd885739dd17fc6bb4e132687fce43f2bf42983c0ac39b60e4943201e9c as deterministic
|
FROM --platform=linux/amd64 rust@sha256:37e6f90f98b3afd15c2526d7abb257a1f4cb7d49808fe3729d9d62020b07b544 as deterministic
|
||||||
|
|
||||||
# Move to a Debian package snapshot
|
# Move to a Debian package snapshot
|
||||||
RUN rm -rf /etc/apt/sources.list.d/debian.sources && \
|
RUN rm -rf /etc/apt/sources.list.d/debian.sources && \
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ fn build_serai_service(prelude: &str, release: bool, features: &str, package: &s
|
|||||||
|
|
||||||
format!(
|
format!(
|
||||||
r#"
|
r#"
|
||||||
FROM rust:1.79-slim-bookworm as builder
|
FROM rust:1.80-slim-bookworm as builder
|
||||||
|
|
||||||
COPY --from=mimalloc-debian libmimalloc.so /usr/lib
|
COPY --from=mimalloc-debian libmimalloc.so /usr/lib
|
||||||
RUN echo "/usr/lib/libmimalloc.so" >> /etc/ld.so.preload
|
RUN echo "/usr/lib/libmimalloc.so" >> /etc/ld.so.preload
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
[toolchain]
|
[toolchain]
|
||||||
channel = "1.79"
|
channel = "1.80"
|
||||||
targets = ["wasm32-unknown-unknown"]
|
targets = ["wasm32-unknown-unknown"]
|
||||||
profile = "minimal"
|
profile = "minimal"
|
||||||
components = ["rust-src", "rustfmt", "clippy"]
|
components = ["rust-src", "rustfmt", "clippy"]
|
||||||
|
|||||||
Reference in New Issue
Block a user