Skip to content

Commit

Permalink
feat: implement a radix sort in MPC and use it for range checks in co…
Browse files Browse the repository at this point in the history
…-noir (#290)
  • Loading branch information
rw0x0 authored Dec 11, 2024
1 parent f50ab33 commit bc8c458
Show file tree
Hide file tree
Showing 6 changed files with 764 additions and 3 deletions.
4 changes: 2 additions & 2 deletions co-noir/co-acvm/src/mpc/rep3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ use std::marker::PhantomData;
use ark_ff::PrimeField;
use co_brillig::mpc::{Rep3BrilligDriver, Rep3BrilligType};
use itertools::{izip, Itertools};
use mpc_core::protocols::rep3::gadgets::sort::batcher_odd_even_merge_sort_yao;
use mpc_core::protocols::rep3::{arithmetic, yao};
use mpc_core::protocols::rep3_ring::gadgets::sort::radix_sort_fields;
use mpc_core::{
lut::LookupTableProvider,
protocols::rep3::{
Expand Down Expand Up @@ -496,6 +496,6 @@ impl<F: PrimeField, N: Rep3Network> NoirWitnessExtensionProtocol<F> for Rep3Acvm
inputs: &[Self::ArithmeticShare],
bitsize: usize,
) -> std::io::Result<Vec<Self::ArithmeticShare>> {
batcher_odd_even_merge_sort_yao(inputs, &mut self.io_context, bitsize)
radix_sort_fields(inputs, &mut self.io_context, bitsize)
}
}
23 changes: 22 additions & 1 deletion mpc-core/src/protocols/rep3/rngs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ use ark_ec::CurveGroup;
use ark_ff::{One, PrimeField};
use fancy_garbling::WireMod2;
use num_bigint::BigUint;
use rand::{distributions::Standard, prelude::Distribution, Rng, RngCore, SeedableRng};
use rand::{
distributions::Standard, prelude::Distribution, seq::SliceRandom, Rng, RngCore, SeedableRng,
};
use rayon::prelude::*;

#[derive(Debug)]
Expand Down Expand Up @@ -208,6 +210,16 @@ impl Rep3Rand {
val & &mask
}

/// Generate a random field_element from rng1
pub fn random_field_element_rng1<F: PrimeField>(&mut self) -> F {
F::rand(&mut self.rng1)
}

/// Generate a random field_element from rng2
pub fn random_field_element_rng2<F: PrimeField>(&mut self) -> F {
F::rand(&mut self.rng2)
}

/// Generate a random `T` from rng1
pub fn random_element_rng1<T>(&mut self) -> T
where
Expand All @@ -230,6 +242,15 @@ impl Rep3Rand {
let seed2 = self.rng2.gen();
(seed1, seed2)
}

/// Generate a random shared permutation
pub(crate) fn random_perm<T: Clone>(&mut self, input: Vec<T>) -> (Vec<T>, Vec<T>) {
let mut a = input.to_owned();
let mut b = input;
a.shuffle(&mut self.rng1);
b.shuffle(&mut self.rng2);
(a, b)
}
}

/// This struct is responsible for creating random shares for the Binary to Arithmetic conversion. The approach is the following: for a final sharing x = x1 + x2 + x3, we want to have random values x2, x3 and subtract these from the original value x using a binary circuit to get the share x1. Hence, we need to sample random x2 and x3 and share them amongst the parties. One RandBitComp struct is responsible for either sampling x2 or x3. For sampling x2, parties 1 and 2 will get x2 in plain (since this is the final share of x), so they need to have a PRF key from all parties. party 3, however, will not get x2 in plain and must thus only be able to sample its shares of x2, requiring two PRF keys.
Expand Down
1 change: 1 addition & 0 deletions mpc-core/src/protocols/rep3_ring.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ pub mod binary;
pub mod casts;
pub mod conversion;
mod detail;
pub mod gadgets;
pub mod ring;
pub mod yao;

Expand Down
5 changes: 5 additions & 0 deletions mpc-core/src/protocols/rep3_ring/gadgets/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
//! Gadgets
//!
//! This module contains some commonly used gadgets for the Rep3 protocol.
pub mod sort;
Loading

0 comments on commit bc8c458

Please sign in to comment.