multi: implement MuSig2 RPCs and remote signing

This commit is contained in:
Oliver Gugger committed 2022-04-29 11:41:09 +02:00
1 parent 8fc99fba00
commit f7275c7fc4
13 files changed
+3450 -58

No files matched your search

+282
View File
@@ -64,6 +64,62 @@ type SignerClient interface {
//The resulting shared public key is serialized in the compressed format and
//hashed with sha256, resulting in the final key length of 256bit.
DeriveSharedKey(ctx context.Context, in *SharedKeyRequest, opts ...grpc.CallOption) (*SharedKeyResponse, error)
//
//MuSig2CombineKeys (experimental!) is a stateless helper RPC that can be used
//to calculate the combined MuSig2 public key from a list of all participating
//signers' public keys. This RPC is completely stateless and deterministic and
//does not create any signing session. It can be used to determine the Taproot
//public key that should be put in an on-chain output once all public keys are
//known. A signing session is only needed later when that output should be
//_spent_ again.
//
//NOTE: The MuSig2 BIP is not final yet and therefore this API must be
//considered to be HIGHLY EXPERIMENTAL and subject to change in upcoming
//releases. Backward compatibility is not guaranteed!
MuSig2CombineKeys(ctx context.Context, in *MuSig2CombineKeysRequest, opts ...grpc.CallOption) (*MuSig2CombineKeysResponse, error)
//
//MuSig2CreateSession (experimental!) creates a new MuSig2 signing session
//using the local key identified by the key locator. The complete list of all
//public keys of all signing parties must be provided, including the public
//key of the local signing key. If nonces of other parties are already known,
//they can be submitted as well to reduce the number of RPC calls necessary
//later on.
//
//NOTE: The MuSig2 BIP is not final yet and therefore this API must be
//considered to be HIGHLY EXPERIMENTAL and subject to change in upcoming
//releases. Backward compatibility is not guaranteed!
MuSig2CreateSession(ctx context.Context, in *MuSig2SessionRequest, opts ...grpc.CallOption) (*MuSig2SessionResponse, error)
//
//MuSig2RegisterNonces (experimental!) registers one or more public nonces of
//other signing participants for a session identified by its ID. This RPC can
//be called multiple times until all nonces are registered.
//
//NOTE: The MuSig2 BIP is not final yet and therefore this API must be
//considered to be HIGHLY EXPERIMENTAL and subject to change in upcoming
//releases. Backward compatibility is not guaranteed!
MuSig2RegisterNonces(ctx context.Context, in *MuSig2RegisterNoncesRequest, opts ...grpc.CallOption) (*MuSig2RegisterNoncesResponse, error)
//
//MuSig2Sign (experimental!) creates a partial signature using the local
//signing key that was specified when the session was created. This can only
//be called when all public nonces of all participants are known and have been
//registered with the session. If this node isn't responsible for combining
//all the partial signatures, then the cleanup flag should be set, indicating
//that the session can be removed from memory once the signature was produced.
//
//NOTE: The MuSig2 BIP is not final yet and therefore this API must be
//considered to be HIGHLY EXPERIMENTAL and subject to change in upcoming
//releases. Backward compatibility is not guaranteed!
MuSig2Sign(ctx context.Context, in *MuSig2SignRequest, opts ...grpc.CallOption) (*MuSig2SignResponse, error)
//
//MuSig2CombineSig (experimental!) combines the given partial signature(s)
//with the local one, if it already exists. Once a partial signature of all
//participants is registered, the final signature will be combined and
//returned.
//
//NOTE: The MuSig2 BIP is not final yet and therefore this API must be
//considered to be HIGHLY EXPERIMENTAL and subject to change in upcoming
//releases. Backward compatibility is not guaranteed!
MuSig2CombineSig(ctx context.Context, in *MuSig2CombineSigRequest, opts ...grpc.CallOption) (*MuSig2CombineSigResponse, error)
}
type signerClient struct {
@@ -119,6 +175,51 @@ func (c *signerClient) DeriveSharedKey(ctx context.Context, in *SharedKeyRequest
return out, nil
}
func (c *signerClient) MuSig2CombineKeys(ctx context.Context, in *MuSig2CombineKeysRequest, opts ...grpc.CallOption) (*MuSig2CombineKeysResponse, error) {
out := new(MuSig2CombineKeysResponse)
err := c.cc.Invoke(ctx, "/signrpc.Signer/MuSig2CombineKeys", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *signerClient) MuSig2CreateSession(ctx context.Context, in *MuSig2SessionRequest, opts ...grpc.CallOption) (*MuSig2SessionResponse, error) {
out := new(MuSig2SessionResponse)
err := c.cc.Invoke(ctx, "/signrpc.Signer/MuSig2CreateSession", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *signerClient) MuSig2RegisterNonces(ctx context.Context, in *MuSig2RegisterNoncesRequest, opts ...grpc.CallOption) (*MuSig2RegisterNoncesResponse, error) {
out := new(MuSig2RegisterNoncesResponse)
err := c.cc.Invoke(ctx, "/signrpc.Signer/MuSig2RegisterNonces", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *signerClient) MuSig2Sign(ctx context.Context, in *MuSig2SignRequest, opts ...grpc.CallOption) (*MuSig2SignResponse, error) {
out := new(MuSig2SignResponse)
err := c.cc.Invoke(ctx, "/signrpc.Signer/MuSig2Sign", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *signerClient) MuSig2CombineSig(ctx context.Context, in *MuSig2CombineSigRequest, opts ...grpc.CallOption) (*MuSig2CombineSigResponse, error) {
out := new(MuSig2CombineSigResponse)
err := c.cc.Invoke(ctx, "/signrpc.Signer/MuSig2CombineSig", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// SignerServer is the server API for Signer service.
// All implementations must embed UnimplementedSignerServer
// for forward compatibility
@@ -169,6 +270,62 @@ type SignerServer interface {
//The resulting shared public key is serialized in the compressed format and
//hashed with sha256, resulting in the final key length of 256bit.
DeriveSharedKey(context.Context, *SharedKeyRequest) (*SharedKeyResponse, error)
//
//MuSig2CombineKeys (experimental!) is a stateless helper RPC that can be used
//to calculate the combined MuSig2 public key from a list of all participating
//signers' public keys. This RPC is completely stateless and deterministic and
//does not create any signing session. It can be used to determine the Taproot
//public key that should be put in an on-chain output once all public keys are
//known. A signing session is only needed later when that output should be
//_spent_ again.
//
//NOTE: The MuSig2 BIP is not final yet and therefore this API must be
//considered to be HIGHLY EXPERIMENTAL and subject to change in upcoming
//releases. Backward compatibility is not guaranteed!
MuSig2CombineKeys(context.Context, *MuSig2CombineKeysRequest) (*MuSig2CombineKeysResponse, error)
//
//MuSig2CreateSession (experimental!) creates a new MuSig2 signing session
//using the local key identified by the key locator. The complete list of all
//public keys of all signing parties must be provided, including the public
//key of the local signing key. If nonces of other parties are already known,
//they can be submitted as well to reduce the number of RPC calls necessary
//later on.
//
//NOTE: The MuSig2 BIP is not final yet and therefore this API must be
//considered to be HIGHLY EXPERIMENTAL and subject to change in upcoming
//releases. Backward compatibility is not guaranteed!
MuSig2CreateSession(context.Context, *MuSig2SessionRequest) (*MuSig2SessionResponse, error)
//
//MuSig2RegisterNonces (experimental!) registers one or more public nonces of
//other signing participants for a session identified by its ID. This RPC can
//be called multiple times until all nonces are registered.
//
//NOTE: The MuSig2 BIP is not final yet and therefore this API must be
//considered to be HIGHLY EXPERIMENTAL and subject to change in upcoming
//releases. Backward compatibility is not guaranteed!
MuSig2RegisterNonces(context.Context, *MuSig2RegisterNoncesRequest) (*MuSig2RegisterNoncesResponse, error)
//
//MuSig2Sign (experimental!) creates a partial signature using the local
//signing key that was specified when the session was created. This can only
//be called when all public nonces of all participants are known and have been
//registered with the session. If this node isn't responsible for combining
//all the partial signatures, then the cleanup flag should be set, indicating
//that the session can be removed from memory once the signature was produced.
//
//NOTE: The MuSig2 BIP is not final yet and therefore this API must be
//considered to be HIGHLY EXPERIMENTAL and subject to change in upcoming
//releases. Backward compatibility is not guaranteed!
MuSig2Sign(context.Context, *MuSig2SignRequest) (*MuSig2SignResponse, error)
//
//MuSig2CombineSig (experimental!) combines the given partial signature(s)
//with the local one, if it already exists. Once a partial signature of all
//participants is registered, the final signature will be combined and
//returned.
//
//NOTE: The MuSig2 BIP is not final yet and therefore this API must be
//considered to be HIGHLY EXPERIMENTAL and subject to change in upcoming
//releases. Backward compatibility is not guaranteed!
MuSig2CombineSig(context.Context, *MuSig2CombineSigRequest) (*MuSig2CombineSigResponse, error)
mustEmbedUnimplementedSignerServer()
}
@@ -191,6 +348,21 @@ func (UnimplementedSignerServer) VerifyMessage(context.Context, *VerifyMessageRe
func (UnimplementedSignerServer) DeriveSharedKey(context.Context, *SharedKeyRequest) (*SharedKeyResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method DeriveSharedKey not implemented")
}
func (UnimplementedSignerServer) MuSig2CombineKeys(context.Context, *MuSig2CombineKeysRequest) (*MuSig2CombineKeysResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method MuSig2CombineKeys not implemented")
}
func (UnimplementedSignerServer) MuSig2CreateSession(context.Context, *MuSig2SessionRequest) (*MuSig2SessionResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method MuSig2CreateSession not implemented")
}
func (UnimplementedSignerServer) MuSig2RegisterNonces(context.Context, *MuSig2RegisterNoncesRequest) (*MuSig2RegisterNoncesResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method MuSig2RegisterNonces not implemented")
}
func (UnimplementedSignerServer) MuSig2Sign(context.Context, *MuSig2SignRequest) (*MuSig2SignResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method MuSig2Sign not implemented")
}
func (UnimplementedSignerServer) MuSig2CombineSig(context.Context, *MuSig2CombineSigRequest) (*MuSig2CombineSigResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method MuSig2CombineSig not implemented")
}
func (UnimplementedSignerServer) mustEmbedUnimplementedSignerServer() {}
// UnsafeSignerServer may be embedded to opt out of forward compatibility for this service.
@@ -294,6 +466,96 @@ func _Signer_DeriveSharedKey_Handler(srv interface{}, ctx context.Context, dec f
return interceptor(ctx, in, info, handler)
}
func _Signer_MuSig2CombineKeys_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(MuSig2CombineKeysRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(SignerServer).MuSig2CombineKeys(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/signrpc.Signer/MuSig2CombineKeys",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SignerServer).MuSig2CombineKeys(ctx, req.(*MuSig2CombineKeysRequest))
}
return interceptor(ctx, in, info, handler)
}
func _Signer_MuSig2CreateSession_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(MuSig2SessionRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(SignerServer).MuSig2CreateSession(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/signrpc.Signer/MuSig2CreateSession",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SignerServer).MuSig2CreateSession(ctx, req.(*MuSig2SessionRequest))
}
return interceptor(ctx, in, info, handler)
}
func _Signer_MuSig2RegisterNonces_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(MuSig2RegisterNoncesRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(SignerServer).MuSig2RegisterNonces(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/signrpc.Signer/MuSig2RegisterNonces",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SignerServer).MuSig2RegisterNonces(ctx, req.(*MuSig2RegisterNoncesRequest))
}
return interceptor(ctx, in, info, handler)
}
func _Signer_MuSig2Sign_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(MuSig2SignRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(SignerServer).MuSig2Sign(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/signrpc.Signer/MuSig2Sign",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SignerServer).MuSig2Sign(ctx, req.(*MuSig2SignRequest))
}
return interceptor(ctx, in, info, handler)
}
func _Signer_MuSig2CombineSig_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(MuSig2CombineSigRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(SignerServer).MuSig2CombineSig(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/signrpc.Signer/MuSig2CombineSig",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SignerServer).MuSig2CombineSig(ctx, req.(*MuSig2CombineSigRequest))
}
return interceptor(ctx, in, info, handler)
}
// Signer_ServiceDesc is the grpc.ServiceDesc for Signer service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
@@ -321,6 +583,26 @@ var Signer_ServiceDesc = grpc.ServiceDesc{
MethodName: "DeriveSharedKey",
Handler: _Signer_DeriveSharedKey_Handler,
},
{
MethodName: "MuSig2CombineKeys",
Handler: _Signer_MuSig2CombineKeys_Handler,
},
{
MethodName: "MuSig2CreateSession",
Handler: _Signer_MuSig2CreateSession_Handler,
},
{
MethodName: "MuSig2RegisterNonces",
Handler: _Signer_MuSig2RegisterNonces_Handler,
},
{
MethodName: "MuSig2Sign",
Handler: _Signer_MuSig2Sign_Handler,
},
{
MethodName: "MuSig2CombineSig",
Handler: _Signer_MuSig2CombineSig_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "signrpc/signer.proto",