-
Notifications
You must be signed in to change notification settings - Fork 45
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
Conversation
There was a problem hiding this 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], |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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. Share
s 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, Share
s 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.
There was a problem hiding this comment.
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.
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.
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.
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]>
Please see the doc comments for details.