Skip to content

Commit

Permalink
feat: revamp input commitment code
Browse files Browse the repository at this point in the history
  • Loading branch information
grumbach authored and davidrusu committed Feb 2, 2023
1 parent 6e501fe commit 423e3dc
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 47 deletions.
22 changes: 2 additions & 20 deletions src/transaction/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
// This SAFE Network Software is licensed under the BSD-3-Clause license.
// Please see the LICENSE file for more details.

use bls_bulletproofs::{group::GroupEncoding, rand::RngCore, PedersenGens};
use bls_bulletproofs::{group::GroupEncoding, PedersenGens};
use blsttc::{PublicKey, SecretKey, Signature};

#[cfg(feature = "serde")]
Expand Down Expand Up @@ -37,30 +37,18 @@ impl RevealedInput {
&self.revealed_commitment
}

/// Generate a pseudo-commitment to the input amount
pub fn random_pseudo_commitment(&self, rng: impl RngCore) -> RevealedCommitment {
RevealedCommitment::from_value(self.revealed_commitment.value, rng)
}

pub fn commitment(&self, pc_gens: &PedersenGens) -> Commitment {
self.revealed_commitment.commit(pc_gens)
}

pub fn sign(
&self,
msg: &[u8],
revealed_pseudo_commitment: &RevealedCommitment,
pc_gens: &PedersenGens,
) -> Input {
pub fn sign(&self, msg: &[u8], pc_gens: &PedersenGens) -> Input {
let public_key = self.public_key();
let commitment = self.commitment(pc_gens);
let pseudo_commitment = revealed_pseudo_commitment.commit(pc_gens);
let signature = self.secret_key.sign(msg);

Input {
public_key,
commitment,
pseudo_commitment,
signature,
}
}
Expand All @@ -71,7 +59,6 @@ impl RevealedInput {
pub struct Input {
pub public_key: PublicKey,
pub commitment: Commitment,
pub pseudo_commitment: Commitment,
pub signature: Signature,
}

Expand All @@ -80,15 +67,10 @@ impl Input {
let mut v: Vec<u8> = Default::default();
v.extend(self.public_key.to_bytes().as_ref());
v.extend(self.commitment.to_bytes().as_ref());
v.extend(self.pseudo_commitment.to_bytes().as_ref());
v.extend(self.signature.to_bytes().as_ref());
v
}

pub fn pseudo_commitment(&self) -> Commitment {
self.pseudo_commitment
}

pub fn public_key(&self) -> PublicKey {
self.public_key
}
Expand Down
48 changes: 21 additions & 27 deletions src/transaction/output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,32 +80,30 @@ impl RevealedTransaction {
) -> Result<(DbcTransaction, Vec<RevealedCommitment>)> {
// We need to gather a bunch of things for our message to sign.
// All public keys in all inputs
// All PseudoCommitments
// All input commitments
// All output public keys.
// All output commitments
// All output range proofs
//
// notes:
// 1. the real pk is randomly mixed with decoys by MlsagMaterial
// 2. output commitments, range_proofs, and public_keys are bundled
// 1. output commitments, range_proofs, and public_keys are bundled
// together in OutputProofs
// 3. all these must be generated in proper order
let revealed_pseudo_commitments = self.revealed_pseudo_commitments(&mut rng);
let pseudo_commitments = self.pseudo_commitments(&revealed_pseudo_commitments);
let revealed_input_commitments = self.revealed_input_commitments();
let input_commitments = self.input_commitments();

let revealed_output_commitments =
self.revealed_output_commitments(&revealed_pseudo_commitments, &mut rng);
self.revealed_output_commitments(&revealed_input_commitments, &mut rng);
let output_proofs = self.output_range_proofs(&revealed_output_commitments, &mut rng)?;

// Generate message to sign.
// note: must match message generated by DbcTransaction::verify()
let msg = gen_message_for_signing(&self.public_keys(), &pseudo_commitments, &output_proofs);
let msg = gen_message_for_signing(&self.public_keys(), &input_commitments, &output_proofs);

// We create a signature for each input
let signed_inputs: Vec<Input> = self
.inputs
.iter()
.zip(revealed_pseudo_commitments.iter())
.map(|(input, r)| input.sign(&msg, r, &Self::pc_gens()))
.map(|input| input.sign(&msg, &Self::pc_gens()))
.collect();

let revealed_output_commitments = revealed_output_commitments
Expand Down Expand Up @@ -134,26 +132,23 @@ impl RevealedTransaction {
self.inputs.iter().map(|input| input.public_key()).collect()
}

fn revealed_pseudo_commitments(&self, mut rng: impl RngCore) -> Vec<RevealedCommitment> {
fn revealed_input_commitments(&self) -> Vec<RevealedCommitment> {
self.inputs
.iter()
.map(|input| input.random_pseudo_commitment(&mut rng))
.map(|input| *input.revealed_commitment())
.collect()
}

fn pseudo_commitments(
&self,
revealed_pseudo_commitments: &[RevealedCommitment],
) -> Vec<Commitment> {
revealed_pseudo_commitments
fn input_commitments(&self) -> Vec<Commitment> {
self.inputs
.iter()
.map(|r| r.commit(&Self::pc_gens()))
.map(|input| input.commitment(&Self::pc_gens()))
.collect()
}

fn revealed_output_commitments(
&self,
revealed_pseudo_commitments: &[RevealedCommitment],
revealed_input_commitments: &[RevealedCommitment],
mut rng: impl RngCore,
) -> Vec<RevealedOutputCommitment> {
// avoid subtraction underflow in next step.
Expand All @@ -172,7 +167,7 @@ impl RevealedTransaction {
.collect();

// todo: replace fold() with sum() when supported in blstrs
let input_sum: Scalar = revealed_pseudo_commitments
let input_sum: Scalar = revealed_input_commitments
.iter()
.map(RevealedCommitment::blinding)
.fold(Scalar::zero(), |sum, x| sum + x);
Expand Down Expand Up @@ -235,15 +230,15 @@ impl RevealedTransaction {
// which must match.
fn gen_message_for_signing(
public_keys: &[PublicKey],
pseudo_commitments: &[Commitment],
input_commitments: &[Commitment],
output_proofs: &[OutputProof],
) -> Vec<u8> {
// Generate message to sign.
let mut msg: Vec<u8> = Default::default();
for pk in public_keys.iter() {
msg.extend(pk.to_bytes().as_ref());
}
for r in pseudo_commitments.iter() {
for r in input_commitments.iter() {
msg.extend(r.to_bytes().as_ref());
}
for o in output_proofs.iter() {
Expand Down Expand Up @@ -328,11 +323,10 @@ impl DbcTransaction {
// All public keys
let public_keys: Vec<PublicKey> = self.inputs.iter().map(|m| m.public_key).collect();

// All PseudoCommitments.
let pseudo_commitments: Vec<Commitment> =
self.inputs.iter().map(|m| m.pseudo_commitment).collect();
// All input commitments
let input_commitments: Vec<Commitment> = self.inputs.iter().map(|i| i.commitment).collect();

gen_message_for_signing(&public_keys, &pseudo_commitments, &self.outputs)
gen_message_for_signing(&public_keys, &input_commitments, &self.outputs)
}

pub fn verify(&self, public_commitments: &[Commitment]) -> Result<()> {
Expand Down Expand Up @@ -372,7 +366,7 @@ impl DbcTransaction {
let input_sum: G1Projective = self
.inputs
.iter()
.map(Input::pseudo_commitment)
.map(|i| i.commitment)
.map(G1Projective::from)
.sum();
let output_sum: G1Projective = self
Expand Down

0 comments on commit 423e3dc

Please sign in to comment.