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

Support cross-shard PRSS in sharded MPC circuits (in memory only for now) #1410

Merged
merged 2 commits into from
Nov 8, 2024

Conversation

akoshelev
Copy link
Collaborator

We ran into an issue where shards need coordinated randomness in more than one protocol:

  • Malicious shuffle needs it to generate MAC keys
  • PRF needs it to generate PRF key to mask the values

At this point I strongly suspect we will need it in more places and the current mitigation is not sustainable. We do simulate key exchange in shuffle and about to in PRF, so I decided to stop the bleeding and implemented coordinated randomness for PRSS.

The only API difference between those two is to use cross-shard PRSS, one would call ShardedContext::cross_shard_prss and shard-scoped PRSS is still available by calling ShardedContext::prss. Both return the same structure, so anything that can be generated with shard-scoped PRSS, can also be generated with cross-shard randomness. It is basically a drop-in replacement, only available for sharded MPC circuits.

Note that this only brings in-memory implementation, but I have implemented 50% of distribution circuit already and it looks pretty straightforward - just generate a key using PRSS and distribute it across shards - it will be used to bootstrap generators on every shard. This will be a separate PR and will take some time to implement - but folks shouldn't be blocked as this change unblocks using the in-memory infrastructure.

We ran into an issue where shards need coordinated randomness in more than one protocol:

* Malicious shuffle needs it to generate MAC keys
* PRF needs it to generate PRF key to mask the values

At this point I strongly suspect we will need it in more places and the current mitigation
is not sustainable. We do simulate key exchange in shuffle and about to in PRF, so I decided
to stop the bleeding and implemented coordinated randomness for PRSS.

The only API difference between those two is to use cross-shard PRSS, one would call
`ShardedContext::cross_shard_prss` and shard-scoped PRSS is still available by calling
`ShardedContext::prss`. Both return the same structure, so anything that can be generated with
shard-scoped PRSS, can also be generated with cross-shard randomness. It is basically a drop-in
replacement, only available for sharded MPC circuits.

Note that this only brings in-memory implementation, but I have implemented 50% of distribution
circuit already and it looks pretty straightforward - just generate a key using PRSS and distribute
it across shards - it will be used to bootstrap generators on every shard. This will be a separate
PR and will take some time to implement - but folks shouldn't be blocked as this change unblocks
using the in-memory infrastructure.
Copy link

codecov bot commented Nov 7, 2024

Codecov Report

Attention: Patch coverage is 84.13793% with 23 lines in your changes missing coverage. Please review.

Project coverage is 93.29%. Comparing base (1e3a417) to head (e6e08af).
Report is 6 commits behind head on main.

Files with missing lines Patch % Lines
ipa-core/src/sharding.rs 16.66% 10 Missing ⚠️
ipa-core/src/protocol/context/dzkp_semi_honest.rs 0.00% 3 Missing ⚠️
ipa-core/src/protocol/context/malicious.rs 0.00% 3 Missing ⚠️
ipa-core/src/protocol/context/semi_honest.rs 50.00% 3 Missing ⚠️
ipa-core/src/bin/helper.rs 0.00% 2 Missing ⚠️
ipa-core/src/helpers/transport/mod.rs 75.00% 1 Missing ⚠️
ipa-core/src/net/transport.rs 83.33% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1410      +/-   ##
==========================================
- Coverage   93.32%   93.29%   -0.03%     
==========================================
  Files         223      224       +1     
  Lines       38533    38602      +69     
==========================================
+ Hits        35960    36014      +54     
- Misses       2573     2588      +15     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link
Member

@eriktaubeneck eriktaubeneck left a comment

Choose a reason for hiding this comment

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

a couple questions on functionality and testing, but overall this looks great.


/// This trait serves the purpose of setting up shard contexts. Each shard shares some
/// global state with others (cross-shard PRSS) and also owns its own state (per-shard PRSS).
/// This construction allows [`ShardWorld`] to
Copy link
Member

Choose a reason for hiding this comment

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

did the end of this get cut off?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

ah, missed that one!

@@ -1329,4 +1317,45 @@ mod tests {
assert_eq!(first_result, second_result);
});
}

#[test]
fn cross_shard_prss() {
Copy link
Member

Choose a reason for hiding this comment

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

is it worth also adding a test to ensure that regular PRSS is not consistent across shards?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Great suggestion, we do already have it. It was implemented with in-memory sharding. Check unique_prss_per_shard test in this file

@@ -211,6 +211,14 @@ impl ShardedContext for Base<'_, Sharded> {
.gateway
.get_shard_receiver(&ChannelId::new(origin, self.gate.clone()))
}

fn cross_shard_prss(&self) -> InstrumentedIndexedSharedRandomness<'_> {
Copy link
Member

Choose a reason for hiding this comment

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

would it make sense to implement this on non-sharded contexts, so that a protocol can use this regardless of sharding (in the non-sharded case, it just acts like normal prss)?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I think this is where Rust type system plays nicely for us - in non-sharded world you should never require cross-shard PRSS and use regular PRSS instead. All sharded circuits we write operate over ShardedContext that will make this API available. Non-sharded MPC won't compile if it tries to use it, which is what we would want imo

Copy link
Member

Choose a reason for hiding this comment

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

got it. so for example with gen_prf_key we'd just have two different implementations, one with Upgradable constraint on C, and another with Upgradable + Sharded? (just to make sure I'm understanding correctly.)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

yea, we will delete non-sharded version anyway, so the only one that we will use is gen_prf_key with C: UpgradableContext + ShardedContext bound. That will provide access to cross_shard_prss

@akoshelev
Copy link
Collaborator Author

I've discussed this PR with @andyleiserson - our conclusion is to merge it to unblock work on hybrid, but there are some things we want to investigate in #1418

@akoshelev akoshelev merged commit eecd25d into private-attribution:main Nov 8, 2024
12 checks passed
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