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

Embed public and private shares into DkgPrivateBegin and DkgEndBegin #98

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

xoloki
Copy link
Collaborator

@xoloki xoloki commented Nov 22, 2024

This change addresses issues arising from out-of-order messages that may arise when WSTS is used in a p2p network. It adds a config option to the Coordinator and Signer state machines, that when enabled embeds the DkgPublicShares and DkgPrivateShares messages into DkgPrivateBegin and DkgPrivateEnd.

@xoloki xoloki force-pushed the embed-public-private-shares branch from c90232f to 38cf8ee Compare December 2, 2024 16:06
@xoloki xoloki changed the title embed public and private shares into DkgPrivateBegin and DkgEndBegin Embed public and private shares into DkgPrivateBegin and DkgEndBegin Dec 2, 2024
@xoloki xoloki requested a review from djordon December 2, 2024 18:24
@xoloki xoloki marked this pull request as ready for review December 2, 2024 18:56
@xoloki xoloki force-pushed the embed-public-private-shares branch from 556c5dc to e78101f Compare December 2, 2024 19:15
…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
@xoloki xoloki force-pushed the embed-public-private-shares branch from e78101f to a4c33be Compare December 6, 2024 16:12
Copy link

@djordon djordon left a 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.

src/state_machine/coordinator/fire.rs Show resolved Hide resolved
src/state_machine/coordinator/fire.rs Show resolved Hide resolved
@@ -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;
Copy link

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?

Copy link
Collaborator Author

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.

Copy link

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?

Copy link
Collaborator Author

@xoloki xoloki Dec 8, 2024

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.

Copy link

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 BTreeMaps 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 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.

Yeah this makes sense to me.

I'm not sure where I'd land on the BTreeMap vs std HashMaps 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?

Copy link
Collaborator Author

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.

Copy link

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?

Copy link
Collaborator Author

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.

Copy link
Collaborator Author

@xoloki xoloki Dec 9, 2024

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.

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