mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-11 21:49:26 +00:00
Smash out Borromean
This commit is contained in:
15
Cargo.lock
generated
15
Cargo.lock
generated
@@ -4751,6 +4751,18 @@ dependencies = [
|
|||||||
"zeroize",
|
"zeroize",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "monero-borromean"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"curve25519-dalek",
|
||||||
|
"monero-generators",
|
||||||
|
"monero-io",
|
||||||
|
"monero-primitives",
|
||||||
|
"std-shims",
|
||||||
|
"zeroize",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "monero-bulletproofs"
|
name = "monero-bulletproofs"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
@@ -4827,7 +4839,9 @@ name = "monero-primitives"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"curve25519-dalek",
|
"curve25519-dalek",
|
||||||
|
"hex",
|
||||||
"monero-generators",
|
"monero-generators",
|
||||||
|
"monero-io",
|
||||||
"sha3",
|
"sha3",
|
||||||
"std-shims",
|
"std-shims",
|
||||||
"zeroize",
|
"zeroize",
|
||||||
@@ -4847,6 +4861,7 @@ dependencies = [
|
|||||||
"hex",
|
"hex",
|
||||||
"hex-literal",
|
"hex-literal",
|
||||||
"modular-frost",
|
"modular-frost",
|
||||||
|
"monero-borromean",
|
||||||
"monero-bulletproofs",
|
"monero-bulletproofs",
|
||||||
"monero-clsag",
|
"monero-clsag",
|
||||||
"monero-generators",
|
"monero-generators",
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ members = [
|
|||||||
"coins/monero/primitives",
|
"coins/monero/primitives",
|
||||||
"coins/monero/ringct/mlsag",
|
"coins/monero/ringct/mlsag",
|
||||||
"coins/monero/ringct/clsag",
|
"coins/monero/ringct/clsag",
|
||||||
|
"coins/monero/ringct/borromean",
|
||||||
"coins/monero/ringct/bulletproofs",
|
"coins/monero/ringct/bulletproofs",
|
||||||
"coins/monero",
|
"coins/monero",
|
||||||
|
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ monero-generators = { path = "generators", version = "0.4", default-features = f
|
|||||||
monero-primitives = { path = "primitives", version = "0.1", default-features = false }
|
monero-primitives = { path = "primitives", version = "0.1", default-features = false }
|
||||||
monero-mlsag = { path = "ringct/mlsag", version = "0.1", default-features = false }
|
monero-mlsag = { path = "ringct/mlsag", version = "0.1", default-features = false }
|
||||||
monero-clsag = { path = "ringct/clsag", version = "0.1", default-features = false }
|
monero-clsag = { path = "ringct/clsag", version = "0.1", default-features = false }
|
||||||
|
monero-borromean = { path = "ringct/borromean", version = "0.1", default-features = false }
|
||||||
monero-bulletproofs = { path = "ringct/bulletproofs", version = "0.1", default-features = false }
|
monero-bulletproofs = { path = "ringct/bulletproofs", version = "0.1", default-features = false }
|
||||||
|
|
||||||
hex-literal = "0.4"
|
hex-literal = "0.4"
|
||||||
|
|||||||
@@ -25,8 +25,12 @@ sha3 = { version = "0.10", default-features = false }
|
|||||||
curve25519-dalek = { version = "4", default-features = false, features = ["alloc", "zeroize"] }
|
curve25519-dalek = { version = "4", default-features = false, features = ["alloc", "zeroize"] }
|
||||||
|
|
||||||
# Other Monero dependencies
|
# Other Monero dependencies
|
||||||
|
monero-io = { path = "../io", version = "0.1", default-features = false }
|
||||||
monero-generators = { path = "../generators", version = "0.4", default-features = false }
|
monero-generators = { path = "../generators", version = "0.4", default-features = false }
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
hex = { version = "0.4", default-features = false, features = ["alloc"] }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
std = [
|
std = [
|
||||||
"std-shims/std",
|
"std-shims/std",
|
||||||
|
|||||||
@@ -19,6 +19,12 @@ use curve25519_dalek::{
|
|||||||
|
|
||||||
use monero_generators::H;
|
use monero_generators::H;
|
||||||
|
|
||||||
|
mod unreduced_scalar;
|
||||||
|
pub use unreduced_scalar::UnreducedScalar;
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
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: OnceLock<Scalar> = OnceLock::new();
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use curve25519_dalek::scalar::Scalar;
|
use curve25519_dalek::scalar::Scalar;
|
||||||
|
|
||||||
use crate::unreduced_scalar::*;
|
use crate::UnreducedScalar;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn recover_scalars() {
|
fn recover_scalars() {
|
||||||
@@ -1,18 +1,19 @@
|
|||||||
use core::cmp::Ordering;
|
use core::cmp::Ordering;
|
||||||
|
|
||||||
use std_shims::{
|
use std_shims::{
|
||||||
sync::OnceLock,
|
sync::OnceLock,
|
||||||
io::{self, *},
|
io::{self, *},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use zeroize::Zeroize;
|
||||||
|
|
||||||
use curve25519_dalek::scalar::Scalar;
|
use curve25519_dalek::scalar::Scalar;
|
||||||
|
|
||||||
use crate::serialize::*;
|
use monero_io::*;
|
||||||
|
|
||||||
static PRECOMPUTED_SCALARS_CELL: OnceLock<[Scalar; 8]> = OnceLock::new();
|
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)]
|
#[allow(non_snake_case)]
|
||||||
pub(crate) fn PRECOMPUTED_SCALARS() -> [Scalar; 8] {
|
fn PRECOMPUTED_SCALARS() -> [Scalar; 8] {
|
||||||
*PRECOMPUTED_SCALARS_CELL.get_or_init(|| {
|
*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) {
|
||||||
@@ -22,14 +23,23 @@ pub(crate) fn PRECOMPUTED_SCALARS() -> [Scalar; 8] {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
/// An unreduced scalar.
|
||||||
|
///
|
||||||
|
/// While most of modern Monero enforces scalars be reduced, certain legacy parts of the code did
|
||||||
|
/// not. These section can generally simply be read as a scalar/reduced into a scalar when the time
|
||||||
|
/// comes, yet a couple have non-standard reductions performed.
|
||||||
|
///
|
||||||
|
/// This struct delays scalar conversions and offers the non-standard reduction.
|
||||||
|
#[derive(Clone, PartialEq, Eq, Debug, Zeroize)]
|
||||||
pub struct UnreducedScalar(pub [u8; 32]);
|
pub struct UnreducedScalar(pub [u8; 32]);
|
||||||
|
|
||||||
impl UnreducedScalar {
|
impl UnreducedScalar {
|
||||||
|
/// Write an UnreducedScalar.
|
||||||
pub fn write<W: Write>(&self, w: &mut W) -> io::Result<()> {
|
pub fn write<W: Write>(&self, w: &mut W) -> io::Result<()> {
|
||||||
w.write_all(&self.0)
|
w.write_all(&self.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Read an UnreducedScalar.
|
||||||
pub fn read<R: Read>(r: &mut R) -> io::Result<UnreducedScalar> {
|
pub fn read<R: Read>(r: &mut R) -> io::Result<UnreducedScalar> {
|
||||||
Ok(UnreducedScalar(read_bytes(r)?))
|
Ok(UnreducedScalar(read_bytes(r)?))
|
||||||
}
|
}
|
||||||
@@ -43,12 +53,12 @@ impl UnreducedScalar {
|
|||||||
bits
|
bits
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the non-adjacent form of this scalar with width 5.
|
// Computes the non-adjacent form of this scalar with width 5.
|
||||||
///
|
//
|
||||||
/// This matches Monero's `slide` function and intentionally gives incorrect outputs under
|
// This matches Monero's `slide` function and intentionally gives incorrect outputs under
|
||||||
/// certain conditions in order to match Monero.
|
// certain conditions in order to match Monero.
|
||||||
///
|
//
|
||||||
/// This function does not execute in constant time.
|
// This function does not execute in constant time.
|
||||||
fn non_adjacent_form(&self) -> [i8; 256] {
|
fn non_adjacent_form(&self) -> [i8; 256] {
|
||||||
let bits = self.as_bits();
|
let bits = self.as_bits();
|
||||||
let mut naf = [0i8; 256];
|
let mut naf = [0i8; 256];
|
||||||
@@ -104,11 +114,11 @@ impl UnreducedScalar {
|
|||||||
/// Recover the scalar that an array of bytes was incorrectly interpreted as by Monero's `slide`
|
/// Recover the scalar that an array of bytes was incorrectly interpreted as by Monero's `slide`
|
||||||
/// function.
|
/// function.
|
||||||
///
|
///
|
||||||
/// In Borromean range proofs Monero was not checking that the scalars used were
|
/// In Borromean range proofs, Monero was not checking that the scalars used were
|
||||||
/// reduced. This lead to the scalar stored being interpreted as a different scalar,
|
/// reduced. This lead to the scalar stored being interpreted as a different scalar.
|
||||||
/// this function recovers that scalar.
|
/// This function recovers that scalar.
|
||||||
///
|
///
|
||||||
/// See: https://github.com/monero-project/monero/issues/8438
|
/// See https://github.com/monero-project/monero/issues/8438 for more info.
|
||||||
pub fn recover_monero_slide_scalar(&self) -> Scalar {
|
pub fn recover_monero_slide_scalar(&self) -> Scalar {
|
||||||
if self.0[31] & 128 == 0 {
|
if self.0[31] & 128 == 0 {
|
||||||
// Computing the w-NAF of a number can only give an output with 1 more bit than
|
// Computing the w-NAF of a number can only give an output with 1 more bit than
|
||||||
41
coins/monero/ringct/borromean/Cargo.toml
Normal file
41
coins/monero/ringct/borromean/Cargo.toml
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
[package]
|
||||||
|
name = "monero-borromean"
|
||||||
|
version = "0.1.0"
|
||||||
|
description = "Borromean ring signatures arranged into a range proof, as done by the Monero protocol"
|
||||||
|
license = "MIT"
|
||||||
|
repository = "https://github.com/serai-dex/serai/tree/develop/coins/monero/ringct/borromean"
|
||||||
|
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
||||||
|
edition = "2021"
|
||||||
|
rust-version = "1.79"
|
||||||
|
|
||||||
|
[package.metadata.docs.rs]
|
||||||
|
all-features = true
|
||||||
|
rustdoc-args = ["--cfg", "docsrs"]
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
std-shims = { path = "../../../../common/std-shims", version = "^0.1.1", default-features = false }
|
||||||
|
|
||||||
|
zeroize = { version = "^1.5", default-features = false, features = ["zeroize_derive"] }
|
||||||
|
|
||||||
|
# Cryptographic dependencies
|
||||||
|
curve25519-dalek = { version = "4", default-features = false, features = ["alloc", "zeroize"] }
|
||||||
|
|
||||||
|
# Other Monero dependencies
|
||||||
|
monero-io = { path = "../../io", version = "0.1", default-features = false }
|
||||||
|
monero-generators = { path = "../../generators", version = "0.4", default-features = false }
|
||||||
|
monero-primitives = { path = "../../primitives", version = "0.1", default-features = false }
|
||||||
|
|
||||||
|
[features]
|
||||||
|
std = [
|
||||||
|
"std-shims/std",
|
||||||
|
|
||||||
|
"zeroize/std",
|
||||||
|
|
||||||
|
"monero-io/std",
|
||||||
|
"monero-generators/std",
|
||||||
|
"monero-primitives/std",
|
||||||
|
]
|
||||||
|
default = ["std"]
|
||||||
21
coins/monero/ringct/borromean/LICENSE
Normal file
21
coins/monero/ringct/borromean/LICENSE
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2022-2024 Luke Parker
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
7
coins/monero/ringct/borromean/README.md
Normal file
7
coins/monero/ringct/borromean/README.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# Monero Borromean
|
||||||
|
|
||||||
|
Borromean ring signatures arranged into a range proof, as done by the Monero
|
||||||
|
protocol.
|
||||||
|
|
||||||
|
This library is usable under no-std when the `std` feature (on by default) is
|
||||||
|
disabled.
|
||||||
@@ -1,18 +1,26 @@
|
|||||||
|
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
||||||
|
#![doc = include_str!("../README.md")]
|
||||||
|
#![deny(missing_docs)]
|
||||||
|
#![cfg_attr(not(feature = "std"), no_std)]
|
||||||
|
#![allow(non_snake_case)]
|
||||||
|
|
||||||
use core::fmt::Debug;
|
use core::fmt::Debug;
|
||||||
use std_shims::io::{self, Read, Write};
|
use std_shims::io::{self, Read, Write};
|
||||||
|
|
||||||
|
use zeroize::Zeroize;
|
||||||
|
|
||||||
use curve25519_dalek::{traits::Identity, Scalar, EdwardsPoint};
|
use curve25519_dalek::{traits::Identity, Scalar, EdwardsPoint};
|
||||||
|
|
||||||
|
use monero_io::*;
|
||||||
use monero_generators::H_pow_2;
|
use monero_generators::H_pow_2;
|
||||||
|
use monero_primitives::{keccak256_to_scalar, UnreducedScalar};
|
||||||
|
|
||||||
use crate::{hash_to_scalar, unreduced_scalar::UnreducedScalar, serialize::*};
|
// 64 Borromean ring signatures, as needed for a 64-bit range proof.
|
||||||
|
//
|
||||||
/// 64 Borromean ring signatures, as needed for a 64-bit range proof.
|
// s0 and s1 are stored as `UnreducedScalar`s due to Monero not requiring they were reduced.
|
||||||
///
|
// `UnreducedScalar` preserves their original byte encoding and implements a custom reduction
|
||||||
/// s0 and s1 are stored as `UnreducedScalar`s due to Monero not requiring they were reduced.
|
// algorithm which was in use.
|
||||||
/// `UnreducedScalar` preserves their original byte encoding and implements a custom reduction
|
#[derive(Clone, PartialEq, Eq, Debug, Zeroize)]
|
||||||
/// algorithm which was in use.
|
|
||||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
|
||||||
struct BorromeanSignatures {
|
struct BorromeanSignatures {
|
||||||
s0: [UnreducedScalar; 64],
|
s0: [UnreducedScalar; 64],
|
||||||
s1: [UnreducedScalar; 64],
|
s1: [UnreducedScalar; 64],
|
||||||
@@ -20,7 +28,7 @@ struct BorromeanSignatures {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl BorromeanSignatures {
|
impl BorromeanSignatures {
|
||||||
/// Read a set of BorromeanSignatures from a reader.
|
// Read a set of BorromeanSignatures.
|
||||||
fn read<R: Read>(r: &mut R) -> io::Result<BorromeanSignatures> {
|
fn read<R: Read>(r: &mut R) -> io::Result<BorromeanSignatures> {
|
||||||
Ok(BorromeanSignatures {
|
Ok(BorromeanSignatures {
|
||||||
s0: read_array(UnreducedScalar::read, r)?,
|
s0: read_array(UnreducedScalar::read, r)?,
|
||||||
@@ -29,7 +37,7 @@ impl BorromeanSignatures {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Write the set of BorromeanSignatures to a writer.
|
// Write the set of BorromeanSignatures.
|
||||||
fn write<W: Write>(&self, w: &mut W) -> io::Result<()> {
|
fn write<W: Write>(&self, w: &mut W) -> io::Result<()> {
|
||||||
for s0 in &self.s0 {
|
for s0 in &self.s0 {
|
||||||
s0.write(w)?;
|
s0.write(w)?;
|
||||||
@@ -52,26 +60,26 @@ impl BorromeanSignatures {
|
|||||||
);
|
);
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
let LV = EdwardsPoint::vartime_double_scalar_mul_basepoint(
|
let LV = EdwardsPoint::vartime_double_scalar_mul_basepoint(
|
||||||
&hash_to_scalar(LL.compress().as_bytes()),
|
&keccak256_to_scalar(LL.compress().as_bytes()),
|
||||||
&keys_b[i],
|
&keys_b[i],
|
||||||
&self.s1[i].recover_monero_slide_scalar(),
|
&self.s1[i].recover_monero_slide_scalar(),
|
||||||
);
|
);
|
||||||
transcript[(i * 32) .. ((i + 1) * 32)].copy_from_slice(LV.compress().as_bytes());
|
transcript[(i * 32) .. ((i + 1) * 32)].copy_from_slice(LV.compress().as_bytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
hash_to_scalar(&transcript) == self.ee
|
keccak256_to_scalar(transcript) == self.ee
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A range proof premised on Borromean ring signatures.
|
/// A range proof premised on Borromean ring signatures.
|
||||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
#[derive(Clone, PartialEq, Eq, Debug, Zeroize)]
|
||||||
pub struct BorromeanRange {
|
pub struct BorromeanRange {
|
||||||
sigs: BorromeanSignatures,
|
sigs: BorromeanSignatures,
|
||||||
bit_commitments: [EdwardsPoint; 64],
|
bit_commitments: [EdwardsPoint; 64],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BorromeanRange {
|
impl BorromeanRange {
|
||||||
/// Read a BorromeanRange proof from a reader.
|
/// Read a BorromeanRange proof.
|
||||||
pub fn read<R: Read>(r: &mut R) -> io::Result<BorromeanRange> {
|
pub fn read<R: Read>(r: &mut R) -> io::Result<BorromeanRange> {
|
||||||
Ok(BorromeanRange {
|
Ok(BorromeanRange {
|
||||||
sigs: BorromeanSignatures::read(r)?,
|
sigs: BorromeanSignatures::read(r)?,
|
||||||
@@ -79,13 +87,14 @@ impl BorromeanRange {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Write the BorromeanRange proof to a reader.
|
/// Write the BorromeanRange proof.
|
||||||
pub fn write<W: Write>(&self, w: &mut W) -> io::Result<()> {
|
pub fn write<W: Write>(&self, w: &mut W) -> io::Result<()> {
|
||||||
self.sigs.write(w)?;
|
self.sigs.write(w)?;
|
||||||
write_raw_vec(write_point, &self.bit_commitments, w)
|
write_raw_vec(write_point, &self.bit_commitments, w)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Verify the commitment contains a 64-bit value.
|
/// Verify the commitment contains a 64-bit value.
|
||||||
|
#[must_use]
|
||||||
pub fn verify(&self, commitment: &EdwardsPoint) -> bool {
|
pub fn verify(&self, commitment: &EdwardsPoint) -> bool {
|
||||||
if &self.bit_commitments.iter().sum::<EdwardsPoint>() != commitment {
|
if &self.bit_commitments.iter().sum::<EdwardsPoint>() != commitment {
|
||||||
return false;
|
return false;
|
||||||
@@ -23,9 +23,6 @@ mod merkle;
|
|||||||
use monero_io as serialize;
|
use monero_io as serialize;
|
||||||
use serialize::{read_byte, read_u16};
|
use serialize::{read_byte, read_u16};
|
||||||
|
|
||||||
/// UnreducedScalar struct with functionality for recovering incorrectly reduced scalars.
|
|
||||||
mod unreduced_scalar;
|
|
||||||
|
|
||||||
/// Ring Signature structs and functionality.
|
/// Ring Signature structs and functionality.
|
||||||
pub mod ring_signatures;
|
pub mod ring_signatures;
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ pub use monero_mlsag as mlsag;
|
|||||||
/// CLSAG struct, along with signing and verifying functionality.
|
/// CLSAG struct, along with signing and verifying functionality.
|
||||||
pub use monero_clsag as clsag;
|
pub use monero_clsag as clsag;
|
||||||
/// BorromeanRange struct, along with verifying functionality.
|
/// BorromeanRange struct, along with verifying functionality.
|
||||||
pub mod borromean;
|
pub use monero_borromean as borromean;
|
||||||
/// Bulletproofs(+) structs, along with proving and verifying functionality.
|
/// Bulletproofs(+) structs, along with proving and verifying functionality.
|
||||||
pub use monero_bulletproofs as bulletproofs;
|
pub use monero_bulletproofs as bulletproofs;
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
mod unreduced_scalar;
|
|
||||||
mod address;
|
mod address;
|
||||||
mod seed;
|
mod seed;
|
||||||
mod extra;
|
mod extra;
|
||||||
|
|||||||
Reference in New Issue
Block a user