Skip to content

Commit

Permalink
Merge pull request #529 from taikiy/remove_unused_code
Browse files Browse the repository at this point in the history
Removing dead code
  • Loading branch information
benjaminsavage authored Mar 10, 2023
2 parents 4cd9b1d + f9c1da3 commit bf2dc2a
Show file tree
Hide file tree
Showing 4 changed files with 5 additions and 301 deletions.
204 changes: 1 addition & 203 deletions src/protocol/sort/generate_permutation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,9 @@ use crate::{
context::{Context, MaliciousContext, NoRecord},
malicious::MaliciousValidator,
sort::{
bit_permutation::bit_permutation,
ShuffleRevealStep::{RevealPermutation, ShufflePermutation},
SortStep::{
ApplyInv, BitPermutationStep, ComposeStep, ShuffleRevealPermutation, SortKeys,
},
SortStep::{ShuffleRevealPermutation, SortKeys},
},
IpaProtocolStep::Sort,
RecordId,
},
secret_sharing::{
Expand All @@ -25,13 +21,10 @@ use crate::{
};

use super::{
compose::compose,
generate_permutation_opt::{generate_permutation_opt, malicious_generate_permutation_opt},
secureapplyinv::secureapplyinv,
shuffle::{get_two_of_three_random_permutations, shuffle_shares},
};
use crate::protocol::{context::SemiHonestContext, sort::ShuffleRevealStep::GeneratePermutation};
use embed_doc_image::embed_doc_image;

#[derive(Debug)]
/// This object contains the output of `shuffle_and_reveal_permutation`
Expand Down Expand Up @@ -126,94 +119,6 @@ pub(super) async fn malicious_shuffle_and_reveal_permutation<F: Field>(
})
}

#[embed_doc_image("semi_honest_sort", "images/sort/semi-honest-sort.png")]
/// This is an implementation of `GenPerm` (Algorithm 6) described in:
/// "An Efficient Secure Three-Party Sorting Protocol with an Honest Majority"
/// by K. Chida, K. Hamada, D. Ikarashi, R. Kikuchi, N. Kiribuchi, and B. Pinkas
/// <https://eprint.iacr.org/2019/695.pdf>.
/// This protocol generates permutation of a stable sort for the given shares of inputs.
///
/// Steps
/// For the 0th bit
/// 1. Get replicated shares in Field using modulus conversion
/// 2. Compute bit permutation that sorts 0th bit
/// For 1st to N-1th bit of input share
/// 1. Shuffle and reveal the i-1th composition
/// 2. Get replicated shares in Field using modulus conversion
/// 3. Sort ith bit based on i-1th bits by applying i-1th composition on ith bit
/// 4 Compute bit permutation that sorts ith bit
/// 5. Compute ith composition by composing i-1th composition on ith permutation
/// In the end, n-1th composition is returned. This is the permutation which sorts the inputs
///
/// ![Generate sort permutation steps][semi_honest_sort]
pub async fn generate_permutation<F>(
ctx: SemiHonestContext<'_>,
sort_keys: &[Vec<Replicated<F>>],
num_bits: u32,
) -> Result<Vec<Replicated<F>>, Error>
where
F: Field,
{
let ctx_0 = ctx.narrow(&Sort(0));
assert_eq!(sort_keys.len(), num_bits as usize);

let bit_0_permutation =
bit_permutation(ctx_0.narrow(&BitPermutationStep), &sort_keys[0]).await?;

let mut composed_less_significant_bits_permutation = bit_0_permutation;
for bit_num in 1..num_bits {
let ctx_bit = ctx.narrow(&Sort(bit_num.try_into().unwrap()));

let revealed_and_random_permutations = shuffle_and_reveal_permutation(
ctx_bit.narrow(&ShuffleRevealPermutation),
composed_less_significant_bits_permutation,
)
.await?;

let bit_i_sorted_by_less_significant_bits = secureapplyinv(
ctx_bit.narrow(&ApplyInv),
sort_keys[bit_num as usize].clone(),
(
revealed_and_random_permutations
.randoms_for_shuffle
.0
.as_slice(),
revealed_and_random_permutations
.randoms_for_shuffle
.1
.as_slice(),
),
&revealed_and_random_permutations.revealed,
)
.await?;

let bit_i_permutation = bit_permutation(
ctx_bit.narrow(&BitPermutationStep),
&bit_i_sorted_by_less_significant_bits,
)
.await?;

let composed_i_permutation = compose(
ctx_bit.narrow(&ComposeStep),
(
revealed_and_random_permutations
.randoms_for_shuffle
.0
.as_slice(),
revealed_and_random_permutations
.randoms_for_shuffle
.1
.as_slice(),
),
&revealed_and_random_permutations.revealed,
bit_i_permutation,
)
.await?;
composed_less_significant_bits_permutation = composed_i_permutation;
}
Ok(composed_less_significant_bits_permutation)
}

/// This function takes in a semihonest context and sort keys, generates a sort permutation, shuffles and reveals it and
/// returns both shuffle-revealed permutation and 2/3 randoms which were used to shuffle the permutation
/// The output of this can be applied to any of semihonest/malicious context
Expand Down Expand Up @@ -253,113 +158,6 @@ pub async fn malicious_generate_permutation_and_reveal_shuffled<F: Field>(
.await
}

#[allow(dead_code)]
#[embed_doc_image("malicious_sort", "images/sort/malicious-sort.png")]
/// Returns a sort permutation in a malicious context.
/// This runs sort in a malicious context. The caller is responsible to validate the accumulator contents and downgrade context to Semi-honest before calling this function
/// The function takes care of upgrading and validating while the sort protocol runs.
/// It then returns a semi honest context with output in Replicated format. The caller should then upgrade the output and context before moving forward
///
/// Steps
/// 1. [Malicious Special] Upgrade the context from semihonest to malicious and get a validator
/// 2. [Malicious Special] Upgrade 0th sort bit keys
/// 3. Compute bit permutation that sorts 0th bit
///
/// For 1st to N-1th bit of input share
/// 1. i. Shuffle the i-1th composition
/// ii. [Malicious Special] Validate the accumulator contents
/// iii. [Malicious Special] Malicious reveal
/// iv. [Malicious Special] Downgrade context to semihonest
/// 2. i. [Malicious Special] Upgrade ith sort bit keys
/// ii. Sort ith bit based on i-1th bits by applying i-1th composition on ith bit
/// 3. Compute bit permutation that sorts ith bit
/// 4. Compute ith composition by composing i-1th composition on ith permutation
/// In the end, following is returned
/// i. n-1th composition: This is the permutation which sorts the inputs
/// ii. Validator which can be used to validate the leftover items in the accumulator
///
/// ![Malicious sort permutation steps][malicious_sort]
/// # Panics
/// If sort keys dont have num of bits same as `num_bits`
/// # Errors
pub async fn malicious_generate_permutation<'a, F>(
sh_ctx: SemiHonestContext<'a>,
sort_keys: &[Vec<Replicated<F>>],
num_bits: u32,
) -> Result<(MaliciousValidator<'a, F>, Vec<MaliciousReplicated<F>>), Error>
where
F: Field,
{
let mut malicious_validator = MaliciousValidator::new(sh_ctx.clone());
let mut m_ctx_bit = malicious_validator.context();
assert_eq!(sort_keys.len(), num_bits as usize);

let upgraded_sort_keys = m_ctx_bit.upgrade(sort_keys[0].clone()).await?;
let bit_0_permutation =
bit_permutation(m_ctx_bit.narrow(&BitPermutationStep), &upgraded_sort_keys).await?;

let mut composed_less_significant_bits_permutation = bit_0_permutation;
for bit_num in 1..num_bits {
let revealed_and_random_permutations = malicious_shuffle_and_reveal_permutation(
m_ctx_bit.narrow(&ShuffleRevealPermutation),
composed_less_significant_bits_permutation,
malicious_validator,
)
.await?;

malicious_validator =
MaliciousValidator::new(sh_ctx.narrow(&Sort(bit_num.try_into().unwrap())));
m_ctx_bit = malicious_validator.context();
let upgraded_sort_keys = m_ctx_bit
.upgrade(sort_keys[bit_num as usize].clone())
.await?;
let bit_i_sorted_by_less_significant_bits = secureapplyinv(
m_ctx_bit.narrow(&ApplyInv),
upgraded_sort_keys,
(
revealed_and_random_permutations
.randoms_for_shuffle
.0
.as_slice(),
revealed_and_random_permutations
.randoms_for_shuffle
.1
.as_slice(),
),
&revealed_and_random_permutations.revealed,
)
.await?;

let bit_i_permutation = bit_permutation(
m_ctx_bit.narrow(&BitPermutationStep),
&bit_i_sorted_by_less_significant_bits,
)
.await?;

let composed_i_permutation = compose(
m_ctx_bit.narrow(&ComposeStep),
(
revealed_and_random_permutations
.randoms_for_shuffle
.0
.as_slice(),
revealed_and_random_permutations
.randoms_for_shuffle
.1
.as_slice(),
),
&revealed_and_random_permutations.revealed,
bit_i_permutation,
)
.await?;
composed_less_significant_bits_permutation = composed_i_permutation;
}
Ok((
malicious_validator,
composed_less_significant_bits_permutation,
))
}

#[cfg(all(test, not(feature = "shuttle")))]
mod tests {
use std::iter::zip;
Expand Down
2 changes: 1 addition & 1 deletion src/protocol/sort/generate_permutation_opt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use crate::{
};
use embed_doc_image::embed_doc_image;

#[embed_doc_image("semi_honest_sort", "images/sort/semi-honest-sort.png")]
/// This is an implementation of `OptGenPerm` (Algorithm 12) described in:
/// "An Efficient Secure Three-Party Sorting Protocol with an Honest Majority"
/// by K. Chida, K. Hamada, D. Ikarashi, R. Kikuchi, N. Kiribuchi, and B. Pinkas
Expand Down Expand Up @@ -112,7 +113,6 @@ where
Ok(composed_less_significant_bits_permutation)
}

#[allow(dead_code)]
#[embed_doc_image("malicious_sort", "images/sort/malicious-sort.png")]
/// Returns a sort permutation in a malicious context.
/// This runs sort in a malicious context. The caller is responsible to validate the accumulator contents and downgrade context to Semi-honest before calling this function
Expand Down
1 change: 0 additions & 1 deletion src/protocol/sort/multi_bit_permutation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ use std::iter::repeat;
/// i. For each record
/// a. Calculate accumulated `prefix_sum` = s + `mult_output`
/// 4. Compute the final output using sum of products executed in parallel for each record.
#[allow(dead_code)]
pub async fn multi_bit_permutation<
'a,
F: Field,
Expand Down
99 changes: 3 additions & 96 deletions src/protocol/sort/secureapplyinv.rs
Original file line number Diff line number Diff line change
@@ -1,57 +1,10 @@
use crate::{
error::Error,
ff::Field,
protocol::{basics::Reshare, context::Context, sort::ApplyInvStep::ShuffleInputs, RecordId},
secret_sharing::SecretSharing,
};
use embed_doc_image::embed_doc_image;

use super::{
apply::apply_inv, apply_sort::shuffle_shares as shuffle_vectors, shuffle::shuffle_shares,
};
#[embed_doc_image("secureapplyinv", "images/sort/secureapplyinv.png")]

/// This is an implementation of ApplyInv (Algorithm 4) found in the paper:
/// "An Efficient Secure Three-Party Sorting Protocol with an Honest Majority"
/// by K. Chida, K. Hamada, D. Ikarashi, R. Kikuchi, N. Kiribuchi, and B. Pinkas
/// <https://eprint.iacr.org/2019/695.pdf>
///
/// This is a protocol that applies the inverse of a secret-shared permutation to a vector of secret-shared values
/// Input: Each helpers know their own secret shares of input and permutation
/// Output: At the end of the protocol, all helpers receive inputs after the permutation is applied
/// This algorithm applies a permutation to the `input` vector. The permutation is secret-shared,
/// and none of the helpers should learn it through this protocol.
/// To keep the permutation secret, it (and the inputs) are first randomly securely shuffled.
/// After this shuffle, the permutation can be revealed.
/// An adversary can only obtain a shuffled permutation, which is just a random permutation.
///
/// ![Secure Apply Inv steps][secureapplyinv]
///
/// Steps
///
/// 1. Generate random permutations using prss
/// 2. Secret shared permutation is shuffled with random permutations
/// 3. Secret shared value is shuffled using the same random permutations
/// 4. The permutation is revealed
/// 5. All helpers call `apply` to apply the permutation locally.
pub async fn secureapplyinv<F: Field, S: SecretSharing<F> + Reshare<C, RecordId>, C: Context>(
ctx: C,
input: Vec<S>,
random_permutations_for_shuffle: (&[u32], &[u32]),
shuffled_sort_permutation: &[u32],
) -> Result<Vec<S>, Error> {
let mut shuffled_input = shuffle_shares(
input,
random_permutations_for_shuffle,
ctx.narrow(&ShuffleInputs),
)
.await?;

apply_inv(shuffled_sort_permutation, &mut shuffled_input);
Ok(shuffled_input)
}
use super::{apply::apply_inv, apply_sort::shuffle_shares as shuffle_vectors};

#[allow(dead_code)]
pub async fn secureapplyinv_multi<C: Context, I: Reshare<C, RecordId> + Send + Sync>(
ctx: C,
input: Vec<I>,
Expand Down Expand Up @@ -80,59 +33,13 @@ mod tests {
protocol::{
context::Context,
sort::{
apply::apply_inv,
generate_permutation::shuffle_and_reveal_permutation,
secureapplyinv::{secureapplyinv, secureapplyinv_multi},
apply::apply_inv, generate_permutation::shuffle_and_reveal_permutation,
secureapplyinv::secureapplyinv_multi,
},
},
test_fixture::{Reconstruct, Runner, TestWorld},
};

#[tokio::test]
pub async fn simple() {
const BATCHSIZE: u32 = 25;
let world = TestWorld::new().await;
let mut rng = rand::thread_rng();

let mut input = Vec::with_capacity(BATCHSIZE as usize);
input.resize_with(BATCHSIZE.try_into().unwrap(), || rng.gen::<Fp31>());

let mut permutation: Vec<u32> = (0..BATCHSIZE).collect();
permutation.shuffle(&mut rng);

let mut expected_result = input.clone();

// Applying permutation on the input in clear to get the expected result
apply_inv(&permutation, &mut expected_result);

let permutation_iter = permutation.into_iter().map(u128::from).map(Fp31::from);

let result = world
.semi_honest(
(input, permutation_iter),
|ctx, (m_shares, m_perms)| async move {
let perm_and_randoms =
shuffle_and_reveal_permutation(ctx.narrow("shuffle_reveal"), m_perms)
.await
.unwrap();
secureapplyinv(
ctx,
m_shares,
(
perm_and_randoms.randoms_for_shuffle.0.as_slice(),
perm_and_randoms.randoms_for_shuffle.1.as_slice(),
),
&perm_and_randoms.revealed,
)
.await
.unwrap()
},
)
.await;

assert_eq!(&expected_result[..], &result.reconstruct());
}

#[tokio::test]
pub async fn multi() {
const BATCHSIZE: u32 = 25;
Expand Down

0 comments on commit bf2dc2a

Please sign in to comment.