Skip to content

Commit

Permalink
r1cs-mpc: mpc-prover: Add batch commitment methods
Browse files Browse the repository at this point in the history
  • Loading branch information
joeykraut committed Aug 2, 2023
1 parent faa6c11 commit 1b5b110
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 25 deletions.
15 changes: 9 additions & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,17 @@ name = "mpc-bulletproof"
# - update html_root_url
# - ensure yoloproofs was disabled in an atomic (revertable) commit
# - update CHANGELOG
version = "2.0.0"
authors = ["Cathie Yun <cathieyun@gmail.com>",
"Henry de Valence <hdevalence@hdevalence.ca>",
"Oleg Andreev <oleganza@gmail.com>"]
version = "0.1.0"
authors = [
"Joey Kraut <joey@renegade.fi>",
"Andrew Kirillov <andrew@renegade.fi>",
]
readme = "README.md"
license = "MIT"
repository = "https://github.com/renegade-fi/mpc-bulletproof"
categories = ["cryptography"]
keywords = ["cryptography", "crypto", "stark", "zero-knowledge", "bulletproofs"]
description = "A pure-Rust implementation of collaboratively proved Bulletproofs using Ristretto"
description = "A pure-Rust implementation of collaboratively proved Bulletproofs over the Stark curve."
edition = "2021"

[dependencies]
Expand All @@ -35,7 +36,9 @@ serde_derive = { version = "1", default-features = false }
thiserror = { version = "1", optional = true }
tokio = { version = "1.12", features = ["macros", "rt-multi-thread"] }
merlin = { git = "https://github.com/renegade-fi/merlin" }
clear_on_drop = { version = "0.2", default-features = false, features = ["nightly"] }
clear_on_drop = { version = "0.2", default-features = false, features = [
"nightly",
] }

[dev-dependencies]
async-std = "1.12"
Expand Down
3 changes: 2 additions & 1 deletion integration/mpc_inner_product.rs
Original file line number Diff line number Diff line change
Expand Up @@ -298,9 +298,10 @@ fn test_random_inner_product(test_args: &IntegrationTestArgs) -> Result<(), Stri
let mut rng = thread_rng();
let index_assignment = (0..2 * n)
.map(|_| rng.gen_range(0..2))
.map(|value| fabric.allocate_scalar(value))
.map(|value| {
if fabric.party_id() == PARTY0 {
fabric.send_scalar(value)
fabric.send_value(value)
} else {
fabric.receive_value()
}
Expand Down
4 changes: 2 additions & 2 deletions src/r1cs_mpc/authenticated_poly.rs
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ mod tests {

async fn receive_message(&mut self) -> Result<NetworkOutbound, MpcNetworkError> {
Ok(NetworkOutbound {
op_id: 0,
result_id: 0,
payload: NetworkPayload::Scalar(Scalar::one()),
})
}
Expand All @@ -306,7 +306,7 @@ mod tests {
_message: NetworkOutbound,
) -> Result<NetworkOutbound, MpcNetworkError> {
Ok(NetworkOutbound {
op_id: 0,
result_id: 0,
payload: NetworkPayload::Scalar(Scalar::one()),
})
}
Expand Down
4 changes: 2 additions & 2 deletions src/r1cs_mpc/mpc_linear_combination.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ impl<'a> From<&'a MpcVariable> for MpcLinearCombination {

impl From<ScalarResult> for MpcLinearCombination {
fn from(s: ScalarResult) -> Self {
let fabric = s.clone_fabric();
let fabric = s.fabric().clone();
MpcLinearCombination {
terms: HashMap::from([(MpcVariable::one(fabric), s)]),
}
Expand All @@ -99,7 +99,7 @@ impl From<ScalarResult> for MpcLinearCombination {

impl From<&ScalarResult> for MpcLinearCombination {
fn from(s: &ScalarResult) -> Self {
let fabric = s.clone_fabric();
let fabric = s.fabric().clone();
MpcLinearCombination {
terms: HashMap::from([(MpcVariable::one(fabric), s.clone())]),
}
Expand Down
65 changes: 52 additions & 13 deletions src/r1cs_mpc/mpc_prover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use crate::{
util, BulletproofGens, PedersenGens,
};
use futures::future::join_all;
use itertools::Itertools;
use merlin::HashChainTranscript as Transcript;
use mpc_stark::{
algebra::{
Expand Down Expand Up @@ -367,12 +368,11 @@ impl<'a, 't, 'g> MpcProver<'a, 't, 'g> {
) -> Result<(AuthenticatedStarkPointOpenResult, MpcVariable), MpcError> {
// Allocate the value in the MPC network and then commit to the shared value
let shared_v = self.fabric.share_scalar(v, owning_party);
self.commit_preshared(&shared_v, v_blinding)
let shared_blinder = self.fabric.allocate_preshared_scalar(v_blinding);
self.commit_preshared(&shared_v, &shared_blinder)
}

/// Commit to a batch of values
///
/// TODO: Optimize this to use a single batched fabric operation
pub fn batch_commit<I, T>(
&mut self,
owning_party: PartyId,
Expand All @@ -383,12 +383,16 @@ impl<'a, 't, 'g> MpcProver<'a, 't, 'g> {
I: IntoIterator<Item = T>,
T: Into<Scalar>,
{
Ok(v.into_iter()
.zip(v_blinding.iter())
.map(|(v, v_blinding)| self.commit(owning_party, v, *v_blinding))
.collect::<Result<Vec<_>, _>>()?
.into_iter()
.unzip())
let v = v.into_iter().map(Into::into).collect_vec();
assert_eq!(v.len(), v_blinding.len());

// Share scalars with counterparty
let shared_v = self.fabric.batch_share_scalar(v, owning_party);
let shared_blinder = self
.fabric
.batch_allocate_preshared_scalar(v_blinding.to_vec());

self.batch_commit_preshared(&shared_v, &shared_blinder)
}

/// Commit to a pre-shared value
Expand All @@ -399,24 +403,59 @@ impl<'a, 't, 'g> MpcProver<'a, 't, 'g> {
pub fn commit_preshared(
&mut self,
v: &AuthenticatedScalarResult,
v_blinding: Scalar,
v_blinding: &AuthenticatedScalarResult,
) -> Result<(AuthenticatedStarkPointOpenResult, MpcVariable), MpcError> {
// Commit to the input, open the commitment, and add the commitment to the transcript.
let blinder = self.fabric.allocate_preshared_scalar(v_blinding);
let value_commit = self.pc_gens.commit_shared(v, &blinder).open_authenticated();
let value_commit = self
.pc_gens
.commit_shared(v, v_blinding)
.open_authenticated();
self.transcript.append_point(b"V", &value_commit.value);

// Add the value to the constraint system
let i = self.v.len();
self.v.push(v.clone());
self.v_blinding.push(blinder);
self.v_blinding.push(v_blinding.clone());

Ok((
value_commit,
MpcVariable::new_with_type(Variable::Committed(i), self.fabric.clone()),
))
}

/// Commit to a batch of pre-shared values
pub fn batch_commit_preshared(
&mut self,
v: &[AuthenticatedScalarResult],
v_blinding: &[AuthenticatedScalarResult],
) -> Result<(Vec<AuthenticatedStarkPointOpenResult>, Vec<MpcVariable>), MpcError> {
assert_eq!(v.len(), v_blinding.len());
let n = v.len();

// Open the blinders
let commitments = v
.iter()
.zip(v_blinding.iter())
.map(|(value, blinder)| self.pc_gens.commit_shared(value, blinder))
.collect_vec();
let open_comms = AuthenticatedStarkPointResult::open_authenticated_batch(&commitments);

open_comms
.iter()
.for_each(|blinder| self.transcript.append_point(b"V", &blinder.value));

let i = self.v.len();
self.v.append(&mut v.to_vec());
self.v_blinding.append(&mut v_blinding.to_vec());

Ok((
open_comms,
(i..i + n)
.map(|i| MpcVariable::new_with_type(Variable::Committed(i), self.fabric.clone()))
.collect(),
))
}

/// Use a challenge, `z`, to flatten the constraints in the
/// constraint system into vectors used for proving and
/// verification.
Expand Down
2 changes: 1 addition & 1 deletion src/transcript.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ impl MpcTranscript {
self.fabric
.new_gate_op::<_, Scalar>(vec![self.latest_op_id], move |_args| {
let mut locked_transcript = transcript_ref.lock().expect(ERR_LOCK_POISONED);
locked_transcript.append_message(b"dom-sep", b"r1cs-2phase");
locked_transcript.r1cs_2phase_domain_sep();

ResultValue::Scalar(Scalar::zero())
});
Expand Down

0 comments on commit 1b5b110

Please sign in to comment.