Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test of malicious behavior during zero check protocol #1205

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

andyleiserson
Copy link
Collaborator

Test case related to #1204 -- will post more detail to the issue.

impl<F: Fn(&MaliciousHelperContext, &mut Vec<u8>) + Send + Sync> MaliciousHelper<F> {
impl<F> MaliciousHelper<F>
where
F: Fn(MaliciousHelperContext, &mut Vec<u8>) -> Pin<Box<dyn Future<Output = ()> + Send>>,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need this given that it is only used in non-async context? it may be better to convert non-async code to async inside this helper - non-async code is much easier to deal with

);

tracing::info!("{:?}", &rv);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
tracing::info!("{:?}", &rv);

Ok(rv == F::ZERO)
}

#[cfg(test)]
pub async fn check_zero_fp32bitprime<C>(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do you have plans to use it outside of this module or we can move it into tests?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the same argument applies to SH1 as well

@@ -124,4 +187,122 @@ mod tests {

Ok(())
}

pub struct NotifyOnceCell<T: Clone + Send + Sync> {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how is it different from https://docs.rs/tokio/latest/tokio/sync/struct.OnceCell.html? Maybe you could elaborate that in the documentation to this struct

}
}

struct MaliciousCheckZeroInterceptor {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lets explain what is the goal for this interceptor because it does seem very specific to check zero use case

tracing::info!("got shares: {sh1:?} {sh2:?}");
let adjusted_share = -sh1 - sh2;
tracing::info!("adjusted share {adjusted_share:?}");
adjusted_share.serialize(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added serialize_to_slice and deserialize_from_slice methods to Serializable trait (only for tests). I think you may want to use them here

})
.await;

assert_eq!(res0, false, "zero check failed on H1");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do you prefer this syntax over assert!(!res0, "...")?

config.stream_interceptor = Arc::new(MaliciousCheckZeroInterceptor::new());
let world = TestWorld::new_with(&config);
let mut rng = thread_rng();
let v = rng.gen::<Fp32BitPrime>();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this test benefit from using a random value or we can use a constant here to avoid false negatives?

)
.await?;

tracing::info!("reveal ({:?}): left {left:?} right {right:?} from left {share_from_left:?} from right {share_from_right:?}", ctx.role());
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that will spam the output I think similarly to another info! trace above. Lets change it to trace! or remove

@akoshelev
Copy link
Collaborator

What I haven't realized is that this test demonstrates that a malicious helper can break the security by making other helpers accept the result of check zero protocol even when u*v != 0. It is a very neat attack discovered by @andyleiserson:

H1 is malicious, H2, H3 are honest helpers executing check_zero

  • H1, H2 and H3 execute the first part of check_zero protocol - semi-honest multiply of r*v (according to the paper, this is the right thing to do here).
  • as part of this multiply, H2 sends data to H3, H3 to H1 and H1 does not send anything to H2.
  • H1 and H3 move to the reveal phase. H1 because it can do whatever it wants (and it has the shares from multiplication), H3 because from its perspective multiplication is done
  • H3 sends its shares to H2 and H1 and waits for others
  • H1 now can combine the shares of r*v because it has all three of them.

At this point, H1 can craft the response for multiplication to H2 that is still waiting and make the resulting share $\hat{r} = r + a$ equal to 0, completely breaking the security of MAC.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants