From 02750193f3f2c056d63069377a01cf2f7704dec0 Mon Sep 17 00:00:00 2001 From: Boog900 <54e72d8a-345f-4599-bd90-c6b9bc7d0ec5@aleeas.com> Date: Mon, 26 Jun 2023 00:22:12 +0100 Subject: [PATCH] Add MgSig proving --- coins/monero/src/ringct/mlsag/mod.rs | 52 +++++++++++++++++++++++++++- coins/monero/src/ringct/mod.rs | 13 ++++--- 2 files changed, 59 insertions(+), 6 deletions(-) diff --git a/coins/monero/src/ringct/mlsag/mod.rs b/coins/monero/src/ringct/mlsag/mod.rs index d7c2f1de..172770aa 100644 --- a/coins/monero/src/ringct/mlsag/mod.rs +++ b/coins/monero/src/ringct/mlsag/mod.rs @@ -5,6 +5,7 @@ use std::io::{Read, Write}; use curve25519_dalek::scalar::Scalar; use curve25519_dalek::edwards::EdwardsPoint; +use curve25519_dalek::traits::Identity; use crate::{hash_to_scalar, serialize::*}; use crate::ringct::hash_to_point; @@ -31,7 +32,56 @@ impl MgSig { }) } - pub fn verify(&self, msg: &[u8; 32], ring: &[[EdwardsPoint; 2]], I: &EdwardsPoint) -> bool { + pub fn verify_rct_full( + &self, + msg: &[u8; 32], + pubs: &[[EdwardsPoint; 2]], + out_pks: &[EdwardsPoint], + fee: &EdwardsPoint, + I: &EdwardsPoint, + ) -> bool { + if pubs.is_empty() { + return false; + } + + let sum_out_pk = { + let mut sum = EdwardsPoint::identity(); + for out_pk in out_pks { + sum += out_pk; + } + sum + }; + + let mut ring_matrix = Vec::with_capacity(pubs.len()); + + for member in pubs.iter() { + ring_matrix.push([member[0], member[1] - sum_out_pk - fee]) + } + + self.verify_mlsag(msg, &ring_matrix, I) + } + + pub fn verify_rct_simple( + &self, + msg: &[u8; 32], + pubs: &[[EdwardsPoint; 2]], + pseudo_out: &EdwardsPoint, + I: &EdwardsPoint, + ) -> bool { + if pubs.is_empty() { + return false; + } + + let mut ring_matrix = Vec::with_capacity(pubs.len()); + + for member in pubs.iter() { + ring_matrix.push([member[0], member[1] - pseudo_out]) + } + + self.verify_mlsag(msg, &ring_matrix, I) + } + + fn verify_mlsag(&self, msg: &[u8; 32], ring: &[[EdwardsPoint; 2]], I: &EdwardsPoint) -> bool { let mut buf = Vec::with_capacity(32 * 6); let mut ci = self.cc; diff --git a/coins/monero/src/ringct/mod.rs b/coins/monero/src/ringct/mod.rs index cf57692f..48d9e9a8 100644 --- a/coins/monero/src/ringct/mod.rs +++ b/coins/monero/src/ringct/mod.rs @@ -108,12 +108,12 @@ pub enum RctPrunable { Null, Borromean { range_sigs: Vec, - mlsags: Vec, + mlsags: Vec, simple: bool, }, BulletProof { bulletproofs: Vec, - mlsags: Vec, + mlsags: Vec, pseudo_outs: Vec, v2: bool, }, @@ -163,7 +163,7 @@ impl RctPrunable { RctPrunable::Null => Ok(()), RctPrunable::Borromean { range_sigs, mlsags, simple: _ } => { write_raw_vec(RangeSig::write, range_sigs, w)?; - write_raw_vec(Mlsag::write, mlsags, w) + write_raw_vec(MgSig::write, mlsags, w) } RctPrunable::BulletProof { bulletproofs, mlsags, pseudo_outs, v2 } => { if !v2 { @@ -172,7 +172,7 @@ impl RctPrunable { write_varint(&bulletproofs.len().try_into().unwrap(), w)?; } write_raw_vec(Bulletproofs::write, bulletproofs, w)?; - write_raw_vec(Mlsag::write, mlsags, w)?; + write_raw_vec(MgSig::write, mlsags, w)?; write_raw_vec(write_point, pseudo_outs, w) } RctPrunable::Clsag { bulletproofs, clsags, pseudo_outs } => { @@ -234,7 +234,10 @@ impl RctPrunable { RctPrunable::Clsag { bulletproofs, .. } => { bulletproofs.iter().try_for_each(|bp| bp.signature_write(w)) } - _ => todo!(), + RctPrunable::BulletProof { bulletproofs, .. } => { + bulletproofs.iter().try_for_each(|bp| bp.signature_write(w)) + } + RctPrunable::Borromean { range_sigs, .. } => range_sigs.iter().try_for_each(|rs| rs.write(w)), } } }