-
Notifications
You must be signed in to change notification settings - Fork 13
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
Embed public and private shares into DkgPrivateBegin and DkgEndBegin #98
base: main
Are you sure you want to change the base?
Conversation
c90232f
to
38cf8ee
Compare
556c5dc
to
e78101f
Compare
…messages make embedding of public and private shares configurable reenable start_private_shares test now that embedding is configurable inc major semver for backwards incompatible API changes test modules do not need to be public unless someone is using them externally allow a static mut ref to an atomic variable used for test log initialization; allow many arguments to Signer::new allow many arguments to setup_with_timeouts fmt and code change for rng PR rebase rebase fixes
e78101f
to
a4c33be
Compare
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.
Not done yet. I had started this a review a while ago, figured that I'd post what I had written so far rather than finish the review.
@@ -891,7 +921,9 @@ impl<SignerType: SignerTrait> StateMachine<State, Error> for Signer<SignerType> | |||
} | |||
#[cfg(test)] | |||
/// Test module for signer functionality | |||
pub mod test { | |||
mod test { | |||
use hashbrown::HashMap; |
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.
Can we use the standard library version of HashMap
, generally speaking?
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.
Originally, there was a goal to provide no_std
support, since this is a relatively common use case (see #60) in Rust code generally, and crypto code specifically. Hence the usage of hashbrown
for HashMap
and HashSet
, rand_core
vs rand
, core
for fmt
, etc.
Now that the fire::Coordinator
needs to do timeouts, though, this is no longer possible for the crate as a whole. There is no replacement for std::time::Instant
in core
or alloc
. We could however still make the non-state machine code no_std
.
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.
Oh right.
And we also use Vec
as well. I would think that the simplest path forward to support no_std
is to go through the alloc
crate, which has "replacements" for Vec
but not for HashMap
(I say replacements but I think std
re-exports alloc
types). alloc
does have a replacement for BTreeMap
, which might be a good move too. We've moved to using the BTreeMap
during serialization in sbtc signers so that everything is deterministic, might be worthwhile here as well.
But yeah, if the no_std
version of things is something we want to do, we shouldn't use the std version of HashMap
here, but maybe switching to the BTreeMap
version is the way to go. 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'm definitely on board with switching to BTreeMap where it makes sense. It's more space efficient anyway. Where are you currently running into this? The state machines are like half HashMap
half BTreeMap
, but the rest of the code is pure HashMap
.
Thinking more about no_std
, I looked over p256k1
and realized that it's chock full of std
, over 1k LOC. So until we can move to k256
, I think we should stop worrying about no_std
and just do what's right.
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'm definitely on board with switching to BTreeMap where it makes sense. It's more space efficient anyway. Where are you currently running into this?
It's not an issue that we're running into with WSTS. But we serialize our messages as protobufs before broadcasting them on the network. The protobuf spec doesn't have a canonical serialization, so we've picked one serialization implementation so that things are deterministic and so on, and converting maps to BTreeMap
s before serialization is part of that process. Well, we haven't proved that our specific implementation is deterministic yet (stacks-network/sbtc#1001), but that's the goal.
Thinking more about
no_std
, I looked overp256k1
and realized that it's chock full ofstd
, over 1k LOC. So until we can move tok256
, I think we should stop worrying aboutno_std
and just do what's right.
Yeah this makes sense to me.
I'm not sure where I'd land on the BTreeMap
vs std HashMap
s here. My guess is that users would usually have a small number of signers (maybe hundreds or thousands) but perhaps a large number of keys (thousands or maybe tens of thousands). With just that I'd lean BTreeMap
but I suppose either works. Not sure if it's worth the effort to benchmark though.
No need for any of these changes in this PR, I was just asking. I think I had asked before and forgot what the resolution was.
Is moving to k256
a goal?
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.
Yeah the BTreeMap discussion is def orthogonal to this PR.
k256
is pure Rust so there's definitely some advantages to moving towards it; p256k1
has bindgen and FFI that make upgrading the underlying secp256k1
library difficult. But the performance benefits of p256k1
are significant, especially with the multiexponentiation support.
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.
Oh, is the one added in RustCrypto/elliptic-curves#955, just super slow compared to libsecp256k1?
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.
It's 3x slower. Which is not a deal breaker for sBTC
, and maybe not even for Nakamoto (when they get their coordinator issues sorted out). It was definitely a dealbreaker when DKG was taking 90 minutes, but those days are long gone.
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.
AFAICT k256
is just using precomputed lookup tables for lincomb
, whereas secp256k1
is doing a full Pippenger algo which gives a logarithmic speedup.
https://github.com/RustCrypto/elliptic-curves/blob/master/k256/src/arithmetic/mul.rs#L294
https://github.com/Trust-Machines/p256k1/blob/master/p256k1/_secp256k1/src/ecmult_impl.h#L498
Which makes sense, because p256k1
ecmult
(which uses precomputed tables) is basically the same performance as k256
lincomb
.
This change addresses issues arising from out-of-order messages that may arise when
WSTS
is used in ap2p
network. It adds a config option to theCoordinator
andSigner
state machines, that when enabled embeds theDkgPublicShares
andDkgPrivateShares
messages intoDkgPrivateBegin
andDkgPrivateEnd
.