mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-11 21:49:26 +00:00
Smash out MLSAG
This commit is contained in:
17
Cargo.lock
generated
17
Cargo.lock
generated
@@ -4810,12 +4810,24 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "monero-primitives"
|
name = "monero-mlsag"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"curve25519-dalek",
|
"curve25519-dalek",
|
||||||
"monero-generators",
|
"monero-generators",
|
||||||
"monero-io",
|
"monero-io",
|
||||||
|
"monero-primitives",
|
||||||
|
"std-shims",
|
||||||
|
"thiserror",
|
||||||
|
"zeroize",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "monero-primitives"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"curve25519-dalek",
|
||||||
|
"monero-generators",
|
||||||
"sha3",
|
"sha3",
|
||||||
"std-shims",
|
"std-shims",
|
||||||
"zeroize",
|
"zeroize",
|
||||||
@@ -4839,8 +4851,8 @@ dependencies = [
|
|||||||
"monero-clsag",
|
"monero-clsag",
|
||||||
"monero-generators",
|
"monero-generators",
|
||||||
"monero-io",
|
"monero-io",
|
||||||
|
"monero-mlsag",
|
||||||
"monero-primitives",
|
"monero-primitives",
|
||||||
"multiexp",
|
|
||||||
"pbkdf2 0.12.2",
|
"pbkdf2 0.12.2",
|
||||||
"rand",
|
"rand",
|
||||||
"rand_chacha",
|
"rand_chacha",
|
||||||
@@ -8100,6 +8112,7 @@ dependencies = [
|
|||||||
"monero-clsag",
|
"monero-clsag",
|
||||||
"monero-generators",
|
"monero-generators",
|
||||||
"monero-io",
|
"monero-io",
|
||||||
|
"monero-mlsag",
|
||||||
"monero-primitives",
|
"monero-primitives",
|
||||||
"monero-serai",
|
"monero-serai",
|
||||||
"multiexp",
|
"multiexp",
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ members = [
|
|||||||
"coins/monero/io",
|
"coins/monero/io",
|
||||||
"coins/monero/generators",
|
"coins/monero/generators",
|
||||||
"coins/monero/primitives",
|
"coins/monero/primitives",
|
||||||
|
"coins/monero/ringct/mlsag",
|
||||||
"coins/monero/ringct/clsag",
|
"coins/monero/ringct/clsag",
|
||||||
"coins/monero/ringct/bulletproofs",
|
"coins/monero/ringct/bulletproofs",
|
||||||
"coins/monero",
|
"coins/monero",
|
||||||
|
|||||||
@@ -39,7 +39,6 @@ curve25519-dalek = { version = "4", default-features = false, features = ["alloc
|
|||||||
# Used for the hash to curve, along with the more complicated proofs
|
# Used for the hash to curve, along with the more complicated proofs
|
||||||
group = { version = "0.13", default-features = false }
|
group = { version = "0.13", default-features = false }
|
||||||
dalek-ff-group = { path = "../../crypto/dalek-ff-group", version = "0.4", default-features = false }
|
dalek-ff-group = { path = "../../crypto/dalek-ff-group", version = "0.4", default-features = false }
|
||||||
multiexp = { path = "../../crypto/multiexp", version = "0.4", default-features = false, features = ["batch"] }
|
|
||||||
|
|
||||||
# Needed for multisig
|
# Needed for multisig
|
||||||
transcript = { package = "flexible-transcript", path = "../../crypto/transcript", version = "0.3", default-features = false, features = ["recommended"], optional = true }
|
transcript = { package = "flexible-transcript", path = "../../crypto/transcript", version = "0.3", default-features = false, features = ["recommended"], optional = true }
|
||||||
@@ -48,6 +47,7 @@ frost = { package = "modular-frost", path = "../../crypto/frost", version = "0.8
|
|||||||
monero-io = { path = "io", version = "0.1", default-features = false }
|
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 }
|
||||||
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-clsag = { path = "ringct/clsag", version = "0.1", default-features = false }
|
monero-clsag = { path = "ringct/clsag", 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 }
|
||||||
|
|
||||||
@@ -89,13 +89,12 @@ std = [
|
|||||||
"sha3/std",
|
"sha3/std",
|
||||||
"pbkdf2/std",
|
"pbkdf2/std",
|
||||||
|
|
||||||
"multiexp/std",
|
|
||||||
|
|
||||||
"transcript/std",
|
"transcript/std",
|
||||||
|
|
||||||
"monero-io/std",
|
"monero-io/std",
|
||||||
"monero-generators/std",
|
"monero-generators/std",
|
||||||
"monero-primitives/std",
|
"monero-primitives/std",
|
||||||
|
"monero-mlsag/std",
|
||||||
"monero-clsag/std",
|
"monero-clsag/std",
|
||||||
"monero-bulletproofs/std",
|
"monero-bulletproofs/std",
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ 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 }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
|
|||||||
45
coins/monero/ringct/mlsag/Cargo.toml
Normal file
45
coins/monero/ringct/mlsag/Cargo.toml
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
[package]
|
||||||
|
name = "monero-mlsag"
|
||||||
|
version = "0.1.0"
|
||||||
|
description = "The MLSAG linkable ring signature, as defined by the Monero protocol"
|
||||||
|
license = "MIT"
|
||||||
|
repository = "https://github.com/serai-dex/serai/tree/develop/coins/monero/ringct/mlsag"
|
||||||
|
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 }
|
||||||
|
|
||||||
|
thiserror = { version = "1", default-features = false, optional = true }
|
||||||
|
|
||||||
|
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",
|
||||||
|
|
||||||
|
"thiserror",
|
||||||
|
|
||||||
|
"zeroize/std",
|
||||||
|
|
||||||
|
"monero-io/std",
|
||||||
|
"monero-generators/std",
|
||||||
|
"monero-primitives/std",
|
||||||
|
]
|
||||||
|
default = ["std"]
|
||||||
21
coins/monero/ringct/mlsag/LICENSE
Normal file
21
coins/monero/ringct/mlsag/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.
|
||||||
6
coins/monero/ringct/mlsag/README.md
Normal file
6
coins/monero/ringct/mlsag/README.md
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
# Monero MLSAG
|
||||||
|
|
||||||
|
The MLSAG linkable ring signature, as defined by the Monero protocol.
|
||||||
|
|
||||||
|
This library is usable under no-std when the `std` feature (on by default) is
|
||||||
|
disabled.
|
||||||
@@ -1,3 +1,9 @@
|
|||||||
|
#![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 std_shims::{
|
use std_shims::{
|
||||||
vec::Vec,
|
vec::Vec,
|
||||||
io::{self, Read, Write},
|
io::{self, Read, Write},
|
||||||
@@ -7,9 +13,9 @@ use zeroize::Zeroize;
|
|||||||
|
|
||||||
use curve25519_dalek::{traits::IsIdentity, Scalar, EdwardsPoint};
|
use curve25519_dalek::{traits::IsIdentity, Scalar, EdwardsPoint};
|
||||||
|
|
||||||
use monero_generators::H;
|
use monero_io::*;
|
||||||
|
use monero_generators::{H, hash_to_point};
|
||||||
use crate::{hash_to_scalar, ringct::hash_to_point, serialize::*};
|
use monero_primitives::keccak256_to_scalar;
|
||||||
|
|
||||||
/// Errors when working with MLSAGs.
|
/// Errors when working with MLSAGs.
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||||
@@ -68,17 +74,17 @@ impl RingMatrix {
|
|||||||
RingMatrix::new(matrix)
|
RingMatrix::new(matrix)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Iterate the members of the matrix.
|
/// Iterate over the members of the matrix.
|
||||||
fn iter(&self) -> impl Iterator<Item = &[EdwardsPoint]> {
|
fn iter(&self) -> impl Iterator<Item = &[EdwardsPoint]> {
|
||||||
self.matrix.iter().map(AsRef::as_ref)
|
self.matrix.iter().map(AsRef::as_ref)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the amount of members in the ring.
|
/// Get the amount of members in the ring.
|
||||||
pub fn members(&self) -> usize {
|
pub fn members(&self) -> usize {
|
||||||
self.matrix.len()
|
self.matrix.len()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the length of a ring member.
|
/// Get the length of a ring member.
|
||||||
///
|
///
|
||||||
/// A ring member is a vector of points for which the signer knows all of the discrete logarithms
|
/// A ring member is a vector of points for which the signer knows all of the discrete logarithms
|
||||||
/// of.
|
/// of.
|
||||||
@@ -96,7 +102,7 @@ pub struct Mlsag {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Mlsag {
|
impl Mlsag {
|
||||||
/// Write the MLSAG to a writer.
|
/// Write a MLSAG.
|
||||||
pub fn write<W: Write>(&self, w: &mut W) -> io::Result<()> {
|
pub fn write<W: Write>(&self, w: &mut W) -> io::Result<()> {
|
||||||
for ss in &self.ss {
|
for ss in &self.ss {
|
||||||
write_raw_vec(write_scalar, ss, w)?;
|
write_raw_vec(write_scalar, ss, w)?;
|
||||||
@@ -104,7 +110,7 @@ impl Mlsag {
|
|||||||
write_scalar(&self.cc, w)
|
write_scalar(&self.cc, w)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Read the MLSAG from a reader.
|
/// Read a MLSAG.
|
||||||
pub fn read<R: Read>(mixins: usize, ss_2_elements: usize, r: &mut R) -> io::Result<Mlsag> {
|
pub fn read<R: Read>(mixins: usize, ss_2_elements: usize, r: &mut R) -> io::Result<Mlsag> {
|
||||||
Ok(Mlsag {
|
Ok(Mlsag {
|
||||||
ss: (0 .. mixins)
|
ss: (0 .. mixins)
|
||||||
@@ -114,7 +120,7 @@ impl Mlsag {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Verify the MLSAG.
|
/// Verify a MLSAG.
|
||||||
pub fn verify(
|
pub fn verify(
|
||||||
&self,
|
&self,
|
||||||
msg: &[u8; 32],
|
msg: &[u8; 32],
|
||||||
@@ -149,7 +155,8 @@ impl Mlsag {
|
|||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
let L = EdwardsPoint::vartime_double_scalar_mul_basepoint(&ci, ring_member_entry, s);
|
let L = EdwardsPoint::vartime_double_scalar_mul_basepoint(&ci, ring_member_entry, s);
|
||||||
|
|
||||||
buf.extend_from_slice(ring_member_entry.compress().as_bytes());
|
let compressed_ring_member_entry = ring_member_entry.compress();
|
||||||
|
buf.extend_from_slice(compressed_ring_member_entry.as_bytes());
|
||||||
buf.extend_from_slice(L.compress().as_bytes());
|
buf.extend_from_slice(L.compress().as_bytes());
|
||||||
|
|
||||||
// Not all dimensions need to be linkable, e.g. commitments, and only linkable layers need
|
// Not all dimensions need to be linkable, e.g. commitments, and only linkable layers need
|
||||||
@@ -160,12 +167,12 @@ impl Mlsag {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
let R = (s * hash_to_point(ring_member_entry)) + (ci * ki);
|
let R = (s * hash_to_point(compressed_ring_member_entry.to_bytes())) + (ci * ki);
|
||||||
buf.extend_from_slice(R.compress().as_bytes());
|
buf.extend_from_slice(R.compress().as_bytes());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ci = hash_to_scalar(&buf);
|
ci = keccak256_to_scalar(&buf);
|
||||||
// keep the msg in the buffer.
|
// keep the msg in the buffer.
|
||||||
buf.drain(msg.len() ..);
|
buf.drain(msg.len() ..);
|
||||||
}
|
}
|
||||||
@@ -190,7 +197,7 @@ pub struct AggregateRingMatrixBuilder {
|
|||||||
impl AggregateRingMatrixBuilder {
|
impl AggregateRingMatrixBuilder {
|
||||||
/// Create a new AggregateRingMatrixBuilder.
|
/// Create a new AggregateRingMatrixBuilder.
|
||||||
///
|
///
|
||||||
/// Takes in the transaction's outputs; commitments and fee.
|
/// This takes in the transaction's outputs' commitments and fee used.
|
||||||
pub fn new(commitments: &[EdwardsPoint], fee: u64) -> Self {
|
pub fn new(commitments: &[EdwardsPoint], fee: u64) -> Self {
|
||||||
AggregateRingMatrixBuilder {
|
AggregateRingMatrixBuilder {
|
||||||
key_ring: vec![],
|
key_ring: vec![],
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ pub(crate) mod hash_to_point;
|
|||||||
pub use hash_to_point::{raw_hash_to_point, hash_to_point};
|
pub use hash_to_point::{raw_hash_to_point, hash_to_point};
|
||||||
|
|
||||||
/// MLSAG struct, along with verifying functionality.
|
/// MLSAG struct, along with verifying functionality.
|
||||||
pub mod mlsag;
|
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.
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ bitcoin-serai = { path = "../../coins/bitcoin", default-features = false, featur
|
|||||||
monero-io = { path = "../../coins/monero/io", default-features = false }
|
monero-io = { path = "../../coins/monero/io", default-features = false }
|
||||||
monero-generators = { path = "../../coins/monero/generators", default-features = false }
|
monero-generators = { path = "../../coins/monero/generators", default-features = false }
|
||||||
monero-primitives = { path = "../../coins/monero/primitives", default-features = false }
|
monero-primitives = { path = "../../coins/monero/primitives", default-features = false }
|
||||||
|
monero-mlsag = { path = "../../coins/monero/ringct/mlsag", default-features = false }
|
||||||
monero-clsag = { path = "../../coins/monero/ringct/clsag", default-features = false }
|
monero-clsag = { path = "../../coins/monero/ringct/clsag", default-features = false }
|
||||||
monero-bulletproofs = { path = "../../coins/monero/ringct/bulletproofs", default-features = false }
|
monero-bulletproofs = { path = "../../coins/monero/ringct/bulletproofs", default-features = false }
|
||||||
monero-serai = { path = "../../coins/monero", default-features = false }
|
monero-serai = { path = "../../coins/monero", default-features = false }
|
||||||
|
|||||||
@@ -20,5 +20,10 @@ pub use frost_schnorrkel;
|
|||||||
|
|
||||||
pub use bitcoin_serai;
|
pub use bitcoin_serai;
|
||||||
|
|
||||||
|
pub use monero_io;
|
||||||
pub use monero_generators;
|
pub use monero_generators;
|
||||||
|
pub use monero_primitives;
|
||||||
|
pub use monero_mlsag;
|
||||||
|
pub use monero_clsag;
|
||||||
|
pub use monero_bulletproofs;
|
||||||
pub use monero_serai;
|
pub use monero_serai;
|
||||||
|
|||||||
Reference in New Issue
Block a user