strangelove-ventures / horcrux

A threshold Tendermint signer
Apache License 2.0
258 stars 81 forks source link

Horcrux should support babylon (threshold BLS in horcrux). #129

Open danbryan opened 1 year ago

danbryan commented 1 year ago

Chains like Babylon use a BLS key to produce a signature at the end of each epoch. Then all of those signatures get together and they are aggregated into 48 bytes to be submitted to Bitcoin. They use BLS because the Ed25519 private keys do not support signature aggregation.

Currently they are instructing their community to add this BLS signature to the priv_validator.json file https://docs.babylonchain.io/docs/testnet/become-validator#2-create-a-bls-key

I believe this prevents operators from using tools like horcrux on babylon chain. Typically if a user runs horcrux, they delete priv_validator.json to ensure no chance of double signing from the threshold signer and local tendermint signer.

@agouin mentioned that we might be able to use this https://pkg.go.dev/github.com/dedis/kyber/sign/tbls to implement threshold BLS in horcrux. It could be built in in addition to the ed25519 signing.

The BLS key could also be separated from the priv_validator.json file. Does it make more sense for us to allow BLS keys, or to encourage separation?

nitronit commented 1 year ago

@danbryan might be slightly off topic. But it would be a very good idea (long-term) to maybe change to kyber and replace the unit410 implementation. Kyber have also implemented the threshold-ed25519 by Stinson et al.

With respect of me being a newbie gopher(!), to do this seamless (and i.e incorporating t-BLS) we would need to refactor the code and be very clear on the "separation of concerns". As of now its 2 or 3 "levels" that are actually using the unit410 implementation of threshold signature. And then 2 leves (i think) on the shares.

I think that the first step should be to factories the responsibilities and define them very clearly:

Something like this: t-validator - responsible for tendermint-layer and potential raft layer. cosigner - responsible for dealings and co-signer communication. signer - responsible for signing, i.e using the signature-algorithm of choose.

In addition it would be interesting to try incorporate some kind of _keystorage - if you might want to use HSM or Vault or something in case its supported by the algorithm to avoid storing the private_keys in plain files.

I been nagging a bit on slack to @agouin on especially the separation of concerns as I find it very hard to understand the codebase sometimes. (Yes, I am the one that found the config passing very very confusing). Also I have even done a very crude MVP fork how this might look. See here: https://github.com/nitronit/horcrux/tree/repackaging

Feel free to reach out if you want to discuss any of the above further.