mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-12 05:59:23 +00:00
Smash out MLSAG
This commit is contained in:
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::{
|
||||
vec::Vec,
|
||||
io::{self, Read, Write},
|
||||
@@ -7,9 +13,9 @@ use zeroize::Zeroize;
|
||||
|
||||
use curve25519_dalek::{traits::IsIdentity, Scalar, EdwardsPoint};
|
||||
|
||||
use monero_generators::H;
|
||||
|
||||
use crate::{hash_to_scalar, ringct::hash_to_point, serialize::*};
|
||||
use monero_io::*;
|
||||
use monero_generators::{H, hash_to_point};
|
||||
use monero_primitives::keccak256_to_scalar;
|
||||
|
||||
/// Errors when working with MLSAGs.
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||
@@ -68,17 +74,17 @@ impl RingMatrix {
|
||||
RingMatrix::new(matrix)
|
||||
}
|
||||
|
||||
/// Iterate the members of the matrix.
|
||||
/// Iterate over the members of the matrix.
|
||||
fn iter(&self) -> impl Iterator<Item = &[EdwardsPoint]> {
|
||||
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 {
|
||||
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
|
||||
/// of.
|
||||
@@ -96,7 +102,7 @@ pub struct Mlsag {
|
||||
}
|
||||
|
||||
impl Mlsag {
|
||||
/// Write the MLSAG to a writer.
|
||||
/// Write a MLSAG.
|
||||
pub fn write<W: Write>(&self, w: &mut W) -> io::Result<()> {
|
||||
for ss in &self.ss {
|
||||
write_raw_vec(write_scalar, ss, w)?;
|
||||
@@ -104,7 +110,7 @@ impl Mlsag {
|
||||
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> {
|
||||
Ok(Mlsag {
|
||||
ss: (0 .. mixins)
|
||||
@@ -114,7 +120,7 @@ impl Mlsag {
|
||||
})
|
||||
}
|
||||
|
||||
/// Verify the MLSAG.
|
||||
/// Verify a MLSAG.
|
||||
pub fn verify(
|
||||
&self,
|
||||
msg: &[u8; 32],
|
||||
@@ -149,7 +155,8 @@ impl Mlsag {
|
||||
#[allow(non_snake_case)]
|
||||
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());
|
||||
|
||||
// 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)]
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
ci = hash_to_scalar(&buf);
|
||||
ci = keccak256_to_scalar(&buf);
|
||||
// keep the msg in the buffer.
|
||||
buf.drain(msg.len() ..);
|
||||
}
|
||||
@@ -190,7 +197,7 @@ pub struct AggregateRingMatrixBuilder {
|
||||
impl 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 {
|
||||
AggregateRingMatrixBuilder {
|
||||
key_ring: vec![],
|
||||
|
||||
Reference in New Issue
Block a user