Skip to content

Shamir Secret Sharing over GF(2^8) #7891

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

Merged
merged 15 commits into from
Apr 19, 2025
Merged

Shamir Secret Sharing over GF(2^8) #7891

merged 15 commits into from
Apr 19, 2025

Conversation

andrewjstone
Copy link
Contributor

@andrewjstone andrewjstone commented Mar 28, 2025

Please see the doc comments for details.

@andrewjstone andrewjstone changed the title WIP: Shamir Secret Sharing over GF(2^8) Shamir Secret Sharing over GF(2^8) Mar 31, 2025
@andrewjstone andrewjstone marked this pull request as ready for review March 31, 2025 22:41
Copy link
Contributor

@inickles inickles left a comment

Choose a reason for hiding this comment

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

Primarily just had one comment / question about the API for shamir, the other comments are minor.

///
/// The secret is the concatenation of the y-coordinates at x=0.
pub fn compute_secret(
shares: &[Share],
Copy link
Contributor

Choose a reason for hiding this comment

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

Because it's part of the public API, it looks to me like shares should be behind a secrecry::Secret, considering this it all that's needed to construct the secret, where that only might be the case depending on the caller. Without enforcing that I think it adds potential for "holding it wrong" here. And so I could see an argument for making the underlying data in a public Share be wrapped in a secrecry::Secret.

This of course would have some big implications on the API, and I could imagine the ergonomic implications might have you cursing my name. I wanted to bounce this off you before thinking through all that further.

Thoughts?

Copy link
Contributor Author

@andrewjstone andrewjstone Apr 3, 2025

Choose a reason for hiding this comment

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

I don't think this is necessary. Shares themselves implement ZeroizeOnDrop and this API really shouldn't mandate how the user maintains them as it can indeed introduce serious ergonomic issues. Although not shown in any tests here, Shares are sent across nodes in messages, and must be collated over time. We'd need a mutable secret to store them, and we don't really want to force the collection in which they are stored on a caller. They can store them as values in maps, Vecs, etc... They can put their collection type l in a Secret, or not, but we don't really care about that here. In order to allow this work, we also need to update Secrecy because in the version we are on you can't have a mutable secret and can't build up shares retrieved over the network into a single collection. Also, I'm pretty sure this API would have to become generic over the collections to take a Secret of arbitrary inner type, which I"m definitely loathe to do.

Now, with that said, I actually think this API probably should be changed, except not to take a secret. It should instead take an Iterator<Item = &Share> to allow storage in various collection types without having to collect into a type that can be passed as a slice.

We could also wrap each individual Share in a Secret, but that just means for every damn math function we are constantly calling expose_secret, which will make things harder to read.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Now, with that said, I actually think this API probably should be changed, except not to take a secret. It should instead take an Iterator<Item = &Share> to allow storage in various collection types without having to collect into a type that can be passed as a slice.

Actually doing this may be a mistake also, as they'd still have to be collected to build a ValidatedShares type. I think the best thing to do is to build on top of this library by using it and then make changes over time if they seem reasonable.

andrewjstone added a commit that referenced this pull request Apr 5, 2025
This code builds upon #7859, which itself builds upon #7891. Those
need to be merged in order first.

A `Node` is the sans-io entity driving the trust quorum protocol. This
PR starts the work of creating the `Node` type and coordinating an
initial configuration.

There's a property based test that generates an initial `ReconfigureMsg`
that is then used to call `Node::coordinate_reconfiguration`, which will
internally setup a `CoordinatorState` and create a bunch of messages
to be sent. We verify that a new `PersistentState` is returned and that
messages are sent.

This needs a bit more documentation and testing, so it's still WIP.
andrewjstone added a commit that referenced this pull request Apr 5, 2025
This code builds upon #7859, which itself builds upon #7891. Those
need to be merged in order first.

A `Node` is the sans-io entity driving the trust quorum protocol. This
PR starts the work of creating the `Node` type and coordinating an
initial configuration.

There's a property based test that generates an initial `ReconfigureMsg`
that is then used to call `Node::coordinate_reconfiguration`, which will
internally setup a `CoordinatorState` and create a bunch of messages
to be sent. We verify that a new `PersistentState` is returned and that
messages are sent.

This needs a bit more documentation and testing, so it's still WIP.
@andrewjstone andrewjstone enabled auto-merge (squash) April 18, 2025 23:34
@andrewjstone andrewjstone merged commit 1d3958c into main Apr 19, 2025
18 checks passed
@andrewjstone andrewjstone deleted the ajs/shamir branch April 19, 2025 00:51
andrewjstone added a commit that referenced this pull request Apr 21, 2025
This code builds upon #7859, which itself builds upon #7891. Those need
to be merged in order first.

A `Node` is the sans-io entity driving the trust quorum protocol. This
PR starts the work of creating the `Node` type and coordinating an
initial configuration.

There's a property based test that generates an initial `ReconfigureMsg`
that is then used to call `Node::coordinate_reconfiguration`, which will
internally setup a `CoordinatorState` and create a bunch of messages to
be sent. We verify that a new `PersistentState` is returned and that
messages are sent.

Some of validation code is also tested. We test a subset of error
conditions, but ensure all the error check methods themselves actually
get called among the checks we choose.

---------

Co-authored-by: Rain <[email protected]>
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.

4 participants