Merge branch 'master' into contracts

Bring the contracts feature branch up to current master, which has since
landed rust 1.80 support (#722), the canonical mwixnet onion code (#726),
and node-client proxy support (#738).

Conflict resolution:
- libwallet/src/mwixnet/*: take master's (#726), dropping the contracts
  branch's older divergent copy. owner.rs::create_mwixnet_req updated to
  master's API (use_test_rng) and master's flat re-export imports.
- Cargo manifests/lock/.cargo: master's deps & version; re-add serde_with
  for Slate v5; keep contracts' .cargo/config.toml (Windows static-CRT).
- lib.rs: keep serde_derive AND serde_with macro_use; single mwixnet decl.
- error.rs: union of master + contracts variants; flat mwixnet re-exports.
- api/libwallet owner.rs: master's #738 + create_mwixnet_req plus the
  contract_* entry points; drop duplicate older create_mwixnet_req method.
- slatepack/armor.rs, node_clients/resp_types.rs: take master's.

Workspace builds; libwallet lib tests pass (34/34). The Slate version()
bug, issue #729 fix, and de-panicking follow in subsequent commits.
This commit is contained in:
jwinterm
2026-06-02 18:26:08 -04:00
30 changed files with 1152 additions and 675 deletions
+20 -9
View File
@@ -24,23 +24,22 @@ use crate::grin_core::libtx::proof;
use crate::grin_keychain::ViewKey;
use crate::grin_util::secp::key::SecretKey;
use crate::grin_util::secp::pedersen;
use crate::grin_util::secp::pedersen::Commitment;
use crate::grin_util::{static_secp_instance, Mutex, ToHex};
use crate::util::{OnionV3Address, OnionV3AddressError};
use crate::api_impl::owner_updater::StatusMessage;
use crate::contract::types::{ContractNewArgsAPI, ContractRevokeArgsAPI, ContractSetupArgsAPI};
use crate::grin_keychain::{BlindingFactor, Identifier, Keychain, SwitchCommitmentType};
use crate::mwixnet::onion::create_onion;
use crate::mwixnet::types::{
add_excess, new_hop, random_secret, ComSignature, Hop, MixnetReqCreationParams, SwapReq,
};
use crate::internal::{keys, scan, selection, tx, updater};
use crate::slate::{PaymentInfo, Slate, SlateState};
use crate::types::{AcctPathMapping, NodeClient, TxLogEntry, WalletBackend, WalletInfo};
use crate::Error;
use crate::{
address, contract, wallet_lock, BuiltOutput, InitTxArgs, IssueInvoiceTxArgs, NodeHeightResult,
address, contract,
mwixnet::{create_onion, ComSignature, Hop, MixnetReqCreationParams, SwapReq},
wallet_lock, BuiltOutput, InitTxArgs, IssueInvoiceTxArgs, NodeHeightResult,
OutputCommitMapping, PaymentProof, RetrieveTxQueryArgs, ScannedBlockInfo, Slatepack,
SlatepackAddress, Slatepacker, SlatepackerArgs, TxLogEntryType, ViewWallet, WalletInitStatus,
WalletInst, WalletLCProvider,
@@ -1609,8 +1608,9 @@ pub fn create_mwixnet_req<'a, T: ?Sized, C, K>(
w: &mut T,
keychain_mask: Option<&SecretKey>,
params: &MixnetReqCreationParams,
commitment: &pedersen::Commitment,
commitment: &Commitment,
lock_output: bool,
use_test_rng: bool,
) -> Result<SwapReq, Error>
where
T: WalletBackend<'a, C, K>,
@@ -1668,7 +1668,12 @@ where
rangeproof: Some(new_output.output.proof.clone()),
}
} else {
let hop_excess = BlindingFactor::rand(&secp);
let hop_excess;
if use_test_rng {
hop_excess = BlindingFactor::zero();
} else {
hop_excess = BlindingFactor::rand(&secp);
}
blind_sum = blind_sum.split(&hop_excess, &secp).unwrap();
Hop {
server_pubkey: p.clone(),
@@ -1680,8 +1685,14 @@ where
})
.collect();
let onion = create_onion(&commitment, &hops).unwrap();
let comsig = ComSignature::sign(amount, &input_blind, &onion.serialize().unwrap()).unwrap();
let onion = create_onion(&commitment, &hops, use_test_rng).unwrap();
let comsig = ComSignature::sign(
amount,
&input_blind,
&onion.serialize().unwrap(),
use_test_rng,
)
.unwrap();
// Lock output if requested
if lock_output {
+2
View File
@@ -26,6 +26,8 @@ use crate::SlatepackAddress;
use chrono::prelude::*;
use ed25519_dalek::Signature as DalekSignature;
pub use crate::mwixnet::{Hop, MixnetReqCreationParams, SwapReq};
/// Type for storing amounts (in nanogrins).
/// Serializes as a string but can deserialize from a string or u64.
#[derive(Serialize, Deserialize)]
+14 -2
View File
@@ -67,11 +67,11 @@ pub enum Error {
/// Comsig error
#[error("Comsig error: {0}")]
ComSig(#[from] crate::mwixnet::onion::crypto::comsig::ComSigError),
ComSig(#[from] crate::mwixnet::ComSigError),
/// mwixnet Onion error
#[error("Onion error: {0}")]
Onion(#[from] crate::mwixnet::onion::onion::OnionError),
Onion(#[from] crate::mwixnet::OnionError),
/// Callback implementation error conversion
#[error("Trait Implementation error")]
@@ -189,6 +189,18 @@ pub enum Error {
#[error("Committed Error: {0}")]
Commit(String),
/// Error Deserializing commit
#[error("Commit Deserialize Error: {0}")]
CommitDeser(String),
/// Error Deserializing key
#[error("Server Key Deserialize Error: {0}")]
ServerKeyDeser(String),
/// Parsing integert
#[error("Can't parse as u64: {0}")]
U64Deser(String),
/// Can't parse slate version
#[error("Can't parse slate version")]
SlateVersionParse,
+3 -2
View File
@@ -32,6 +32,8 @@ use grin_wallet_util as util;
use blake2_rfc as blake2;
#[macro_use]
extern crate serde_derive;
#[macro_use]
extern crate serde_with;
#[macro_use]
@@ -48,11 +50,10 @@ pub mod api_impl;
pub mod contract;
mod error;
mod internal;
pub mod mwixnet;
mod slate;
pub mod slate_versions;
pub mod slatepack;
pub mod mwixnet;
mod types;
pub use crate::error::Error;
+9 -2
View File
@@ -13,5 +13,12 @@
// limitations under the License.
//! Onion modules for mxmixnet
pub mod onion;
pub mod types;
mod onion;
mod types;
pub use onion::{
create_onion, onion::Onion, onion::OnionError, util as onion_util, ComSigError, ComSignature,
MwixnetPublicKey,
};
pub use types::{Hop, MixnetReqCreationParams, SwapReq};
+41 -16
View File
@@ -14,12 +14,14 @@
//! Comsig modules for mxmixnet
use secp256k1zkp::{self, pedersen::Commitment, ContextFlag, Secp256k1, SecretKey};
use grin_util::secp::{
self as secp256k1zkp, pedersen::Commitment, rand::thread_rng, ContextFlag, Secp256k1, SecretKey,
};
use blake2_rfc::blake2b::Blake2b;
use byteorder::{BigEndian, ByteOrder};
use grin_core::ser::{self, Readable, Reader, Writeable, Writer};
use secp256k1zkp::rand::thread_rng;
use rand::rngs::mock::StepRng;
use thiserror::Error;
/// A generalized Schnorr signature with a pedersen commitment value & blinding factors as the keys
@@ -33,8 +35,10 @@ pub struct ComSignature {
/// Error types for Commitment Signatures
#[derive(Error, Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
pub enum ComSigError {
/// Invalid commitment signature
#[error("Commitment signature is invalid")]
InvalidSig,
/// Secp256k1zkp error
#[error("Secp256k1zkp error: {0:?}")]
Secp256k1zkp(secp256k1zkp::Error),
}
@@ -46,6 +50,7 @@ impl From<secp256k1zkp::Error> for ComSigError {
}
impl ComSignature {
/// Create a new ComSignature
pub fn new(pub_nonce: &Commitment, s: &SecretKey, t: &SecretKey) -> ComSignature {
ComSignature {
pub_nonce: pub_nonce.to_owned(),
@@ -54,25 +59,41 @@ impl ComSignature {
}
}
#[allow(dead_code)]
/// Sign commitment with amount, blinding factor, and message
pub fn sign(
amount: u64,
blind: &SecretKey,
msg: &Vec<u8>,
use_test_rng: bool,
) -> Result<ComSignature, ComSigError> {
let secp = Secp256k1::with_caps(ContextFlag::Commit);
let mut amt_bytes = [0; 32];
BigEndian::write_u64(&mut amt_bytes[24..32], amount);
let k_amt = SecretKey::from_slice(&secp, &amt_bytes)?;
let k_1;
let k_2;
let k_1 = SecretKey::new(&secp, &mut thread_rng());
let k_2 = SecretKey::new(&secp, &mut thread_rng());
if use_test_rng {
// allow for consistent test results
let mut test_rng = StepRng::new(1_234_567_890_u64, 1);
k_1 = SecretKey::new(&secp, &mut test_rng);
k_2 = SecretKey::new(&secp, &mut test_rng);
} else {
k_1 = SecretKey::new(&secp, &mut thread_rng());
k_2 = SecretKey::new(&secp, &mut thread_rng());
}
let commitment = secp.commit(amount, blind.clone())?;
let nonce_commitment = secp.commit_blind(k_1.clone(), k_2.clone())?;
let e = ComSignature::calc_challenge(&secp, &commitment, &nonce_commitment, &msg)?;
let e = ComSignature::calc_challenge(
&secp,
&commitment,
&nonce_commitment,
&msg,
use_test_rng,
)?;
// s = k_1 + (e * amount)
let mut s = k_amt.clone();
@@ -87,20 +108,20 @@ impl ComSignature {
Ok(ComSignature::new(&nonce_commitment, &s, &t))
}
#[allow(non_snake_case)]
/// Verify the commitment signature
pub fn verify(&self, commit: &Commitment, msg: &Vec<u8>) -> Result<(), ComSigError> {
let secp = Secp256k1::with_caps(ContextFlag::Commit);
let S1 = secp.commit_blind(self.s.clone(), self.t.clone())?;
let s1 = secp.commit_blind(self.s.clone(), self.t.clone())?;
let mut Ce = commit.to_pubkey(&secp)?;
let e = ComSignature::calc_challenge(&secp, &commit, &self.pub_nonce, &msg)?;
Ce.mul_assign(&secp, &e)?;
let mut ce = commit.to_pubkey(&secp)?;
let e = ComSignature::calc_challenge(&secp, &commit, &self.pub_nonce, &msg, false)?;
ce.mul_assign(&secp, &e)?;
let commits = vec![Commitment::from_pubkey(&secp, &Ce)?, self.pub_nonce.clone()];
let S2 = secp.commit_sum(commits, Vec::new())?;
let commits = vec![Commitment::from_pubkey(&secp, &ce)?, self.pub_nonce.clone()];
let s2 = secp.commit_sum(commits, Vec::new())?;
if S1 != S2 {
if s1 != s2 {
return Err(ComSigError::InvalidSig);
}
@@ -112,8 +133,12 @@ impl ComSignature {
commit: &Commitment,
nonce_commit: &Commitment,
msg: &Vec<u8>,
use_test_rng: bool,
) -> Result<SecretKey, ComSigError> {
let mut challenge_hasher = Blake2b::new(32);
if use_test_rng {
return Ok(super::secp::random_secret(use_test_rng));
}
challenge_hasher.update(&commit.0);
challenge_hasher.update(&nonce_commit.0);
challenge_hasher.update(msg);
@@ -178,8 +203,8 @@ impl Writeable for ComSignature {
mod tests {
use super::{ComSigError, ComSignature, ContextFlag, Secp256k1, SecretKey};
use grin_util::secp::rand::{thread_rng, RngCore};
use rand::Rng;
use secp256k1zkp::rand::{thread_rng, RngCore};
/// Test signing and verification of ComSignatures
#[test]
@@ -189,7 +214,7 @@ mod tests {
let amount = thread_rng().next_u64();
let blind = SecretKey::new(&secp, &mut thread_rng());
let msg: [u8; 16] = rand::thread_rng().gen();
let comsig = ComSignature::sign(amount, &blind, &msg.to_vec())?;
let comsig = ComSignature::sign(amount, &blind, &msg.to_vec(), false)?;
let commit = secp.commit(amount, blind.clone())?;
assert!(comsig.verify(&commit, &msg.to_vec()).is_ok());
+6 -2
View File
@@ -14,9 +14,9 @@
//! Dalek key wrapper for mwixnet primitives
use super::secp::SecretKey;
use grin_util::secp::key::SecretKey;
use ed25519_dalek::{Keypair, PublicKey, Signature, Signer, Verifier};
use ed25519_dalek::{PublicKey, Signature, Verifier};
use grin_core::ser::{self, Readable, Reader, Writeable, Writer};
use grin_util::ToHex;
use thiserror::Error;
@@ -68,6 +68,7 @@ impl AsRef<PublicKey> for DalekPublicKey {
}
}
#[cfg(test)]
/// Serializes an Option<DalekPublicKey> to and from hex
pub mod option_dalek_pubkey_serde {
use super::DalekPublicKey;
@@ -144,6 +145,7 @@ impl AsRef<Signature> for DalekSignature {
}
/// Serializes a DalekSignature to and from hex
#[cfg(test)]
pub mod dalek_sig_serde {
use super::DalekSignature;
use grin_util::ToHex;
@@ -171,7 +173,9 @@ pub mod dalek_sig_serde {
/// Dalek signature sign wrapper
// TODO: This is likely duplicated throughout crate, check
#[cfg(test)]
pub fn sign(sk: &SecretKey, message: &[u8]) -> Result<DalekSignature, DalekError> {
use ed25519_dalek::{Keypair, Signer};
let secret =
ed25519_dalek::SecretKey::from_bytes(&sk.0).map_err(|_| DalekError::KeyParseError)?;
let public: PublicKey = (&secret).into();
+3 -1
View File
@@ -1,4 +1,4 @@
// Copyright 2023 The Grin Developers
// Copyright 2024 The Grin Developers
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -17,3 +17,5 @@
pub mod comsig;
pub mod dalek;
pub mod secp;
pub use comsig::{comsig_serde, ComSigError, ComSignature};
+36 -17
View File
@@ -1,4 +1,4 @@
// Copyright 2023 The Grin Developers
// Copyright 2024 The Grin Developers
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -12,26 +12,30 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//! SECP wrapper functions for onion/comsig
//! TODO: Likely redundant stuff in here, trim
//! SECP operations for comsig
pub use secp256k1zkp::aggsig;
pub use secp256k1zkp::constants::{
AGG_SIGNATURE_SIZE, COMPRESSED_PUBLIC_KEY_SIZE, MAX_PROOF_SIZE, PEDERSEN_COMMITMENT_SIZE,
SECRET_KEY_SIZE,
pub use grin_util::secp::{
self as secp256k1zkp,
constants::SECRET_KEY_SIZE,
key::{SecretKey, ZERO_KEY},
pedersen::Commitment,
rand::thread_rng,
ContextFlag, Secp256k1,
};
pub use secp256k1zkp::ecdh::SharedSecret;
pub use secp256k1zkp::key::{PublicKey, SecretKey, ZERO_KEY};
pub use secp256k1zkp::pedersen::{Commitment, RangeProof};
pub use secp256k1zkp::{ContextFlag, Message, Secp256k1, Signature};
use grin_core::ser::{self, Reader};
use secp256k1zkp::rand::thread_rng;
use rand::rngs::mock::StepRng;
/// Generate a random SecretKey.
pub fn random_secret() -> SecretKey {
pub fn random_secret(use_test_rng: bool) -> SecretKey {
let secp = Secp256k1::new();
SecretKey::new(&secp, &mut thread_rng())
if use_test_rng {
// allow for consistent test results
let mut test_rng = StepRng::new(1_234_567_890_u64, 1);
SecretKey::new(&secp, &mut test_rng)
} else {
SecretKey::new(&secp, &mut thread_rng())
}
}
/// Deserialize a SecretKey from a Reader
@@ -43,6 +47,7 @@ pub fn read_secret_key<R: Reader>(reader: &mut R) -> Result<SecretKey, ser::Erro
}
/// Build a Pedersen Commitment using the provided value and blinding factor
#[cfg(test)]
pub fn commit(value: u64, blind: &SecretKey) -> Result<Commitment, secp256k1zkp::Error> {
let secp = Secp256k1::with_caps(ContextFlag::Commit);
let commit = secp.commit(value, blind.clone())?;
@@ -71,9 +76,23 @@ pub fn sub_value(commitment: &Commitment, value: u64) -> Result<Commitment, secp
}
/// Signs the message with the provided SecretKey
pub fn sign(sk: &SecretKey, msg: &Message) -> Result<Signature, secp256k1zkp::Error> {
#[cfg(test)]
#[allow(dead_code)]
pub fn sign(
sk: &SecretKey,
msg: &grin_util::secp::Message,
) -> Result<grin_util::secp::Signature, secp256k1zkp::Error> {
let secp = Secp256k1::with_caps(ContextFlag::Full);
let pubkey = PublicKey::from_secret_key(&secp, &sk)?;
let sig = aggsig::sign_single(&secp, &msg, &sk, None, None, None, Some(&pubkey), None)?;
let pubkey = grin_util::secp::PublicKey::from_secret_key(&secp, &sk)?;
let sig = grin_util::secp::aggsig::sign_single(
&secp,
&msg,
&sk,
None,
None,
None,
Some(&pubkey),
None,
)?;
Ok(sig)
}
+34 -21
View File
@@ -1,4 +1,4 @@
// Copyright 2023 The Grin Developers
// Copyright 2024 The Grin Developers
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -14,19 +14,26 @@
//! Onion module definition
pub mod crypto;
mod crypto;
pub mod onion;
pub mod util;
use crypto::secp::{random_secret, Commitment, SecretKey};
use onion::{new_stream_cipher, Onion, OnionError, Payload, RawBytes};
pub use crypto::{
comsig_serde, dalek::DalekPublicKey as MwixnetPublicKey, ComSigError, ComSignature,
};
use chacha20::cipher::StreamCipher;
use grin_core::core::FeeFields;
use secp256k1zkp::pedersen::RangeProof;
use grin_util::secp::{
pedersen::{Commitment, RangeProof},
SecretKey,
};
use x25519_dalek::PublicKey as xPublicKey;
use x25519_dalek::{SharedSecret, StaticSecret};
use crypto::secp::random_secret;
use onion::{new_stream_cipher, Onion, OnionError, Payload, RawBytes};
/// Onion hop struct
#[derive(Clone)]
pub struct Hop {
@@ -41,6 +48,7 @@ pub struct Hop {
}
/// Crate a new hop
#[cfg(test)]
pub fn new_hop(
server_key: &SecretKey,
hop_excess: &SecretKey,
@@ -56,7 +64,11 @@ pub fn new_hop(
}
/// Create an Onion for the Commitment, encrypting the payload for each hop
pub fn create_onion(commitment: &Commitment, hops: &Vec<Hop>) -> Result<Onion, OnionError> {
pub fn create_onion(
commitment: &Commitment,
hops: &Vec<Hop>,
use_test_rng: bool,
) -> Result<Onion, OnionError> {
if hops.is_empty() {
return Ok(Onion {
ephemeral_pubkey: xPublicKey::from([0u8; 32]),
@@ -67,14 +79,14 @@ pub fn create_onion(commitment: &Commitment, hops: &Vec<Hop>) -> Result<Onion, O
let mut shared_secrets: Vec<SharedSecret> = Vec::new();
let mut enc_payloads: Vec<RawBytes> = Vec::new();
let mut ephemeral_sk = StaticSecret::from(random_secret().0);
let mut ephemeral_sk = StaticSecret::from(random_secret(use_test_rng).0);
let onion_ephemeral_pk = xPublicKey::from(&ephemeral_sk);
for i in 0..hops.len() {
let hop = &hops[i];
let shared_secret = ephemeral_sk.diffie_hellman(&hop.server_pubkey);
shared_secrets.push(shared_secret);
ephemeral_sk = StaticSecret::from(random_secret().0);
ephemeral_sk = StaticSecret::from(random_secret(use_test_rng).0);
let next_ephemeral_pk = if i < (hops.len() - 1) {
xPublicKey::from(&ephemeral_sk)
} else {
@@ -106,16 +118,17 @@ pub fn create_onion(commitment: &Commitment, hops: &Vec<Hop>) -> Result<Onion, O
}
/// Internal tests
#[allow(missing_docs)]
#[allow(missing_docs, dead_code)]
#[cfg(test)]
pub mod test_util {
use super::*;
use crypto::dalek::DalekPublicKey;
use crypto::secp;
use grin_core::core::hash::Hash;
use grin_util::secp::Secp256k1;
use grin_util::ToHex;
use rand::{thread_rng, RngCore};
use secp256k1zkp::Secp256k1;
pub fn rand_onion() -> Onion {
let commit = rand_commit();
@@ -128,32 +141,32 @@ pub mod test_util {
None
};
let hop = new_hop(
&random_secret(),
&random_secret(),
&random_secret(false),
&random_secret(false),
thread_rng().next_u32(),
rangeproof,
);
hops.push(hop);
}
create_onion(&commit, &hops).unwrap()
create_onion(&commit, &hops, false).unwrap()
}
pub fn rand_commit() -> Commitment {
secp::commit(rand::thread_rng().next_u64(), &secp::random_secret()).unwrap()
secp::commit(rand::thread_rng().next_u64(), &secp::random_secret(false)).unwrap()
}
pub fn rand_hash() -> Hash {
Hash::from_hex(secp::random_secret().to_hex().as_str()).unwrap()
Hash::from_hex(secp::random_secret(false).to_hex().as_str()).unwrap()
}
pub fn rand_proof() -> RangeProof {
let secp = Secp256k1::new();
secp.bullet_proof(
rand::thread_rng().next_u64(),
secp::random_secret(),
secp::random_secret(),
secp::random_secret(),
secp::random_secret(false),
secp::random_secret(false),
secp::random_secret(false),
None,
None,
)
@@ -177,8 +190,8 @@ pub mod test_util {
let rp = secp.bullet_proof(
out_value,
blind.clone(),
secp::random_secret(),
secp::random_secret(),
secp::random_secret(false),
secp::random_secret(false),
None,
None,
);
@@ -187,7 +200,7 @@ pub mod test_util {
}
pub fn rand_keypair() -> (SecretKey, DalekPublicKey) {
let sk = random_secret();
let sk = random_secret(false);
let pk = DalekPublicKey::from_secret(&sk);
(sk, pk)
}
+14 -7
View File
@@ -14,7 +14,6 @@
//! Onion defn for mwixnet
use super::crypto::secp::{self, Commitment, RangeProof, SecretKey};
use super::util::{read_optional, vec_to_array, write_optional};
use std::convert::TryFrom;
@@ -26,6 +25,11 @@ use chacha20::cipher::{NewCipher, StreamCipher};
use chacha20::{ChaCha20, Key, Nonce};
use grin_core::core::FeeFields;
use grin_core::ser::{self, Readable, Reader, Writeable, Writer};
use grin_util::secp::{
self as secp256k1zkp,
key::SecretKey,
pedersen::{Commitment, RangeProof},
};
use grin_util::{self, ToHex};
use hmac::digest::InvalidLength;
use hmac::{Hmac, Mac};
@@ -35,6 +39,8 @@ use sha2::Sha256;
use thiserror::Error;
use x25519_dalek::{PublicKey as xPublicKey, SharedSecret, StaticSecret};
use super::crypto::secp;
type HmacSha256 = Hmac<Sha256>;
/// Raw bytes alias
pub type RawBytes = Vec<u8>;
@@ -374,7 +380,7 @@ pub mod tests {
let fee_per_hop: u32 = 2;
let in_value: u64 = 1000;
let out_value: u64 = in_value - total_fee;
let blind = random_secret();
let blind = random_secret(false);
let commitment = secp::commit(in_value, &blind).unwrap();
let mut hops: Vec<Hop> = Vec::new();
@@ -382,15 +388,15 @@ pub mod tests {
let mut final_commit = secp::commit(out_value, &blind).unwrap();
let mut final_blind = blind.clone();
for i in 0..5 {
keys.push(random_secret());
keys.push(random_secret(false));
let excess = random_secret();
let excess = random_secret(false);
let secp = secp256k1zkp::Secp256k1::with_caps(secp256k1zkp::ContextFlag::Commit);
final_blind.add_assign(&secp, &excess).unwrap();
final_commit = secp::add_excess(&final_commit, &excess).unwrap();
let proof = if i == 4 {
let n1 = random_secret();
let n1 = random_secret(false);
let rp = secp.bullet_proof(
out_value,
final_blind.clone(),
@@ -409,11 +415,12 @@ pub mod tests {
hops.push(hop);
}
let mut onion_packet = crate::mwixnet::onion::create_onion(&commitment, &hops).unwrap();
let mut onion_packet =
crate::mwixnet::onion::create_onion(&commitment, &hops, false).unwrap();
let mut payload = Payload {
next_ephemeral_pk: onion_packet.ephemeral_pubkey.clone(),
excess: random_secret(),
excess: random_secret(false),
fee: FeeFields::from(fee_per_hop),
rangeproof: None,
};
+3 -3
View File
@@ -37,7 +37,7 @@ use std::convert::TryInto;
/// # Example
///
/// ```
/// use grin_wallet_libwallet::mwixnet::onion::util::write_optional;
/// use grin_wallet_libwallet::mwixnet::onion_util::write_optional;
/// let mut writer:Vec<u8> = vec![];
/// let optional_value: Option<u32> = Some(10);
/// //write_optional(&mut writer, &optional_value);
@@ -75,7 +75,7 @@ pub fn write_optional<O: Writeable, W: Writer>(
/// # Example
///
/// ```
/// use grin_wallet_libwallet::mwixnet::onion::util::read_optional;
/// use grin_wallet_libwallet::mwixnet::onion_util::read_optional;
/// use grin_core::ser::{BinReader, ProtocolVersion, DeserializationMode};
/// let mut buf: &[u8] = &[1, 0, 0, 0, 10];
/// let mut reader = BinReader::new(&mut buf, ProtocolVersion::local(), DeserializationMode::default());
@@ -106,7 +106,7 @@ pub fn read_optional<O: Readable, R: Reader>(reader: &mut R) -> Result<Option<O>
/// # Example
///
/// ```
/// use grin_wallet_libwallet::mwixnet::onion::util::vec_to_array;
/// use grin_wallet_libwallet::mwixnet::onion_util::vec_to_array;
/// let v = vec![0, 1, 2, 3, 4, 5];
/// let a = vec_to_array::<4>(&v).unwrap();
/// assert_eq!(a, [0, 1, 2, 3]);
+10 -9
View File
@@ -1,4 +1,4 @@
// Copyright 2022 The Grin Developers
// Copyright 2024 The Grin Developers
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -15,28 +15,29 @@
//! Types related to mwixnet requests required by rest of lib crate apis
//! Should rexport all needed types here
pub use super::onion::crypto::comsig::{self, ComSignature};
pub use super::onion::crypto::secp::{add_excess, random_secret};
pub use super::onion::onion::Onion;
pub use super::onion::{new_hop, Hop};
use crate::grin_util::secp::key::SecretKey;
use super::onion::comsig_serde;
use grin_core::libtx::secp_ser::string_or_u64;
use grin_util::secp::key::SecretKey;
use serde::{Deserialize, Serialize};
pub use super::onion::{onion::Onion, ComSignature, Hop};
/// A Swap request
#[derive(Serialize, Deserialize, Debug)]
pub struct SwapReq {
/// Com signature
#[serde(with = "comsig::comsig_serde")]
#[serde(with = "comsig_serde")]
pub comsig: ComSignature,
/// Onion
pub onion: Onion,
}
/// mwixnetRequest Creation Params
#[derive(Serialize, Deserialize, Debug)]
pub struct MixnetReqCreationParams {
/// List of all the server keys
pub server_keys: Vec<SecretKey>,
/// Fees per hop
pub fee_per_hop: u32,
#[serde(with = "string_or_u64")]
pub fee_per_hop: u64,
}
+5 -5
View File
@@ -188,11 +188,11 @@ fn format_slatepack(slatepack: &str) -> Result<String, Error> {
// Returns the first four bytes of a double sha256 hash of some bytes
fn generate_check(payload: &[u8]) -> Result<Vec<u8>, Error> {
let mut first_hash = Sha256::new();
first_hash.update(payload);
let mut second_hash = Sha256::new();
second_hash.update(first_hash.finalize());
let checksum = second_hash.finalize();
let mut first_hasher = Sha256::new();
first_hasher.update(payload);
let mut second_hasher = Sha256::new();
second_hasher.update(first_hasher.finalize());
let checksum = second_hasher.finalize();
let check_bytes: Vec<u8> = checksum[0..4].to_vec();
Ok(check_bytes)
}