mirror of
https://github.com/serai-dex/serai.git
synced 2024-12-22 11:39:35 +00:00
Rust 1.80
Some checks failed
Coordinator Tests / build (push) Has been cancelled
crypto/ Tests / test-crypto (push) Has been cancelled
Full Stack Tests / build (push) Has been cancelled
Lint / clippy (macos-13) (push) Has been cancelled
Lint / clippy (macos-14) (push) Has been cancelled
Lint / clippy (ubuntu-latest) (push) Has been cancelled
Lint / clippy (windows-latest) (push) Has been cancelled
Lint / deny (push) Has been cancelled
Lint / fmt (push) Has been cancelled
Lint / machete (push) Has been cancelled
Message Queue Tests / build (push) Has been cancelled
Monero Tests / unit-tests (push) Has been cancelled
Reproducible Runtime / build (push) Has been cancelled
Tests / test-infra (push) Has been cancelled
common/ Tests / test-common (push) Has been cancelled
Monero Tests / integration-tests (v0.17.3.2) (push) Has been cancelled
Monero Tests / integration-tests (v0.18.2.0) (push) Has been cancelled
networks/ Tests / test-networks (push) Has been cancelled
no-std build / build (push) Has been cancelled
Processor Tests / build (push) Has been cancelled
Tests / test-substrate (push) Has been cancelled
Tests / test-serai-client (push) Has been cancelled
Some checks failed
Coordinator Tests / build (push) Has been cancelled
crypto/ Tests / test-crypto (push) Has been cancelled
Full Stack Tests / build (push) Has been cancelled
Lint / clippy (macos-13) (push) Has been cancelled
Lint / clippy (macos-14) (push) Has been cancelled
Lint / clippy (ubuntu-latest) (push) Has been cancelled
Lint / clippy (windows-latest) (push) Has been cancelled
Lint / deny (push) Has been cancelled
Lint / fmt (push) Has been cancelled
Lint / machete (push) Has been cancelled
Message Queue Tests / build (push) Has been cancelled
Monero Tests / unit-tests (push) Has been cancelled
Reproducible Runtime / build (push) Has been cancelled
Tests / test-infra (push) Has been cancelled
common/ Tests / test-common (push) Has been cancelled
Monero Tests / integration-tests (v0.17.3.2) (push) Has been cancelled
Monero Tests / integration-tests (v0.18.2.0) (push) Has been cancelled
networks/ Tests / test-networks (push) Has been cancelled
no-std build / build (push) Has been cancelled
Processor Tests / build (push) Has been cancelled
Tests / test-substrate (push) Has been cancelled
Tests / test-serai-client (push) Has been cancelled
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:
parent
6f34c2ff77
commit
880565cb81
38 changed files with 147 additions and 195 deletions
|
@ -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] {
|
let mut precomputed_scalars = [Scalar::ONE; 8];
|
||||||
*PRECOMPUTED_SCALARS_CELL.get_or_init(|| {
|
for (i, scalar) in precomputed_scalars.iter_mut().enumerate().skip(1) {
|
||||||
let mut precomputed_scalars = [Scalar::ONE; 8];
|
*scalar = Scalar::from(u8::try_from((i * 2) + 1).unwrap());
|
||||||
for (i, scalar) in precomputed_scalars.iter_mut().enumerate().skip(1) {
|
}
|
||||||
*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 {{
|
G: std_shims::vec![
|
||||||
GENERATORS_CELL.get_or_init(|| Generators {{
|
{G_str}
|
||||||
G: std_shims::vec![
|
],
|
||||||
{G_str}
|
H: std_shims::vec![
|
||||||
],
|
{H_str}
|
||||||
H: std_shims::vec![
|
],
|
||||||
{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 {{
|
monero_generators::bulletproofs_generators(b"{prefix}")
|
||||||
GENERATORS_CELL.get_or_init(|| {{
|
}});
|
||||||
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();
|
// Why this uses a hash_to_point is completely unknown.
|
||||||
pub(crate) fn TRANSCRIPT() -> [u8; 32] {
|
pub(crate) static TRANSCRIPT: LazyLock<[u8; 32]> =
|
||||||
// Why this uses a hash_to_point is completely unknown.
|
LazyLock::new(|| hash_to_point(keccak256(b"bulletproof_plus_transcript")).compress().to_bytes());
|
||||||
*TRANSCRIPT_CELL
|
|
||||||
.get_or_init(|| 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,30 +163,26 @@ impl WordList {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static LANGUAGES_CELL: OnceLock<HashMap<Language, WordList>> = OnceLock::new();
|
static LANGUAGES: LazyLock<HashMap<Language, WordList>> = LazyLock::new(|| {
|
||||||
#[allow(non_snake_case)]
|
HashMap::from([
|
||||||
fn LANGUAGES() -> &'static HashMap<Language, WordList> {
|
(Language::Czech, WordList::new(include!("./words/cs.rs"), true, false)),
|
||||||
LANGUAGES_CELL.get_or_init(|| {
|
(Language::French, WordList::new(include!("./words/fr.rs"), true, true)),
|
||||||
HashMap::from([
|
(Language::Korean, WordList::new(include!("./words/ko.rs"), false, false)),
|
||||||
(Language::Czech, WordList::new(include!("./words/cs.rs"), true, false)),
|
(Language::English, WordList::new(include!("./words/en.rs"), true, false)),
|
||||||
(Language::French, WordList::new(include!("./words/fr.rs"), true, true)),
|
(Language::Italian, WordList::new(include!("./words/it.rs"), true, false)),
|
||||||
(Language::Korean, WordList::new(include!("./words/ko.rs"), false, false)),
|
(Language::Spanish, WordList::new(include!("./words/es.rs"), true, true)),
|
||||||
(Language::English, WordList::new(include!("./words/en.rs"), true, false)),
|
(Language::Japanese, WordList::new(include!("./words/ja.rs"), false, false)),
|
||||||
(Language::Italian, WordList::new(include!("./words/it.rs"), true, false)),
|
(Language::Portuguese, WordList::new(include!("./words/pt.rs"), true, false)),
|
||||||
(Language::Spanish, WordList::new(include!("./words/es.rs"), true, true)),
|
(
|
||||||
(Language::Japanese, WordList::new(include!("./words/ja.rs"), false, false)),
|
Language::ChineseSimplified,
|
||||||
(Language::Portuguese, WordList::new(include!("./words/pt.rs"), true, false)),
|
WordList::new(include!("./words/zh_simplified.rs"), false, false),
|
||||||
(
|
),
|
||||||
Language::ChineseSimplified,
|
(
|
||||||
WordList::new(include!("./words/zh_simplified.rs"), false, false),
|
Language::ChineseTraditional,
|
||||||
),
|
WordList::new(include!("./words/zh_traditional.rs"), false, false),
|
||||||
(
|
),
|
||||||
Language::ChineseTraditional,
|
])
|
||||||
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,27 +102,23 @@ impl WordList {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static LANGUAGES_CELL: OnceLock<HashMap<Language, WordList>> = OnceLock::new();
|
static LANGUAGES: LazyLock<HashMap<Language, WordList>> = LazyLock::new(|| {
|
||||||
#[allow(non_snake_case)]
|
HashMap::from([
|
||||||
fn LANGUAGES() -> &'static HashMap<Language, WordList> {
|
(Language::Chinese, WordList::new(include!("./words/zh.rs"), 1)),
|
||||||
LANGUAGES_CELL.get_or_init(|| {
|
(Language::English, WordList::new(include!("./words/en.rs"), 3)),
|
||||||
HashMap::from([
|
(Language::Dutch, WordList::new(include!("./words/nl.rs"), 4)),
|
||||||
(Language::Chinese, WordList::new(include!("./words/zh.rs"), 1)),
|
(Language::French, WordList::new(include!("./words/fr.rs"), 4)),
|
||||||
(Language::English, WordList::new(include!("./words/en.rs"), 3)),
|
(Language::Spanish, WordList::new(include!("./words/es.rs"), 4)),
|
||||||
(Language::Dutch, WordList::new(include!("./words/nl.rs"), 4)),
|
(Language::German, WordList::new(include!("./words/de.rs"), 4)),
|
||||||
(Language::French, WordList::new(include!("./words/fr.rs"), 4)),
|
(Language::Italian, WordList::new(include!("./words/it.rs"), 4)),
|
||||||
(Language::Spanish, WordList::new(include!("./words/es.rs"), 4)),
|
(Language::Portuguese, WordList::new(include!("./words/pt.rs"), 4)),
|
||||||
(Language::German, WordList::new(include!("./words/de.rs"), 4)),
|
(Language::Japanese, WordList::new(include!("./words/ja.rs"), 3)),
|
||||||
(Language::Italian, WordList::new(include!("./words/it.rs"), 4)),
|
(Language::Russian, WordList::new(include!("./words/ru.rs"), 4)),
|
||||||
(Language::Portuguese, WordList::new(include!("./words/pt.rs"), 4)),
|
(Language::Esperanto, WordList::new(include!("./words/eo.rs"), 4)),
|
||||||
(Language::Japanese, WordList::new(include!("./words/ja.rs"), 3)),
|
(Language::Lojban, WordList::new(include!("./words/jbo.rs"), 4)),
|
||||||
(Language::Russian, WordList::new(include!("./words/ru.rs"), 4)),
|
(Language::DeprecatedEnglish, WordList::new(include!("./words/ang.rs"), 4)),
|
||||||
(Language::Esperanto, WordList::new(include!("./words/eo.rs"), 4)),
|
])
|
||||||
(Language::Lojban, WordList::new(include!("./words/jbo.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"]
|
||||||
|
|
Loading…
Reference in a new issue