Open Konubinix opened 3 months ago
Thank you, sorry for the delayed response. Any additional changes you'd like to make? Why moving the ot stuff from internal/ to pkg/?
Thank you for your reply,
We use the doerner implementation that defines the structures ConfigReceiver and ConfigSender
At the end of the key generation, both parties need to keep the generated ConfigReceiver (for one party) and the ConfigSender (for the other party) so that they can be used to create signatures in the future. Therefore, we need to serialize them.
In multi-party-sig, we can create a ConfigReceiver if we have instances of Setup, SecretShare, Public and ChainKey, therefore we focused on serializing those types. Among them, only Setup did not expose any way to marshall/unmarshall it.
For that reason, we exposed the ot module, so that we could have access to this Setup structure and implement the Marshall/Unmarshall function. This is what this pull request does.
Our marshalling/unmarshalling code looks like this:
type ConfigReceiverBytes struct {
Setup []byte
SecretShare []byte
Public []byte
ChainKey []byte
}
func MarshallConfigReceiver(configReceiver *doerner.ConfigReceiver) ([]byte, error) {
secretShare, err := configReceiver.SecretShare.MarshalBinary()
if err != nil {
return nil, fmt.Errorf("could not serialize configReceiver.SecretShare: %v", err)
}
public, err := configReceiver.Public.MarshalBinary()
if err != nil {
return nil, fmt.Errorf("could not serialize configReceiver.Public: %v", err)
}
setup, err := configReceiver.Setup.MarshalJSON()
if err != nil {
return nil, fmt.Errorf("could not serialize configReceiver.Setup: %v", err)
}
output := ConfigReceiverBytes{
Setup: setup,
SecretShare: secretShare,
Public: public,
ChainKey: configReceiver.ChainKey,
}
res, err := json.Marshal(output)
if err != nil {
return nil, fmt.Errorf("could not marshall keygen output: %v", err)
}
return res, nil
}
func UnmarshallConfigReceiver(configReceiverRaw []byte) (*doerner.ConfigReceiver, error) {
configReceiverBytes := ConfigReceiverBytes{}
err := json.Unmarshal(configReceiverRaw, &configReceiverBytes)
if err != nil {
return nil, fmt.Errorf("could not unmarshall keygen output: %v", err)
}
secretShare := new(curve.Secp256k1Scalar)
err = secretShare.UnmarshalBinary(configReceiverBytes.SecretShare)
if err != nil {
return nil, fmt.Errorf("could not unmarshal configReceiverBytes.secretShare: %v", err)
}
public := new(curve.Secp256k1Point)
err = public.UnmarshalBinary(configReceiverBytes.Public)
if err != nil {
return nil, fmt.Errorf("could not unmarshal configReceiverBytes.public: %v", err)
}
setup := ot.CorreOTReceiveSetup{}
err = setup.UnmarshalJSON(configReceiverBytes.Setup)
if err != nil {
return nil, fmt.Errorf("could not unmarshal configReceiverBytes.setup: %v", err)
}
configReceiver := doerner.ConfigReceiver{
Setup: &setup,
SecretShare: secretShare,
Public: public,
ChainKey: configReceiverBytes.ChainKey,
}
return &configReceiver, nil
}
We have not gone to production yet, but run a lot keygen and signatures as part of our tests and so far, we have not had any issue yet. Thus, we don't need to add more code.
In my company, we needed to persist the result of the doerner18 dkg so that we can sign later on.
To do so, we needed to be able to serialize the Setup generated during the dkg.
This pull requests makes this possible.
I assume that this pull request is far from being ready for merge, but I'm starting the conversation and hoping that you will point me to the changes to be made to eventually be able to merge this upstream.