mirror of
https://github.com/SwingbyProtocol/tss-lib.git
synced 2026-01-09 13:57:58 -05:00
Adding identification of aborts per section 4.1 of the paper. A pair of ECDSA keys is created in round 1 for player authentication. It signs the Paillier public key first. It then signs the shares in round 2. In case the Feldman check fails in round 3, evidence is broadcasted. Round 4 is now split into normal logic and handling an abort. When handling the abort, an independent player (not the plaintiff, not the accused one) will re-verify the signature of the share and re-check the Feldman shares. The outcome of the abort identification may indeed blame the accused party if the Feldman check fails, or else it may blame the plaintiff for trying to frame the accused party.
This commit is contained in:
@@ -43,8 +43,8 @@ type KGRound1Message struct {
|
||||
PaillierN []byte `protobuf:"bytes,2,opt,name=paillier_n,json=paillierN,proto3" json:"paillier_n,omitempty"`
|
||||
AuthenticationEcdsaPublicKeyX []byte `protobuf:"bytes,3,opt,name=authentication_ecdsa_public_key_x,json=authenticationEcdsaPublicKeyX,proto3" json:"authentication_ecdsa_public_key_x,omitempty"`
|
||||
AuthenticationEcdsaPublicKeyY []byte `protobuf:"bytes,4,opt,name=authentication_ecdsa_public_key_y,json=authenticationEcdsaPublicKeyY,proto3" json:"authentication_ecdsa_public_key_y,omitempty"`
|
||||
AuthenticationEcdsaSigR []byte `protobuf:"bytes,5,opt,name=authentication_ecdsa_sig_r,json=authenticationEcdsaSigR,proto3" json:"authentication_ecdsa_sig_r,omitempty"`
|
||||
AuthenticationEcdsaSigS []byte `protobuf:"bytes,6,opt,name=authentication_ecdsa_sig_s,json=authenticationEcdsaSigS,proto3" json:"authentication_ecdsa_sig_s,omitempty"`
|
||||
AuthenticationPaillierSigR []byte `protobuf:"bytes,5,opt,name=authentication_paillier_sig_r,json=authenticationPaillierSigR,proto3" json:"authentication_paillier_sig_r,omitempty"`
|
||||
AuthenticationPaillierSigS []byte `protobuf:"bytes,6,opt,name=authentication_paillier_sig_s,json=authenticationPaillierSigS,proto3" json:"authentication_paillier_sig_s,omitempty"`
|
||||
NTilde []byte `protobuf:"bytes,7,opt,name=n_tilde,json=nTilde,proto3" json:"n_tilde,omitempty"`
|
||||
H1 []byte `protobuf:"bytes,8,opt,name=h1,proto3" json:"h1,omitempty"`
|
||||
H2 []byte `protobuf:"bytes,9,opt,name=h2,proto3" json:"h2,omitempty"`
|
||||
@@ -114,16 +114,16 @@ func (x *KGRound1Message) GetAuthenticationEcdsaPublicKeyY() []byte {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *KGRound1Message) GetAuthenticationEcdsaSigR() []byte {
|
||||
func (x *KGRound1Message) GetAuthenticationPaillierSigR() []byte {
|
||||
if x != nil {
|
||||
return x.AuthenticationEcdsaSigR
|
||||
return x.AuthenticationPaillierSigR
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *KGRound1Message) GetAuthenticationEcdsaSigS() []byte {
|
||||
func (x *KGRound1Message) GetAuthenticationPaillierSigS() []byte {
|
||||
if x != nil {
|
||||
return x.AuthenticationEcdsaSigS
|
||||
return x.AuthenticationPaillierSigS
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -356,13 +356,174 @@ func (x *KGRound3Message) GetProofXiT() []byte {
|
||||
return nil
|
||||
}
|
||||
|
||||
type VSSShareWithAuthSigMessage struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
VssThreshold uint32 `protobuf:"varint,1,opt,name=vss_threshold,json=vssThreshold,proto3" json:"vss_threshold,omitempty"`
|
||||
VssId []byte `protobuf:"bytes,2,opt,name=vss_id,json=vssId,proto3" json:"vss_id,omitempty"`
|
||||
VssSigma []byte `protobuf:"bytes,3,opt,name=vss_sigma,json=vssSigma,proto3" json:"vss_sigma,omitempty"`
|
||||
AccusedParty uint32 `protobuf:"varint,4,opt,name=accused_party,json=accusedParty,proto3" json:"accused_party,omitempty"`
|
||||
AuthSigPk *common.ECPoint `protobuf:"bytes,5,opt,name=auth_sig_pk,json=authSigPk,proto3" json:"auth_sig_pk,omitempty"`
|
||||
AuthEcdsaSignatureR []byte `protobuf:"bytes,6,opt,name=authEcdsaSignature_r,json=authEcdsaSignatureR,proto3" json:"authEcdsaSignature_r,omitempty"`
|
||||
AuthEcdsaSignatureS []byte `protobuf:"bytes,7,opt,name=authEcdsaSignature_s,json=authEcdsaSignatureS,proto3" json:"authEcdsaSignature_s,omitempty"`
|
||||
KGDj [][]byte `protobuf:"bytes,8,rep,name=KGDj,proto3" json:"KGDj,omitempty"`
|
||||
}
|
||||
|
||||
func (x *VSSShareWithAuthSigMessage) Reset() {
|
||||
*x = VSSShareWithAuthSigMessage{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_protob_ecdsa_keygen_proto_msgTypes[4]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *VSSShareWithAuthSigMessage) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*VSSShareWithAuthSigMessage) ProtoMessage() {}
|
||||
|
||||
func (x *VSSShareWithAuthSigMessage) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_protob_ecdsa_keygen_proto_msgTypes[4]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use VSSShareWithAuthSigMessage.ProtoReflect.Descriptor instead.
|
||||
func (*VSSShareWithAuthSigMessage) Descriptor() ([]byte, []int) {
|
||||
return file_protob_ecdsa_keygen_proto_rawDescGZIP(), []int{4}
|
||||
}
|
||||
|
||||
func (x *VSSShareWithAuthSigMessage) GetVssThreshold() uint32 {
|
||||
if x != nil {
|
||||
return x.VssThreshold
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *VSSShareWithAuthSigMessage) GetVssId() []byte {
|
||||
if x != nil {
|
||||
return x.VssId
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *VSSShareWithAuthSigMessage) GetVssSigma() []byte {
|
||||
if x != nil {
|
||||
return x.VssSigma
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *VSSShareWithAuthSigMessage) GetAccusedParty() uint32 {
|
||||
if x != nil {
|
||||
return x.AccusedParty
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *VSSShareWithAuthSigMessage) GetAuthSigPk() *common.ECPoint {
|
||||
if x != nil {
|
||||
return x.AuthSigPk
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *VSSShareWithAuthSigMessage) GetAuthEcdsaSignatureR() []byte {
|
||||
if x != nil {
|
||||
return x.AuthEcdsaSignatureR
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *VSSShareWithAuthSigMessage) GetAuthEcdsaSignatureS() []byte {
|
||||
if x != nil {
|
||||
return x.AuthEcdsaSignatureS
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *VSSShareWithAuthSigMessage) GetKGDj() [][]byte {
|
||||
if x != nil {
|
||||
return x.KGDj
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//
|
||||
// Represents a BROADCAST message sent to each party during Round 3 of the ECDSA TSS keygen protocol
|
||||
// when in abort mode.
|
||||
type KGRound3MessageAbortMode struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
PlaintiffParty uint32 `protobuf:"varint,1,opt,name=plaintiff_party,json=plaintiffParty,proto3" json:"plaintiff_party,omitempty"`
|
||||
SuspiciousVsss []*VSSShareWithAuthSigMessage `protobuf:"bytes,2,rep,name=suspicious_vsss,json=suspiciousVsss,proto3" json:"suspicious_vsss,omitempty"`
|
||||
}
|
||||
|
||||
func (x *KGRound3MessageAbortMode) Reset() {
|
||||
*x = KGRound3MessageAbortMode{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_protob_ecdsa_keygen_proto_msgTypes[5]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *KGRound3MessageAbortMode) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*KGRound3MessageAbortMode) ProtoMessage() {}
|
||||
|
||||
func (x *KGRound3MessageAbortMode) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_protob_ecdsa_keygen_proto_msgTypes[5]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use KGRound3MessageAbortMode.ProtoReflect.Descriptor instead.
|
||||
func (*KGRound3MessageAbortMode) Descriptor() ([]byte, []int) {
|
||||
return file_protob_ecdsa_keygen_proto_rawDescGZIP(), []int{5}
|
||||
}
|
||||
|
||||
func (x *KGRound3MessageAbortMode) GetPlaintiffParty() uint32 {
|
||||
if x != nil {
|
||||
return x.PlaintiffParty
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *KGRound3MessageAbortMode) GetSuspiciousVsss() []*VSSShareWithAuthSigMessage {
|
||||
if x != nil {
|
||||
return x.SuspiciousVsss
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var File_protob_ecdsa_keygen_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_protob_ecdsa_keygen_proto_rawDesc = []byte{
|
||||
0x0a, 0x19, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x2f, 0x65, 0x63, 0x64, 0x73, 0x61, 0x2d, 0x6b,
|
||||
0x65, 0x79, 0x67, 0x65, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x13, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x62, 0x2f, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x22, 0xc3, 0x04, 0x0a, 0x0f, 0x4b, 0x47, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x31, 0x4d, 0x65, 0x73,
|
||||
0x22, 0xcf, 0x04, 0x0a, 0x0f, 0x4b, 0x47, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x31, 0x4d, 0x65, 0x73,
|
||||
0x73, 0x61, 0x67, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65,
|
||||
0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74,
|
||||
0x6d, 0x65, 0x6e, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x61, 0x69, 0x6c, 0x6c, 0x69, 0x65, 0x72,
|
||||
@@ -376,55 +537,84 @@ var file_protob_ecdsa_keygen_proto_rawDesc = []byte{
|
||||
0x65, 0x63, 0x64, 0x73, 0x61, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79,
|
||||
0x5f, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x1d, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e,
|
||||
0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x63, 0x64, 0x73, 0x61, 0x50, 0x75, 0x62,
|
||||
0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x59, 0x12, 0x3b, 0x0a, 0x1a, 0x61, 0x75, 0x74, 0x68, 0x65,
|
||||
0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x63, 0x64, 0x73, 0x61, 0x5f,
|
||||
0x73, 0x69, 0x67, 0x5f, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x17, 0x61, 0x75, 0x74,
|
||||
0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x63, 0x64, 0x73, 0x61,
|
||||
0x53, 0x69, 0x67, 0x52, 0x12, 0x3b, 0x0a, 0x1a, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69,
|
||||
0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x63, 0x64, 0x73, 0x61, 0x5f, 0x73, 0x69, 0x67,
|
||||
0x5f, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x17, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e,
|
||||
0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x63, 0x64, 0x73, 0x61, 0x53, 0x69, 0x67,
|
||||
0x53, 0x12, 0x17, 0x0a, 0x07, 0x6e, 0x5f, 0x74, 0x69, 0x6c, 0x64, 0x65, 0x18, 0x07, 0x20, 0x01,
|
||||
0x28, 0x0c, 0x52, 0x06, 0x6e, 0x54, 0x69, 0x6c, 0x64, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x68, 0x31,
|
||||
0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x68, 0x31, 0x12, 0x0e, 0x0a, 0x02, 0x68, 0x32,
|
||||
0x18, 0x09, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x68, 0x32, 0x12, 0x1d, 0x0a, 0x0a, 0x64, 0x6c,
|
||||
0x6e, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x5f, 0x31, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x09,
|
||||
0x64, 0x6c, 0x6e, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x31, 0x12, 0x1d, 0x0a, 0x0a, 0x64, 0x6c, 0x6e,
|
||||
0x70, 0x72, 0x6f, 0x6f, 0x66, 0x5f, 0x32, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x09, 0x64,
|
||||
0x6c, 0x6e, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x32, 0x12, 0x2d, 0x0a, 0x13, 0x70, 0x72, 0x6f, 0x6f,
|
||||
0x66, 0x5f, 0x6e, 0x5f, 0x73, 0x71, 0x75, 0x61, 0x72, 0x65, 0x5f, 0x66, 0x72, 0x65, 0x65, 0x18,
|
||||
0x0c, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x10, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x4e, 0x53, 0x71, 0x75,
|
||||
0x61, 0x72, 0x65, 0x46, 0x72, 0x65, 0x65, 0x12, 0x3d, 0x0a, 0x1c, 0x72, 0x61, 0x6e, 0x64, 0x5f,
|
||||
0x69, 0x6e, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x5f, 0x6e, 0x5f, 0x73, 0x71, 0x75, 0x61,
|
||||
0x72, 0x65, 0x5f, 0x66, 0x72, 0x65, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x17, 0x72,
|
||||
0x61, 0x6e, 0x64, 0x49, 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x4e, 0x53, 0x71, 0x75, 0x61,
|
||||
0x72, 0x65, 0x46, 0x72, 0x65, 0x65, 0x22, 0xa2, 0x01, 0x0a, 0x10, 0x4b, 0x47, 0x52, 0x6f, 0x75,
|
||||
0x6e, 0x64, 0x32, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x31, 0x12, 0x14, 0x0a, 0x05, 0x73,
|
||||
0x68, 0x61, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72,
|
||||
0x65, 0x12, 0x3b, 0x0a, 0x1a, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74,
|
||||
0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x63, 0x64, 0x73, 0x61, 0x5f, 0x73, 0x69, 0x67, 0x5f, 0x72, 0x18,
|
||||
0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x17, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63,
|
||||
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x63, 0x64, 0x73, 0x61, 0x53, 0x69, 0x67, 0x52, 0x12, 0x3b,
|
||||
0x0a, 0x1a, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x5f, 0x65, 0x63, 0x64, 0x73, 0x61, 0x5f, 0x73, 0x69, 0x67, 0x5f, 0x73, 0x18, 0x03, 0x20, 0x01,
|
||||
0x28, 0x0c, 0x52, 0x17, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69,
|
||||
0x6f, 0x6e, 0x45, 0x63, 0x64, 0x73, 0x61, 0x53, 0x69, 0x67, 0x53, 0x22, 0x37, 0x0a, 0x10, 0x4b,
|
||||
0x47, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x32, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x32, 0x12,
|
||||
0x23, 0x0a, 0x0d, 0x64, 0x65, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74,
|
||||
0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0c, 0x64, 0x65, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74,
|
||||
0x6d, 0x65, 0x6e, 0x74, 0x22, 0x86, 0x01, 0x0a, 0x0f, 0x4b, 0x47, 0x52, 0x6f, 0x75, 0x6e, 0x64,
|
||||
0x33, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x70, 0x61, 0x69, 0x6c,
|
||||
0x6c, 0x69, 0x65, 0x72, 0x5f, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c,
|
||||
0x52, 0x0d, 0x70, 0x61, 0x69, 0x6c, 0x6c, 0x69, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x12,
|
||||
0x2e, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x5f, 0x78, 0x69, 0x5f, 0x61, 0x6c, 0x70, 0x68,
|
||||
0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x45, 0x43, 0x50, 0x6f, 0x69, 0x6e,
|
||||
0x74, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x58, 0x69, 0x41, 0x6c, 0x70, 0x68, 0x61, 0x12,
|
||||
0x1c, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x5f, 0x78, 0x69, 0x5f, 0x74, 0x18, 0x03, 0x20,
|
||||
0x01, 0x28, 0x0c, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x58, 0x69, 0x54, 0x42, 0x2f, 0x5a,
|
||||
0x2d, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62, 0x69, 0x6e, 0x61,
|
||||
0x6e, 0x63, 0x65, 0x2d, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2f, 0x74, 0x73, 0x73, 0x2d, 0x6c, 0x69,
|
||||
0x62, 0x2f, 0x65, 0x63, 0x64, 0x73, 0x61, 0x2f, 0x6b, 0x65, 0x79, 0x67, 0x65, 0x6e, 0x62, 0x06,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x59, 0x12, 0x41, 0x0a, 0x1d, 0x61, 0x75, 0x74, 0x68, 0x65,
|
||||
0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x61, 0x69, 0x6c, 0x6c, 0x69,
|
||||
0x65, 0x72, 0x5f, 0x73, 0x69, 0x67, 0x5f, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x1a,
|
||||
0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61,
|
||||
0x69, 0x6c, 0x6c, 0x69, 0x65, 0x72, 0x53, 0x69, 0x67, 0x52, 0x12, 0x41, 0x0a, 0x1d, 0x61, 0x75,
|
||||
0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x61, 0x69,
|
||||
0x6c, 0x6c, 0x69, 0x65, 0x72, 0x5f, 0x73, 0x69, 0x67, 0x5f, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28,
|
||||
0x0c, 0x52, 0x1a, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
|
||||
0x6e, 0x50, 0x61, 0x69, 0x6c, 0x6c, 0x69, 0x65, 0x72, 0x53, 0x69, 0x67, 0x53, 0x12, 0x17, 0x0a,
|
||||
0x07, 0x6e, 0x5f, 0x74, 0x69, 0x6c, 0x64, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06,
|
||||
0x6e, 0x54, 0x69, 0x6c, 0x64, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x68, 0x31, 0x18, 0x08, 0x20, 0x01,
|
||||
0x28, 0x0c, 0x52, 0x02, 0x68, 0x31, 0x12, 0x0e, 0x0a, 0x02, 0x68, 0x32, 0x18, 0x09, 0x20, 0x01,
|
||||
0x28, 0x0c, 0x52, 0x02, 0x68, 0x32, 0x12, 0x1d, 0x0a, 0x0a, 0x64, 0x6c, 0x6e, 0x70, 0x72, 0x6f,
|
||||
0x6f, 0x66, 0x5f, 0x31, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x09, 0x64, 0x6c, 0x6e, 0x70,
|
||||
0x72, 0x6f, 0x6f, 0x66, 0x31, 0x12, 0x1d, 0x0a, 0x0a, 0x64, 0x6c, 0x6e, 0x70, 0x72, 0x6f, 0x6f,
|
||||
0x66, 0x5f, 0x32, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x09, 0x64, 0x6c, 0x6e, 0x70, 0x72,
|
||||
0x6f, 0x6f, 0x66, 0x32, 0x12, 0x2d, 0x0a, 0x13, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x5f, 0x6e, 0x5f,
|
||||
0x73, 0x71, 0x75, 0x61, 0x72, 0x65, 0x5f, 0x66, 0x72, 0x65, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28,
|
||||
0x0c, 0x52, 0x10, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x4e, 0x53, 0x71, 0x75, 0x61, 0x72, 0x65, 0x46,
|
||||
0x72, 0x65, 0x65, 0x12, 0x3d, 0x0a, 0x1c, 0x72, 0x61, 0x6e, 0x64, 0x5f, 0x69, 0x6e, 0x74, 0x5f,
|
||||
0x70, 0x72, 0x6f, 0x6f, 0x66, 0x5f, 0x6e, 0x5f, 0x73, 0x71, 0x75, 0x61, 0x72, 0x65, 0x5f, 0x66,
|
||||
0x72, 0x65, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x17, 0x72, 0x61, 0x6e, 0x64, 0x49,
|
||||
0x6e, 0x74, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x4e, 0x53, 0x71, 0x75, 0x61, 0x72, 0x65, 0x46, 0x72,
|
||||
0x65, 0x65, 0x22, 0xa2, 0x01, 0x0a, 0x10, 0x4b, 0x47, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x32, 0x4d,
|
||||
0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x31, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x65,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x65, 0x12, 0x3b, 0x0a,
|
||||
0x1a, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f,
|
||||
0x65, 0x63, 0x64, 0x73, 0x61, 0x5f, 0x73, 0x69, 0x67, 0x5f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28,
|
||||
0x0c, 0x52, 0x17, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
|
||||
0x6e, 0x45, 0x63, 0x64, 0x73, 0x61, 0x53, 0x69, 0x67, 0x52, 0x12, 0x3b, 0x0a, 0x1a, 0x61, 0x75,
|
||||
0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x63, 0x64,
|
||||
0x73, 0x61, 0x5f, 0x73, 0x69, 0x67, 0x5f, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x17,
|
||||
0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x63,
|
||||
0x64, 0x73, 0x61, 0x53, 0x69, 0x67, 0x53, 0x22, 0x37, 0x0a, 0x10, 0x4b, 0x47, 0x52, 0x6f, 0x75,
|
||||
0x6e, 0x64, 0x32, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x32, 0x12, 0x23, 0x0a, 0x0d, 0x64,
|
||||
0x65, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x03,
|
||||
0x28, 0x0c, 0x52, 0x0c, 0x64, 0x65, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74,
|
||||
0x22, 0x86, 0x01, 0x0a, 0x0f, 0x4b, 0x47, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x33, 0x4d, 0x65, 0x73,
|
||||
0x73, 0x61, 0x67, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x70, 0x61, 0x69, 0x6c, 0x6c, 0x69, 0x65, 0x72,
|
||||
0x5f, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0d, 0x70, 0x61,
|
||||
0x69, 0x6c, 0x6c, 0x69, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x12, 0x2e, 0x0a, 0x0e, 0x70,
|
||||
0x72, 0x6f, 0x6f, 0x66, 0x5f, 0x78, 0x69, 0x5f, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x18, 0x02, 0x20,
|
||||
0x01, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x45, 0x43, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x0c, 0x70,
|
||||
0x72, 0x6f, 0x6f, 0x66, 0x58, 0x69, 0x41, 0x6c, 0x70, 0x68, 0x61, 0x12, 0x1c, 0x0a, 0x0a, 0x70,
|
||||
0x72, 0x6f, 0x6f, 0x66, 0x5f, 0x78, 0x69, 0x5f, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52,
|
||||
0x08, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x58, 0x69, 0x54, 0x22, 0xbe, 0x02, 0x0a, 0x1a, 0x56, 0x53,
|
||||
0x53, 0x53, 0x68, 0x61, 0x72, 0x65, 0x57, 0x69, 0x74, 0x68, 0x41, 0x75, 0x74, 0x68, 0x53, 0x69,
|
||||
0x67, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x76, 0x73, 0x73, 0x5f,
|
||||
0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52,
|
||||
0x0c, 0x76, 0x73, 0x73, 0x54, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x12, 0x15, 0x0a,
|
||||
0x06, 0x76, 0x73, 0x73, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76,
|
||||
0x73, 0x73, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x76, 0x73, 0x73, 0x5f, 0x73, 0x69, 0x67, 0x6d,
|
||||
0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x76, 0x73, 0x73, 0x53, 0x69, 0x67, 0x6d,
|
||||
0x61, 0x12, 0x23, 0x0a, 0x0d, 0x61, 0x63, 0x63, 0x75, 0x73, 0x65, 0x64, 0x5f, 0x70, 0x61, 0x72,
|
||||
0x74, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x61, 0x63, 0x63, 0x75, 0x73, 0x65,
|
||||
0x64, 0x50, 0x61, 0x72, 0x74, 0x79, 0x12, 0x28, 0x0a, 0x0b, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x73,
|
||||
0x69, 0x67, 0x5f, 0x70, 0x6b, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x45, 0x43,
|
||||
0x50, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x09, 0x61, 0x75, 0x74, 0x68, 0x53, 0x69, 0x67, 0x50, 0x6b,
|
||||
0x12, 0x31, 0x0a, 0x14, 0x61, 0x75, 0x74, 0x68, 0x45, 0x63, 0x64, 0x73, 0x61, 0x53, 0x69, 0x67,
|
||||
0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x13,
|
||||
0x61, 0x75, 0x74, 0x68, 0x45, 0x63, 0x64, 0x73, 0x61, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75,
|
||||
0x72, 0x65, 0x52, 0x12, 0x31, 0x0a, 0x14, 0x61, 0x75, 0x74, 0x68, 0x45, 0x63, 0x64, 0x73, 0x61,
|
||||
0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28,
|
||||
0x0c, 0x52, 0x13, 0x61, 0x75, 0x74, 0x68, 0x45, 0x63, 0x64, 0x73, 0x61, 0x53, 0x69, 0x67, 0x6e,
|
||||
0x61, 0x74, 0x75, 0x72, 0x65, 0x53, 0x12, 0x12, 0x0a, 0x04, 0x4b, 0x47, 0x44, 0x6a, 0x18, 0x08,
|
||||
0x20, 0x03, 0x28, 0x0c, 0x52, 0x04, 0x4b, 0x47, 0x44, 0x6a, 0x22, 0x89, 0x01, 0x0a, 0x18, 0x4b,
|
||||
0x47, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x33, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x41, 0x62,
|
||||
0x6f, 0x72, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x70, 0x6c, 0x61, 0x69, 0x6e,
|
||||
0x74, 0x69, 0x66, 0x66, 0x5f, 0x70, 0x61, 0x72, 0x74, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d,
|
||||
0x52, 0x0e, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x74, 0x69, 0x66, 0x66, 0x50, 0x61, 0x72, 0x74, 0x79,
|
||||
0x12, 0x44, 0x0a, 0x0f, 0x73, 0x75, 0x73, 0x70, 0x69, 0x63, 0x69, 0x6f, 0x75, 0x73, 0x5f, 0x76,
|
||||
0x73, 0x73, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x56, 0x53, 0x53, 0x53,
|
||||
0x68, 0x61, 0x72, 0x65, 0x57, 0x69, 0x74, 0x68, 0x41, 0x75, 0x74, 0x68, 0x53, 0x69, 0x67, 0x4d,
|
||||
0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x0e, 0x73, 0x75, 0x73, 0x70, 0x69, 0x63, 0x69, 0x6f,
|
||||
0x75, 0x73, 0x56, 0x73, 0x73, 0x73, 0x42, 0x2f, 0x5a, 0x2d, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62,
|
||||
0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62, 0x69, 0x6e, 0x61, 0x6e, 0x63, 0x65, 0x2d, 0x63, 0x68, 0x61,
|
||||
0x69, 0x6e, 0x2f, 0x74, 0x73, 0x73, 0x2d, 0x6c, 0x69, 0x62, 0x2f, 0x65, 0x63, 0x64, 0x73, 0x61,
|
||||
0x2f, 0x6b, 0x65, 0x79, 0x67, 0x65, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -439,21 +629,25 @@ func file_protob_ecdsa_keygen_proto_rawDescGZIP() []byte {
|
||||
return file_protob_ecdsa_keygen_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_protob_ecdsa_keygen_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
|
||||
var file_protob_ecdsa_keygen_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
|
||||
var file_protob_ecdsa_keygen_proto_goTypes = []interface{}{
|
||||
(*KGRound1Message)(nil), // 0: KGRound1Message
|
||||
(*KGRound2Message1)(nil), // 1: KGRound2Message1
|
||||
(*KGRound2Message2)(nil), // 2: KGRound2Message2
|
||||
(*KGRound3Message)(nil), // 3: KGRound3Message
|
||||
(*common.ECPoint)(nil), // 4: ECPoint
|
||||
(*KGRound1Message)(nil), // 0: KGRound1Message
|
||||
(*KGRound2Message1)(nil), // 1: KGRound2Message1
|
||||
(*KGRound2Message2)(nil), // 2: KGRound2Message2
|
||||
(*KGRound3Message)(nil), // 3: KGRound3Message
|
||||
(*VSSShareWithAuthSigMessage)(nil), // 4: VSSShareWithAuthSigMessage
|
||||
(*KGRound3MessageAbortMode)(nil), // 5: KGRound3MessageAbortMode
|
||||
(*common.ECPoint)(nil), // 6: ECPoint
|
||||
}
|
||||
var file_protob_ecdsa_keygen_proto_depIdxs = []int32{
|
||||
4, // 0: KGRound3Message.proof_xi_alpha:type_name -> ECPoint
|
||||
1, // [1:1] is the sub-list for method output_type
|
||||
1, // [1:1] is the sub-list for method input_type
|
||||
1, // [1:1] is the sub-list for extension type_name
|
||||
1, // [1:1] is the sub-list for extension extendee
|
||||
0, // [0:1] is the sub-list for field type_name
|
||||
6, // 0: KGRound3Message.proof_xi_alpha:type_name -> ECPoint
|
||||
6, // 1: VSSShareWithAuthSigMessage.auth_sig_pk:type_name -> ECPoint
|
||||
4, // 2: KGRound3MessageAbortMode.suspicious_vsss:type_name -> VSSShareWithAuthSigMessage
|
||||
3, // [3:3] is the sub-list for method output_type
|
||||
3, // [3:3] is the sub-list for method input_type
|
||||
3, // [3:3] is the sub-list for extension type_name
|
||||
3, // [3:3] is the sub-list for extension extendee
|
||||
0, // [0:3] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_protob_ecdsa_keygen_proto_init() }
|
||||
@@ -510,6 +704,30 @@ func file_protob_ecdsa_keygen_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_protob_ecdsa_keygen_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*VSSShareWithAuthSigMessage); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_protob_ecdsa_keygen_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*KGRound3MessageAbortMode); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
@@ -517,7 +735,7 @@ func file_protob_ecdsa_keygen_proto_init() {
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_protob_ecdsa_keygen_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 4,
|
||||
NumMessages: 6,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
|
||||
@@ -51,9 +51,16 @@ type (
|
||||
vs vss.Vs
|
||||
shares vss.Shares
|
||||
deCommitPolyG cmt.HashDeCommitment
|
||||
abortTriggers []AbortTrigger
|
||||
}
|
||||
)
|
||||
|
||||
type AbortTrigger int
|
||||
|
||||
const (
|
||||
FeldmanCheckFailure AbortTrigger = iota
|
||||
)
|
||||
|
||||
// Exported, used in `tss` client
|
||||
func NewLocalParty(
|
||||
params *tss.Parameters,
|
||||
@@ -141,6 +148,8 @@ func (p *LocalParty) StoreMessage(msg tss.ParsedMessage) (bool, *tss.Error) {
|
||||
p.temp.kgRound2Message2s[fromPIdx] = msg
|
||||
case *KGRound3Message:
|
||||
p.temp.kgRound3Messages[fromPIdx] = msg
|
||||
case *KGRound3MessageAbortMode:
|
||||
p.temp.kgRound3Messages[fromPIdx] = msg
|
||||
default: // unrecognised message, just ignore!
|
||||
common.Logger.Warnf("unrecognised message ignored: %v", msg)
|
||||
return false, nil
|
||||
|
||||
@@ -14,9 +14,12 @@ import (
|
||||
"math/big"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/go-multierror"
|
||||
"github.com/ipfs/go-log"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
@@ -168,6 +171,184 @@ func TestBadMessageCulprits(t *testing.T) {
|
||||
err2.Error())
|
||||
}
|
||||
|
||||
// The function will change the Feldman shares at the end of round 1
|
||||
// making party 1 send a bad share to party 0
|
||||
func SharedPartyUpdaterInjectingFeldmanError(party tss.Party, msg tss.Message, errCh chan<- *tss.Error) {
|
||||
// do not send a message from this party back to itself
|
||||
if party.PartyID() == msg.GetFrom() {
|
||||
return
|
||||
}
|
||||
bz, _, err := msg.WireBytes()
|
||||
if err != nil {
|
||||
errCh <- party.WrapError(err)
|
||||
return
|
||||
}
|
||||
pMsg, err := tss.ParseWireMessage(bz, msg.GetFrom(), msg.IsBroadcast())
|
||||
if err != nil {
|
||||
errCh <- party.WrapError(err)
|
||||
return
|
||||
}
|
||||
|
||||
// Intercepting a round 1 broadcast message and changing a share
|
||||
// Making party 1 send bad share to party 0 in round 2
|
||||
if "KGRound1Message" == msg.Type() && party.PartyID().Index == 1 {
|
||||
if msg.GetFrom().Index != 1 && msg.IsBroadcast() {
|
||||
common.Logger.Debugf("current party: %v", party.PartyID())
|
||||
round := party.FirstRound().(*round1)
|
||||
retries := 0
|
||||
for (round.temp.shares == nil || len(round.temp.shares) < 1) && retries < 10 {
|
||||
common.Logger.Debug("waiting for parties to start...")
|
||||
time.Sleep(2 * time.Second)
|
||||
retries++
|
||||
}
|
||||
|
||||
// injecting a (probably) incorrect share
|
||||
round.temp.shares[0].Share = new(big.Int).Add(round.temp.shares[0].Share, big.NewInt(1))
|
||||
}
|
||||
}
|
||||
|
||||
if _, err := party.Update(pMsg); err != nil {
|
||||
errCh <- err
|
||||
}
|
||||
}
|
||||
|
||||
func TestIdentifiableAbortFeldmanShareFail(t *testing.T) {
|
||||
setUp("info")
|
||||
|
||||
threshold := testThreshold
|
||||
fixtures, pIDs, err := LoadKeygenTestFixtures(testParticipants)
|
||||
if err != nil {
|
||||
common.Logger.Info("No test fixtures were found, so the safe primes will be generated from scratch. This may take a while...",
|
||||
err)
|
||||
pIDs = tss.GenerateTestPartyIDs(testParticipants)
|
||||
}
|
||||
|
||||
p2pCtx := tss.NewPeerContext(pIDs)
|
||||
parties := make([]*LocalParty, 0, len(pIDs))
|
||||
|
||||
errCh := make(chan *tss.Error, len(pIDs))
|
||||
outCh := make(chan tss.Message, len(pIDs))
|
||||
endCh := make(chan LocalPartySaveData, len(pIDs))
|
||||
|
||||
updater := SharedPartyUpdaterInjectingFeldmanError
|
||||
|
||||
parties, errCh = initTheParties(pIDs, p2pCtx, threshold, fixtures, outCh, endCh, parties, errCh)
|
||||
|
||||
// PHASE: keygen
|
||||
keygen:
|
||||
for {
|
||||
fmt.Printf("ACTIVE GOROUTINES: %d\n", runtime.NumGoroutine())
|
||||
select {
|
||||
case err := <-errCh:
|
||||
// We expect an error
|
||||
assert.Error(t, err, "should have thrown an abort identification error")
|
||||
msg := err.Cause().Error()
|
||||
assert.Truef(t, strings.Contains(msg, "abort identification - error in the Feldman share verification"),
|
||||
"the error detected should have been for abort identification")
|
||||
mError := err.Cause().(*multierror.Error)
|
||||
assert.Greaterf(t, len(mError.Errors), 0, "too few errors returned", len(mError.Errors))
|
||||
vc := (mError.Errors[0]).(*tss.VictimAndCulprit)
|
||||
assert.Truef(t, vc.Victim != nil && vc.Victim.Index == 0,
|
||||
"the victim should have been 0 but it was %v instead", vc.Victim.Index)
|
||||
assert.Truef(t, vc.Culprit != nil && vc.Culprit.Index == 1,
|
||||
"the culprit should have been 1 but it was %v instead", vc.Culprit.Index)
|
||||
break keygen
|
||||
|
||||
case msg := <-outCh:
|
||||
if handleMessage(t, msg, parties, updater, errCh) {
|
||||
return
|
||||
}
|
||||
case _ = <-endCh:
|
||||
assert.FailNow(t, "the end channel should not have returned")
|
||||
break keygen
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// When a round 2 broadcast is detected, set an abort flag to trigger
|
||||
// a false Feldman check failure.
|
||||
func SharedPartyUpdaterInjectingFramingError(party tss.Party, msg tss.Message, errCh chan<- *tss.Error) {
|
||||
// do not send a message from this party back to itself
|
||||
if party.PartyID() == msg.GetFrom() {
|
||||
return
|
||||
}
|
||||
bz, _, err := msg.WireBytes()
|
||||
if err != nil {
|
||||
errCh <- party.WrapError(err)
|
||||
return
|
||||
}
|
||||
pMsg, err := tss.ParseWireMessage(bz, msg.GetFrom(), msg.IsBroadcast())
|
||||
if err != nil {
|
||||
errCh <- party.WrapError(err)
|
||||
return
|
||||
}
|
||||
|
||||
// Intercepting a round 2 broadcast message
|
||||
if msg.Type() == "KGRound2Message2" && msg.IsBroadcast() && msg.GetFrom().Index == 0 && party.PartyID().Index == 1 {
|
||||
common.Logger.Debugf("party %s at round 2 - msg %s from %s", party.PartyID(), msg.Type(), msg.GetFrom())
|
||||
tlp := party.(*LocalParty)
|
||||
tlp.temp.abortTriggers = []AbortTrigger{FeldmanCheckFailure}
|
||||
}
|
||||
|
||||
if _, err := party.Update(pMsg); err != nil {
|
||||
errCh <- err
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// The test will trigger a false Feldman check failure.
|
||||
// The abort identification will label the case as the plaintiff trying to frame the accused player.
|
||||
func TestIdentifiableAbortTryToFrame(t *testing.T) {
|
||||
setUp("info")
|
||||
|
||||
threshold := testThreshold
|
||||
fixtures, pIDs, err := LoadKeygenTestFixtures(testParticipants)
|
||||
if err != nil {
|
||||
common.Logger.Info("No test fixtures were found, so the safe primes will be generated from scratch. This may take a while...",
|
||||
err)
|
||||
pIDs = tss.GenerateTestPartyIDs(testParticipants)
|
||||
}
|
||||
|
||||
p2pCtx := tss.NewPeerContext(pIDs)
|
||||
parties := make([]*LocalParty, 0, len(pIDs))
|
||||
|
||||
errCh := make(chan *tss.Error, len(pIDs))
|
||||
outCh := make(chan tss.Message, len(pIDs))
|
||||
endCh := make(chan LocalPartySaveData, len(pIDs))
|
||||
|
||||
updater := SharedPartyUpdaterInjectingFramingError
|
||||
|
||||
parties, errCh = initTheParties(pIDs, p2pCtx, threshold, fixtures, outCh, endCh, parties, errCh)
|
||||
|
||||
// PHASE: keygen
|
||||
keygen:
|
||||
for {
|
||||
fmt.Printf("ACTIVE GOROUTINES: %d\n", runtime.NumGoroutine())
|
||||
select {
|
||||
case err := <-errCh:
|
||||
// We expect an error
|
||||
assert.Error(t, err, "should have thrown an abort identification error")
|
||||
msg := err.Cause().Error()
|
||||
assert.Truef(t, strings.Contains(msg, "abort identification - the plaintiff party tried to frame the accused one"),
|
||||
"the error detected should have been a framing case in abort identification")
|
||||
mError := err.Cause().(*multierror.Error)
|
||||
assert.Greaterf(t, len(mError.Errors), 0, "too few errors returned", len(mError.Errors))
|
||||
vc := (mError.Errors[0]).(*tss.VictimAndCulprit)
|
||||
assert.EqualValues(t, vc.Culprit.Index, 1,
|
||||
"the 1st culprit should have been 1 but it was %d instead", vc.Culprit.Index)
|
||||
break keygen
|
||||
|
||||
case msg := <-outCh:
|
||||
if handleMessage(t, msg, parties, updater, errCh) {
|
||||
return
|
||||
}
|
||||
case _ = <-endCh:
|
||||
assert.FailNow(t, "the end channel should not have returned")
|
||||
break keygen
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestE2EConcurrentAndSaveFixtures(t *testing.T) {
|
||||
setUp("info")
|
||||
|
||||
@@ -176,7 +357,8 @@ func TestE2EConcurrentAndSaveFixtures(t *testing.T) {
|
||||
threshold := testThreshold
|
||||
fixtures, pIDs, err := LoadKeygenTestFixtures(testParticipants)
|
||||
if err != nil {
|
||||
common.Logger.Info("No test fixtures were found, so the safe primes will be generated from scratch. This may take a while...")
|
||||
common.Logger.Info("No test fixtures were found, so the safe primes will be generated from scratch. This may take a while...",
|
||||
err)
|
||||
pIDs = tss.GenerateTestPartyIDs(testParticipants)
|
||||
}
|
||||
|
||||
@@ -191,22 +373,7 @@ func TestE2EConcurrentAndSaveFixtures(t *testing.T) {
|
||||
|
||||
startGR := runtime.NumGoroutine()
|
||||
|
||||
// init the parties
|
||||
for i := 0; i < len(pIDs); i++ {
|
||||
var P *LocalParty
|
||||
params := tss.NewParameters(p2pCtx, pIDs[i], len(pIDs), threshold)
|
||||
if i < len(fixtures) {
|
||||
P = NewLocalParty(params, outCh, endCh, fixtures[i].LocalPreParams).(*LocalParty)
|
||||
} else {
|
||||
P = NewLocalParty(params, outCh, endCh).(*LocalParty)
|
||||
}
|
||||
parties = append(parties, P)
|
||||
go func(P *LocalParty) {
|
||||
if err := P.Start(); err != nil {
|
||||
errCh <- err
|
||||
}
|
||||
}(P)
|
||||
}
|
||||
parties, errCh = initTheParties(pIDs, p2pCtx, threshold, fixtures, outCh, endCh, parties, errCh)
|
||||
|
||||
// PHASE: keygen
|
||||
var ended int32
|
||||
@@ -220,20 +387,8 @@ keygen:
|
||||
break keygen
|
||||
|
||||
case msg := <-outCh:
|
||||
dest := msg.GetTo()
|
||||
if dest == nil { // broadcast!
|
||||
for _, P := range parties {
|
||||
if P.PartyID().Index == msg.GetFrom().Index {
|
||||
continue
|
||||
}
|
||||
go updater(P, msg, errCh)
|
||||
}
|
||||
} else { // point-to-point!
|
||||
if dest[0].Index == msg.GetFrom().Index {
|
||||
t.Fatalf("party %d tried to send a message to itself (%d)", dest[0].Index, msg.GetFrom().Index)
|
||||
return
|
||||
}
|
||||
go updater(parties[dest[0].Index], msg, errCh)
|
||||
if handleMessage(t, msg, parties, updater, errCh) {
|
||||
return
|
||||
}
|
||||
|
||||
case save := <-endCh:
|
||||
@@ -339,6 +494,45 @@ keygen:
|
||||
}
|
||||
}
|
||||
|
||||
func handleMessage(t *testing.T, msg tss.Message, parties []*LocalParty, updater func(party tss.Party, msg tss.Message, errCh chan<- *tss.Error), errCh chan *tss.Error) bool {
|
||||
dest := msg.GetTo()
|
||||
if dest == nil { // broadcast!
|
||||
for _, P := range parties {
|
||||
if P.PartyID().Index == msg.GetFrom().Index {
|
||||
continue
|
||||
}
|
||||
go updater(P, msg, errCh)
|
||||
}
|
||||
} else { // point-to-point!
|
||||
if dest[0].Index == msg.GetFrom().Index {
|
||||
t.Fatalf("party %d tried to send a message to itself (%d)", dest[0].Index, msg.GetFrom().Index)
|
||||
return true
|
||||
}
|
||||
go updater(parties[dest[0].Index], msg, errCh)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func initTheParties(pIDs tss.SortedPartyIDs, p2pCtx *tss.PeerContext, threshold int, fixtures []LocalPartySaveData, outCh chan tss.Message, endCh chan LocalPartySaveData, parties []*LocalParty, errCh chan *tss.Error) ([]*LocalParty, chan *tss.Error) {
|
||||
// init the parties
|
||||
for i := 0; i < len(pIDs); i++ {
|
||||
var P *LocalParty
|
||||
params := tss.NewParameters(p2pCtx, pIDs[i], len(pIDs), threshold)
|
||||
if i < len(fixtures) {
|
||||
P = NewLocalParty(params, outCh, endCh, fixtures[i].LocalPreParams).(*LocalParty)
|
||||
} else {
|
||||
P = NewLocalParty(params, outCh, endCh).(*LocalParty)
|
||||
}
|
||||
parties = append(parties, P)
|
||||
go func(P *LocalParty) {
|
||||
if err := P.Start(); err != nil {
|
||||
errCh <- err
|
||||
}
|
||||
}(P)
|
||||
}
|
||||
return parties, errCh
|
||||
}
|
||||
|
||||
func tryWriteTestFixtureFile(t *testing.T, index int, data LocalPartySaveData) {
|
||||
fixtureFileName := makeTestFixtureFilePath(index)
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ var (
|
||||
(*KGRound2Message1)(nil),
|
||||
(*KGRound2Message2)(nil),
|
||||
(*KGRound3Message)(nil),
|
||||
(*KGRound3MessageAbortMode)(nil),
|
||||
}
|
||||
)
|
||||
|
||||
@@ -39,7 +40,7 @@ func NewKGRound1Message(
|
||||
ct cmt.HashCommitment,
|
||||
paillierPK *paillier.PublicKey,
|
||||
authEcdsaPK *ecdsa.PublicKey,
|
||||
authEcdsaSignature *ECDSASignature,
|
||||
authPaillierSignature *ECDSASignature,
|
||||
nTildeI, h1I, h2I, proofNSquareFree, randIntProofNSquareFree *big.Int,
|
||||
dlnProof1, dlnProof2 *dlnp.Proof,
|
||||
) (tss.ParsedMessage, error) {
|
||||
@@ -67,8 +68,8 @@ func NewKGRound1Message(
|
||||
RandIntProofNSquareFree: randIntProofNSquareFree.Bytes(),
|
||||
AuthenticationEcdsaPublicKeyX: authEcdsaPK.X.Bytes(),
|
||||
AuthenticationEcdsaPublicKeyY: authEcdsaPK.Y.Bytes(),
|
||||
AuthenticationEcdsaSigR: authEcdsaSignature.r.Bytes(),
|
||||
AuthenticationEcdsaSigS: authEcdsaSignature.s.Bytes(),
|
||||
AuthenticationPaillierSigR: authPaillierSignature.r.Bytes(),
|
||||
AuthenticationPaillierSigS: authPaillierSignature.s.Bytes(),
|
||||
}
|
||||
msg := tss.NewMessageWrapper(meta, content)
|
||||
return tss.NewMessage(meta, content, msg), nil
|
||||
@@ -103,9 +104,9 @@ func (m *KGRound1Message) UnmarshalAuthEcdsaPK() *ecdsa.PublicKey {
|
||||
}
|
||||
}
|
||||
|
||||
func (m *KGRound1Message) UnmarshalAuthEcdsaSignature() *ECDSASignature {
|
||||
return NewECDSASignature(new(big.Int).SetBytes(m.AuthenticationEcdsaSigR),
|
||||
new(big.Int).SetBytes(m.AuthenticationEcdsaSigS))
|
||||
func (m *KGRound1Message) UnmarshalAuthPaillierSignature() *ECDSASignature {
|
||||
return NewECDSASignature(new(big.Int).SetBytes(m.GetAuthenticationPaillierSigR()),
|
||||
new(big.Int).SetBytes(m.GetAuthenticationPaillierSigS()))
|
||||
}
|
||||
|
||||
func (m *KGRound1Message) UnmarshalNTilde() *big.Int {
|
||||
@@ -251,3 +252,62 @@ func (m *KGRound3Message) UnmarshalXiProof() (*zkp.DLogProof, error) {
|
||||
T: new(big.Int).SetBytes(m.GetProofXiT()),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ----- //
|
||||
|
||||
func NewKGRound3MessageAbortMode(
|
||||
from *tss.PartyID,
|
||||
suspiciousVssShareWithAuthSigMessages []*VSSShareWithAuthSigMessage,
|
||||
) tss.ParsedMessage {
|
||||
meta := tss.MessageRouting{
|
||||
From: from,
|
||||
IsBroadcast: true,
|
||||
}
|
||||
content := &KGRound3MessageAbortMode{SuspiciousVsss: suspiciousVssShareWithAuthSigMessages,
|
||||
PlaintiffParty: uint32(from.Index)}
|
||||
msg := tss.NewMessageWrapper(meta, content)
|
||||
return tss.NewMessage(meta, content, msg)
|
||||
}
|
||||
|
||||
func (m *KGRound3MessageAbortMode) ValidateBasic() bool {
|
||||
if m == nil {
|
||||
return false
|
||||
}
|
||||
for _, b := range m.GetSuspiciousVsss() {
|
||||
ok := common.NonEmptyBytes(b.GetAuthSigPk().X) &&
|
||||
common.NonEmptyBytes(b.GetAuthSigPk().Y) &&
|
||||
common.NonEmptyBytes(b.GetVssId()) &&
|
||||
common.NonEmptyBytes(b.GetVssSigma())
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (m *KGRound3MessageAbortMode) UnmarshalFeldmanCheckFailureEvidence() ([]*FeldmanCheckFailureEvidence, int) {
|
||||
suspiciousVsss := m.GetSuspiciousVsss()
|
||||
feldmanCheckFailures := make([]*FeldmanCheckFailureEvidence, len(suspiciousVsss))
|
||||
for n, vsss := range suspiciousVsss {
|
||||
share := vss.Share{Share: new(big.Int).SetBytes(vsss.GetVssSigma()),
|
||||
ID: new(big.Int).SetBytes(vsss.GetVssId()),
|
||||
Threshold: int(vsss.GetVssThreshold()),
|
||||
}
|
||||
pk := ecdsa.PublicKey{X: new(big.Int).SetBytes(vsss.GetAuthSigPk().GetX()),
|
||||
Y: new(big.Int).SetBytes(vsss.GetAuthSigPk().GetY()),
|
||||
Curve: tss.EC()}
|
||||
authEcdsaSignature := ECDSASignature{r: new(big.Int).SetBytes(vsss.GetAuthEcdsaSignatureR()),
|
||||
s: new(big.Int).SetBytes(vsss.GetAuthEcdsaSignatureS())}
|
||||
var KGDj = make([]*big.Int, len(vsss.GetKGDj()))
|
||||
for a, k := range vsss.GetKGDj() {
|
||||
KGDj[a] = new(big.Int).SetBytes(k)
|
||||
}
|
||||
|
||||
e := FeldmanCheckFailureEvidence{sigmaji: &share, authSignaturePkj: pk,
|
||||
accusedPartyj: vsss.GetAccusedParty(),
|
||||
KGDj: KGDj,
|
||||
authEcdsaSignature: &authEcdsaSignature}
|
||||
feldmanCheckFailures[n] = &e
|
||||
}
|
||||
return feldmanCheckFailures, int(m.GetPlaintiffParty())
|
||||
}
|
||||
|
||||
@@ -145,7 +145,7 @@ consumer:
|
||||
|
||||
preParams := &LocalPreParams{
|
||||
PaillierSK: paiSK,
|
||||
AuthEcdsaPrivateKey: authEcdsaKey,
|
||||
AuthEcdsaPrivateKey: (*MarshallableEcdsaPrivateKey)(authEcdsaKey),
|
||||
NTildei: NTildei,
|
||||
H1i: h1i,
|
||||
H2i: h2i,
|
||||
|
||||
@@ -83,11 +83,12 @@ func (round *round1) Start() *tss.Error {
|
||||
}
|
||||
|
||||
// Sign the Paillier PK
|
||||
r, s, err := ecdsa.Sign(rand.Reader, preParams.AuthEcdsaPrivateKey, HashPaillierKey(&preParams.PaillierSK.PublicKey))
|
||||
r, s, err := ecdsa.Sign(rand.Reader, (*ecdsa.PrivateKey)(preParams.AuthEcdsaPrivateKey),
|
||||
HashPaillierKey(&preParams.PaillierSK.PublicKey))
|
||||
if err != nil {
|
||||
return round.WrapError(errors.New("ecdsa signature for authentication failed"), Pi)
|
||||
}
|
||||
authEcdsaSignature := NewECDSASignature(r, s)
|
||||
authPaillierSignaturei := NewECDSASignature(r, s)
|
||||
round.save.LocalPreParams = *preParams
|
||||
round.save.NTildej[i] = preParams.NTildei
|
||||
round.save.H1j[i], round.save.H2j[i] = preParams.H1i, preParams.H2i
|
||||
@@ -130,8 +131,9 @@ func (round *round1) Start() *tss.Error {
|
||||
// BROADCAST commitments, paillier pk + proof; round 1 message
|
||||
{
|
||||
msg, err := NewKGRound1Message(
|
||||
round.PartyID(), cmt.C, &preParams.PaillierSK.PublicKey, &preParams.AuthEcdsaPrivateKey.PublicKey,
|
||||
authEcdsaSignature,
|
||||
round.PartyID(), cmt.C, &preParams.PaillierSK.PublicKey,
|
||||
&preParams.AuthEcdsaPrivateKey.PublicKey,
|
||||
authPaillierSignaturei,
|
||||
preParams.NTildei, preParams.H1i, preParams.H2i,
|
||||
proofNSquareFree, randIntProofNSquareFreei, dlnProof1, dlnProof2)
|
||||
if err != nil {
|
||||
|
||||
@@ -40,12 +40,14 @@ func (round *round2) Start() *tss.Error {
|
||||
wg := new(sync.WaitGroup)
|
||||
for j, msg := range round.temp.kgRound1Messages {
|
||||
r1msg := msg.Content().(*KGRound1Message)
|
||||
H1j, H2j, NTildej, authEcdsaPKj, authEcdsaSigj :=
|
||||
paillierPKj, H1j, H2j, NTildej, authEcdsaPKj, authPaillierSigj :=
|
||||
r1msg.UnmarshalPaillierPK(),
|
||||
r1msg.UnmarshalH1(),
|
||||
r1msg.UnmarshalH2(),
|
||||
r1msg.UnmarshalNTilde(),
|
||||
r1msg.UnmarshalAuthEcdsaPK(),
|
||||
r1msg.UnmarshalAuthEcdsaSignature()
|
||||
r1msg.UnmarshalAuthPaillierSignature()
|
||||
|
||||
if H1j.Cmp(H2j) == 0 {
|
||||
return round.WrapError(errors.New("h1j and h2j were equal for this party"), msg.GetFrom())
|
||||
}
|
||||
@@ -85,14 +87,14 @@ func (round *round2) Start() *tss.Error {
|
||||
wg.Done()
|
||||
}(j, msg, r1msg, NTildej)
|
||||
|
||||
// Signing the share
|
||||
// Verify the Paillier PK with the authentication PK and sign the share
|
||||
go func(j int, msg tss.ParsedMessage) {
|
||||
hash := HashPaillierKey(round.save.PaillierPKs[j])
|
||||
verifies := ecdsa.Verify(authEcdsaPKj, hash, authEcdsaSigj.r, authEcdsaSigj.s)
|
||||
verifies := ecdsa.Verify(authEcdsaPKj, HashPaillierKey(paillierPKj), authPaillierSigj.r, authPaillierSigj.s)
|
||||
if !verifies {
|
||||
authSignaturesFailCulprits[j] = msg.GetFrom()
|
||||
} else {
|
||||
r, s, err := ecdsa.Sign(rand.Reader, round.save.AuthEcdsaPrivateKey, HashShare(round.temp.shares[j]))
|
||||
r, s, err := ecdsa.Sign(rand.Reader, (*ecdsa.PrivateKey)(round.save.AuthEcdsaPrivateKey),
|
||||
HashShare(round.temp.shares[j]))
|
||||
authSignatures[j] = NewECDSASignature(r, s)
|
||||
if err != nil {
|
||||
authSignaturesFailCulprits[j] = msg.GetFrom()
|
||||
@@ -141,7 +143,7 @@ func (round *round2) Start() *tss.Error {
|
||||
r1msg.UnmarshalNTilde(),
|
||||
r1msg.UnmarshalCommitment()
|
||||
round.save.PaillierPKs[j] = paillierPK // used in round 4
|
||||
round.save.AuthenticationPKs[j] = authEcdsaPKj
|
||||
round.save.AuthenticationPKs[j] = (*MarshallableEcdsaPublicKey)(authEcdsaPKj)
|
||||
round.save.NTildej[j] = NTildej
|
||||
round.save.H1j[j], round.save.H2j[j] = H1j, H2j
|
||||
round.temp.KGCs[j] = KGC
|
||||
|
||||
@@ -22,6 +22,16 @@ import (
|
||||
"github.com/binance-chain/tss-lib/tss"
|
||||
)
|
||||
|
||||
// The evidence of an eventual Feldman check failure will be evaluated
|
||||
// during the abort identification in round 4.
|
||||
type FeldmanCheckFailureEvidence struct {
|
||||
sigmaji *vss.Share
|
||||
authSignaturePkj ecdsa.PublicKey
|
||||
accusedPartyj uint32
|
||||
KGDj []*big.Int
|
||||
authEcdsaSignature *ECDSASignature
|
||||
}
|
||||
|
||||
func (round *round3) Start() *tss.Error {
|
||||
if round.started {
|
||||
return round.WrapError(errors.New("round already started"))
|
||||
@@ -41,8 +51,9 @@ func (round *round3) Start() *tss.Error {
|
||||
|
||||
// 4-11.
|
||||
type vssOut struct {
|
||||
unWrappedErr error
|
||||
pjVs vss.Vs
|
||||
unWrappedErr error
|
||||
pjVs vss.Vs
|
||||
feldmanCheckFailureArgs *FeldmanCheckFailureEvidence
|
||||
}
|
||||
chs := make([]chan vssOut, len(Ps))
|
||||
for i := range chs {
|
||||
@@ -64,12 +75,13 @@ func (round *round3) Start() *tss.Error {
|
||||
cmtDeCmt := commitments.HashCommitDecommit{C: KGCj, D: KGDj}
|
||||
ok, flatPolyGs := cmtDeCmt.DeCommit()
|
||||
if !ok || flatPolyGs == nil {
|
||||
ch <- vssOut{errors.New("de-commitment verify failed"), nil}
|
||||
ch <- vssOut{errors.New("de-commitment verify failed"), nil,
|
||||
nil}
|
||||
return
|
||||
}
|
||||
PjVs, err := crypto.UnFlattenECPoints(tss.EC(), flatPolyGs)
|
||||
if err != nil {
|
||||
ch <- vssOut{err, nil}
|
||||
ch <- vssOut{err, nil, nil}
|
||||
return
|
||||
}
|
||||
r2msg1 := round.temp.kgRound2Message1s[j].Content().(*KGRound2Message1)
|
||||
@@ -80,19 +92,34 @@ func (round *round3) Start() *tss.Error {
|
||||
}
|
||||
authEcdsaSignature := r2msg1.UnmarshalAuthEcdsaSignature()
|
||||
|
||||
authEcdsaSignatureOk := ecdsa.Verify(round.save.AuthenticationPKs[j], HashShare(&PjShare),
|
||||
authEcdsaSignatureOk := ecdsa.Verify((*ecdsa.PublicKey)(round.save.AuthenticationPKs[j]),
|
||||
HashShare(&PjShare),
|
||||
authEcdsaSignature.r, authEcdsaSignature.s)
|
||||
if !authEcdsaSignatureOk {
|
||||
ch <- vssOut{errors.New("ecdsa signature of VSS share for authentication failed"),
|
||||
nil}
|
||||
nil, nil}
|
||||
return
|
||||
}
|
||||
if ok = PjShare.Verify(round.Threshold(), PjVs); !ok {
|
||||
ch <- vssOut{errors.New("vss verify failed"), nil}
|
||||
|
||||
if ok = PjShare.Verify(round.Threshold(), PjVs) && !round.shouldTriggerAbortInFeldmanCheck(); !ok {
|
||||
// Prepare evidence to be verified during the abort identification
|
||||
evidence := FeldmanCheckFailureEvidence{
|
||||
sigmaji: &PjShare,
|
||||
authSignaturePkj: ecdsa.PublicKey{
|
||||
Curve: tss.EC(),
|
||||
X: round.save.AuthenticationPKs[j].X,
|
||||
Y: round.save.AuthenticationPKs[j].Y},
|
||||
accusedPartyj: uint32(j),
|
||||
KGDj: KGDj,
|
||||
authEcdsaSignature: authEcdsaSignature,
|
||||
}
|
||||
|
||||
ch <- vssOut{errors.New("vss verify failed"), nil,
|
||||
&evidence}
|
||||
return
|
||||
}
|
||||
// (9) handled above
|
||||
ch <- vssOut{nil, PjVs}
|
||||
ch <- vssOut{nil, PjVs, nil}
|
||||
}(j, chs[j])
|
||||
}
|
||||
|
||||
@@ -113,6 +140,7 @@ func (round *round3) Start() *tss.Error {
|
||||
vssResults := make([]vssOut, len(Ps))
|
||||
{
|
||||
culprits := make([]*tss.PartyID, 0, len(Ps)) // who caused the error(s)
|
||||
feldmanCheckFailures := make([]*FeldmanCheckFailureEvidence, 0)
|
||||
for j, Pj := range Ps {
|
||||
if j == PIdx {
|
||||
continue
|
||||
@@ -121,8 +149,20 @@ func (round *round3) Start() *tss.Error {
|
||||
// collect culprits to error out with
|
||||
if err := vssResults[j].unWrappedErr; err != nil {
|
||||
culprits = append(culprits, Pj)
|
||||
if vssResults[j].feldmanCheckFailureArgs != nil {
|
||||
feldmanCheckFailures = append(feldmanCheckFailures, vssResults[j].feldmanCheckFailureArgs)
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(feldmanCheckFailures) > 0 {
|
||||
vssShareWithAuthSigMessages := prepareShareWithAuthSigMessages(feldmanCheckFailures, round.PartyID())
|
||||
|
||||
// BROADCAST the failed sigma and the authentication signature for the abort identification
|
||||
r3msg := NewKGRound3MessageAbortMode(round.PartyID(), vssShareWithAuthSigMessages)
|
||||
round.temp.kgRound3Messages[PIdx] = r3msg
|
||||
round.out <- r3msg
|
||||
return nil
|
||||
}
|
||||
var multiErr error
|
||||
if len(culprits) > 0 {
|
||||
for _, vssResult := range vssResults {
|
||||
@@ -206,10 +246,39 @@ func (round *round3) Start() *tss.Error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func prepareShareWithAuthSigMessages(feldmanCheckFailures []*FeldmanCheckFailureEvidence, partyID *tss.PartyID) []*VSSShareWithAuthSigMessage {
|
||||
vssShareWithAuthSigMessages := make([]*VSSShareWithAuthSigMessage, len(feldmanCheckFailures))
|
||||
for a, evidence := range feldmanCheckFailures {
|
||||
ecPoint := common.ECPoint{X: evidence.authSignaturePkj.X.Bytes(), Y: evidence.authSignaturePkj.Y.Bytes()}
|
||||
KGDjmsg := make([][]byte, len(evidence.KGDj))
|
||||
for b, k := range evidence.KGDj {
|
||||
KGDjmsg[b] = k.Bytes()
|
||||
}
|
||||
|
||||
msg := VSSShareWithAuthSigMessage{
|
||||
VssThreshold: uint32(evidence.sigmaji.Threshold),
|
||||
VssId: evidence.sigmaji.ID.Bytes(),
|
||||
VssSigma: evidence.sigmaji.Share.Bytes(),
|
||||
AccusedParty: evidence.accusedPartyj,
|
||||
AuthSigPk: &ecPoint,
|
||||
KGDj: KGDjmsg,
|
||||
AuthEcdsaSignatureR: evidence.authEcdsaSignature.r.Bytes(),
|
||||
AuthEcdsaSignatureS: evidence.authEcdsaSignature.s.Bytes()}
|
||||
vssShareWithAuthSigMessages[a] = &msg
|
||||
common.Logger.Warnf("party %v is the plaintiff triggering an abort identification"+
|
||||
" accusing party %v",
|
||||
partyID, evidence.accusedPartyj)
|
||||
}
|
||||
return vssShareWithAuthSigMessages
|
||||
}
|
||||
|
||||
func (round *round3) CanAccept(msg tss.ParsedMessage) bool {
|
||||
if _, ok := msg.Content().(*KGRound3Message); ok {
|
||||
return msg.IsBroadcast()
|
||||
}
|
||||
if _, ok := msg.Content().(*KGRound3MessageAbortMode); ok {
|
||||
return msg.IsBroadcast()
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -231,3 +300,7 @@ func (round *round3) NextRound() tss.Round {
|
||||
round.started = false
|
||||
return &round4{round}
|
||||
}
|
||||
|
||||
func (round *round3) shouldTriggerAbortInFeldmanCheck() bool {
|
||||
return round.shouldTriggerAbort(FeldmanCheckFailure)
|
||||
}
|
||||
|
||||
@@ -8,13 +8,7 @@ package keygen
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/go-multierror"
|
||||
|
||||
"github.com/binance-chain/tss-lib/common"
|
||||
"github.com/binance-chain/tss-lib/crypto/paillier"
|
||||
"github.com/binance-chain/tss-lib/crypto/zkp"
|
||||
"github.com/binance-chain/tss-lib/tss"
|
||||
)
|
||||
|
||||
@@ -26,86 +20,24 @@ func (round *round4) Start() *tss.Error {
|
||||
round.started = true
|
||||
round.resetOK()
|
||||
|
||||
i := round.PartyID().Index
|
||||
Ps := round.Parties().IDs()
|
||||
PIDs := Ps.Keys()
|
||||
ecdsaPub := round.save.ECDSAPub
|
||||
|
||||
// 1-3. (concurrent)
|
||||
// r3 messages are assumed to be available and != nil in this function
|
||||
r3msgs := round.temp.kgRound3Messages
|
||||
type channelOut struct {
|
||||
unWrappedErr error
|
||||
ok bool
|
||||
}
|
||||
chs := make([]chan channelOut, len(r3msgs))
|
||||
for i := range chs {
|
||||
chs[i] = make(chan channelOut)
|
||||
}
|
||||
for j, msg := range round.temp.kgRound3Messages {
|
||||
if j == i {
|
||||
continue
|
||||
}
|
||||
r3msg := msg.Content().(*KGRound3Message)
|
||||
go func(prf paillier.Proof, j int, ch chan<- channelOut) {
|
||||
ppk := round.save.PaillierPKs[j]
|
||||
ok, err := prf.Verify(ppk.N, PIDs[j], ecdsaPub)
|
||||
if err != nil {
|
||||
common.Logger.Error(round.WrapError(err, Ps[j]).Error())
|
||||
ch <- channelOut{err, false}
|
||||
return
|
||||
}
|
||||
ch <- channelOut{nil, ok}
|
||||
}(r3msg.UnmarshalProofInts(), j, chs[j])
|
||||
|
||||
if zkProofxi, err := r3msg.UnmarshalXiProof(); err != nil {
|
||||
common.Logger.Error("error unmarshalling the xj ZK proof for party %v", Ps[j])
|
||||
return round.WrapError(fmt.Errorf("error unmarshalling the xj ZK proof for party %v", Ps[j]))
|
||||
} else {
|
||||
go func(prf *zkp.DLogProof, j int, ch chan<- channelOut) {
|
||||
bigXj := round.save.BigXj[j]
|
||||
ok := prf.Verify(bigXj)
|
||||
if !ok {
|
||||
err := fmt.Errorf("error in the verification the xj ZK proof for party %v", Ps[j])
|
||||
common.Logger.Error(err)
|
||||
ch <- channelOut{err, false}
|
||||
return
|
||||
}
|
||||
ch <- channelOut{nil, ok}
|
||||
}(zkProofxi, j, chs[j])
|
||||
abortr3msgs := make([]tss.ParsedMessage, 0)
|
||||
for _, m := range r3msgs {
|
||||
if m.Type() == "KGRound3MessageAbortMode" {
|
||||
abortr3msgs = append(abortr3msgs, m)
|
||||
}
|
||||
}
|
||||
|
||||
outResults := make([]channelOut, len(Ps))
|
||||
culprits := make([]*tss.PartyID, 0, len(Ps)) // who caused the error(s)
|
||||
// consume unbuffered channels (end the goroutines)
|
||||
for j, ch := range chs {
|
||||
if j == i {
|
||||
round.ok[j] = true
|
||||
continue
|
||||
}
|
||||
outResults[j] = <-ch
|
||||
if err := outResults[j].unWrappedErr; err != nil && j < len(Ps) {
|
||||
culprits = append(culprits, Ps[j])
|
||||
}
|
||||
round.ok[j] = outResults[j].ok
|
||||
i := round.PartyID().Index
|
||||
Ps := round.Parties().IDs()
|
||||
if len(abortr3msgs) > 0 {
|
||||
return round.startInAbortMode(i, Ps, abortr3msgs)
|
||||
} else {
|
||||
PIDs := Ps.Keys()
|
||||
ecdsaPub := round.save.ECDSAPub
|
||||
return round.startNormal(i, Ps, PIDs, ecdsaPub, r3msgs)
|
||||
}
|
||||
{
|
||||
var multiErr error
|
||||
if len(culprits) > 0 {
|
||||
for _, vssResult := range outResults {
|
||||
if vssResult.unWrappedErr == nil {
|
||||
continue
|
||||
}
|
||||
multiErr = multierror.Append(multiErr, vssResult.unWrappedErr)
|
||||
}
|
||||
return round.WrapError(multiErr, culprits...)
|
||||
}
|
||||
}
|
||||
|
||||
round.end <- *round.save
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (round *round4) CanAccept(msg tss.ParsedMessage) bool {
|
||||
|
||||
127
ecdsa/keygen/round_4_abort.go
Normal file
127
ecdsa/keygen/round_4_abort.go
Normal file
@@ -0,0 +1,127 @@
|
||||
// Copyright © 2020 Swingby
|
||||
//
|
||||
|
||||
package keygen
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
|
||||
"github.com/hashicorp/go-multierror"
|
||||
|
||||
"github.com/binance-chain/tss-lib/common"
|
||||
"github.com/binance-chain/tss-lib/crypto"
|
||||
"github.com/binance-chain/tss-lib/crypto/commitments"
|
||||
"github.com/binance-chain/tss-lib/tss"
|
||||
)
|
||||
|
||||
type FeldmanError int
|
||||
|
||||
// Possible errors
|
||||
const (
|
||||
NoError FeldmanError = iota
|
||||
DecommitError
|
||||
UnFlattenError
|
||||
ShareVerificationError
|
||||
PlaintiffTryingToFrameAccusedParty
|
||||
)
|
||||
|
||||
func (round *round4) feldmanCheck(feldmanCheckFailureEvidence *FeldmanCheckFailureEvidence) (bool, FeldmanError) {
|
||||
KGCj := round.temp.KGCs[feldmanCheckFailureEvidence.accusedPartyj]
|
||||
|
||||
cmtDeCmt := commitments.HashCommitDecommit{C: KGCj, D: feldmanCheckFailureEvidence.KGDj}
|
||||
ok, flatPolyGs := cmtDeCmt.DeCommit()
|
||||
if !ok || flatPolyGs == nil {
|
||||
return false, DecommitError
|
||||
}
|
||||
PjVs, err := crypto.UnFlattenECPoints(tss.EC(), flatPolyGs)
|
||||
if err != nil {
|
||||
return false, UnFlattenError
|
||||
}
|
||||
var PjShare = feldmanCheckFailureEvidence.sigmaji
|
||||
if ok = PjShare.Verify(round.Threshold(), PjVs); !ok {
|
||||
return false, ShareVerificationError
|
||||
}
|
||||
return true, NoError
|
||||
}
|
||||
|
||||
func (round *round4) startInAbortMode(i int, Ps tss.SortedPartyIDs, abortr3msgs []tss.ParsedMessage) *tss.Error {
|
||||
|
||||
var errorMap = map[FeldmanError]string{
|
||||
DecommitError: "abort identification - error opening de-commitment",
|
||||
UnFlattenError: "abort identification - error unflattening EC points from de-commitment",
|
||||
ShareVerificationError: "abort identification - error in the Feldman share verification",
|
||||
PlaintiffTryingToFrameAccusedParty: "abort identification - the plaintiff party tried to frame the accused one"}
|
||||
|
||||
type attributionOfBlame struct {
|
||||
partyToBlame *tss.PartyID
|
||||
victim uint32
|
||||
feldmanError FeldmanError
|
||||
}
|
||||
common.Logger.Debugf("party %v is starting the abort identification", Ps[i])
|
||||
culprits := make([]attributionOfBlame, 0)
|
||||
culpritSet := make(map[*tss.PartyID]struct{})
|
||||
for _, msg := range abortr3msgs {
|
||||
r3msg := msg.Content().(*KGRound3MessageAbortMode)
|
||||
feldmanCheckFailureEvidences, plaintiffParty := r3msg.UnmarshalFeldmanCheckFailureEvidence()
|
||||
if i == plaintiffParty {
|
||||
common.Logger.Debugf("party %v is the plaintiff and is excusing itself from the attribution of blame",
|
||||
Ps[i])
|
||||
continue
|
||||
}
|
||||
|
||||
for _, evidence := range feldmanCheckFailureEvidences {
|
||||
if i == int(evidence.accusedPartyj) {
|
||||
common.Logger.Debugf("the current party %v is being accused and is excusing itself from the attribution of blame",
|
||||
Ps[i])
|
||||
continue
|
||||
}
|
||||
|
||||
common.Logger.Debugf("party %v round 4 plaintiff party: %v, accused party: %v", round.PartyID(),
|
||||
plaintiffParty, evidence.accusedPartyj)
|
||||
|
||||
authSignaturesAreEqual := len(round.save.AuthenticationPKs) > int(evidence.accusedPartyj) &&
|
||||
evidence.authSignaturePkj.Equal((*ecdsa.PublicKey)(round.save.AuthenticationPKs[int(evidence.accusedPartyj)]))
|
||||
|
||||
authEcdsaSignatureOk := ecdsa.Verify(&evidence.authSignaturePkj, HashShare(evidence.sigmaji),
|
||||
evidence.authEcdsaSignature.r, evidence.authEcdsaSignature.s)
|
||||
var partyToBlame *tss.PartyID
|
||||
if !authEcdsaSignatureOk || !authSignaturesAreEqual {
|
||||
partyToBlame = round.Parties().IDs()[plaintiffParty]
|
||||
culprits = append(culprits, attributionOfBlame{partyToBlame: partyToBlame, victim: evidence.accusedPartyj,
|
||||
feldmanError: PlaintiffTryingToFrameAccusedParty})
|
||||
} else {
|
||||
ok, feldmanError := round.feldmanCheck(evidence)
|
||||
if !ok {
|
||||
partyToBlame = round.Parties().IDs()[evidence.accusedPartyj]
|
||||
culprits = append(culprits, attributionOfBlame{partyToBlame: partyToBlame,
|
||||
victim: uint32(plaintiffParty),
|
||||
feldmanError: feldmanError})
|
||||
} else {
|
||||
partyToBlame = round.Parties().IDs()[plaintiffParty]
|
||||
culprits = append(culprits, attributionOfBlame{partyToBlame: partyToBlame,
|
||||
feldmanError: PlaintiffTryingToFrameAccusedParty})
|
||||
}
|
||||
}
|
||||
common.Logger.Debugf("party %v, party to blame: %v", round.PartyID(), partyToBlame)
|
||||
culpritSet[partyToBlame] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
uniqueCulprits := make([]*tss.PartyID, 0, len(culpritSet))
|
||||
for aCulprit := range culpritSet {
|
||||
uniqueCulprits = append(uniqueCulprits, aCulprit)
|
||||
}
|
||||
|
||||
var multiErr error
|
||||
for _, culprit := range culprits {
|
||||
vc := &tss.VictimAndCulprit{Victim: Ps[culprit.victim], Culprit: culprit.partyToBlame,
|
||||
Message: errorMap[culprit.feldmanError]}
|
||||
multiErr = multierror.Append(multiErr, vc)
|
||||
}
|
||||
if len(culprits) > 0 {
|
||||
return round.WrapMultiError(multiErr, Ps[culprits[0].victim], uniqueCulprits...)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
|
||||
}
|
||||
97
ecdsa/keygen/round_4_normal.go
Normal file
97
ecdsa/keygen/round_4_normal.go
Normal file
@@ -0,0 +1,97 @@
|
||||
// Copyright © 2019 Binance
|
||||
//
|
||||
// This file is part of Binance. The full Binance copyright notice, including
|
||||
// terms governing use, modification, and redistribution, is contained in the
|
||||
// file LICENSE at the root of the source code distribution tree.
|
||||
|
||||
package keygen
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/big"
|
||||
|
||||
"github.com/hashicorp/go-multierror"
|
||||
|
||||
"github.com/binance-chain/tss-lib/common"
|
||||
"github.com/binance-chain/tss-lib/crypto"
|
||||
"github.com/binance-chain/tss-lib/crypto/paillier"
|
||||
"github.com/binance-chain/tss-lib/crypto/zkp"
|
||||
"github.com/binance-chain/tss-lib/tss"
|
||||
)
|
||||
|
||||
func (round *round4) startNormal(i int, Ps tss.SortedPartyIDs, PIDs []*big.Int, ecdsaPub *crypto.ECPoint,
|
||||
r3msgs []tss.ParsedMessage) *tss.Error {
|
||||
|
||||
type channelOut struct {
|
||||
unWrappedErr error
|
||||
ok bool
|
||||
}
|
||||
chs := make([]chan channelOut, len(r3msgs))
|
||||
for i := range chs {
|
||||
chs[i] = make(chan channelOut)
|
||||
}
|
||||
for j, msg := range round.temp.kgRound3Messages {
|
||||
if j == i {
|
||||
continue
|
||||
}
|
||||
r3msg := msg.Content().(*KGRound3Message)
|
||||
go func(prf paillier.Proof, j int, ch chan<- channelOut) {
|
||||
ppk := round.save.PaillierPKs[j]
|
||||
ok, err := prf.Verify(ppk.N, PIDs[j], ecdsaPub)
|
||||
if err != nil {
|
||||
common.Logger.Error(round.WrapError(err, Ps[j]).Error())
|
||||
ch <- channelOut{err, false}
|
||||
return
|
||||
}
|
||||
ch <- channelOut{nil, ok}
|
||||
}(r3msg.UnmarshalProofInts(), j, chs[j])
|
||||
|
||||
if zkProofxi, err := r3msg.UnmarshalXiProof(); err != nil {
|
||||
common.Logger.Error("error unmarshalling the xj ZK proof for party %v", Ps[j])
|
||||
return round.WrapError(fmt.Errorf("error unmarshalling the xj ZK proof for party %v", Ps[j]))
|
||||
} else {
|
||||
go func(prf *zkp.DLogProof, j int, ch chan<- channelOut) {
|
||||
bigXj := round.save.BigXj[j]
|
||||
ok := prf.Verify(bigXj)
|
||||
if !ok {
|
||||
err := fmt.Errorf("error in the verification the xj ZK proof for party %v", Ps[j])
|
||||
common.Logger.Error(err)
|
||||
ch <- channelOut{err, false}
|
||||
return
|
||||
}
|
||||
ch <- channelOut{nil, ok}
|
||||
}(zkProofxi, j, chs[j])
|
||||
}
|
||||
}
|
||||
|
||||
outResults := make([]channelOut, len(Ps))
|
||||
culprits := make([]*tss.PartyID, 0, len(Ps)) // who caused the error(s)
|
||||
// consume unbuffered channels (end the goroutines)
|
||||
for j, ch := range chs {
|
||||
if j == i {
|
||||
round.ok[j] = true
|
||||
continue
|
||||
}
|
||||
outResults[j] = <-ch
|
||||
if err := outResults[j].unWrappedErr; err != nil && j < len(Ps) {
|
||||
culprits = append(culprits, Ps[j])
|
||||
}
|
||||
round.ok[j] = outResults[j].ok
|
||||
}
|
||||
{
|
||||
var multiErr error
|
||||
if len(culprits) > 0 {
|
||||
for _, vssResult := range outResults {
|
||||
if vssResult.unWrappedErr == nil {
|
||||
continue
|
||||
}
|
||||
multiErr = multierror.Append(multiErr, vssResult.unWrappedErr)
|
||||
}
|
||||
return round.WrapError(multiErr, culprits...)
|
||||
}
|
||||
}
|
||||
|
||||
round.end <- *round.save
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -86,6 +86,10 @@ func (round *base) WrapError(err error, culprits ...*tss.PartyID) *tss.Error {
|
||||
return tss.NewError(err, TaskName, round.number, round.PartyID(), culprits...)
|
||||
}
|
||||
|
||||
func (round *base) WrapMultiError(err error, victim *tss.PartyID, culprits ...*tss.PartyID) *tss.Error {
|
||||
return tss.NewError(err, TaskName, round.number, victim, culprits...)
|
||||
}
|
||||
|
||||
// ----- //
|
||||
|
||||
// `ok` tracks parties which have been verified by Update()
|
||||
@@ -94,3 +98,15 @@ func (round *base) resetOK() {
|
||||
round.ok[j] = false
|
||||
}
|
||||
}
|
||||
|
||||
func (round *base) shouldTriggerAbort(trigger AbortTrigger) bool {
|
||||
if len(round.temp.abortTriggers) == 0 {
|
||||
return false
|
||||
}
|
||||
for _, t := range round.temp.abortTriggers {
|
||||
if trigger == t {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ package keygen
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"math/big"
|
||||
|
||||
"github.com/binance-chain/tss-lib/common"
|
||||
@@ -18,9 +19,16 @@ import (
|
||||
)
|
||||
|
||||
type (
|
||||
// We will customize the Json serialization of the public key
|
||||
// used for party authentication.
|
||||
// The serialization of the Koblitz curve showed problems,
|
||||
// as the type does not expose a number of attributes.
|
||||
MarshallableEcdsaPrivateKey ecdsa.PrivateKey
|
||||
MarshallableEcdsaPublicKey ecdsa.PublicKey
|
||||
|
||||
LocalPreParams struct {
|
||||
PaillierSK *paillier.PrivateKey // ski
|
||||
AuthEcdsaPrivateKey *ecdsa.PrivateKey
|
||||
AuthEcdsaPrivateKey *MarshallableEcdsaPrivateKey
|
||||
NTildei,
|
||||
H1i, H2i,
|
||||
Alpha, Beta,
|
||||
@@ -44,9 +52,9 @@ type (
|
||||
NTildej, H1j, H2j []*big.Int
|
||||
|
||||
// public keys (Xj = uj*G for each Pj)
|
||||
BigXj []*crypto.ECPoint // Xj
|
||||
PaillierPKs []*paillier.PublicKey // pkj
|
||||
AuthenticationPKs []*ecdsa.PublicKey // auth_yj
|
||||
BigXj []*crypto.ECPoint // Xj
|
||||
PaillierPKs []*paillier.PublicKey // pkj
|
||||
AuthenticationPKs []*MarshallableEcdsaPublicKey // auth_yj
|
||||
|
||||
// the ECDSA public key
|
||||
ECDSAPub *crypto.ECPoint // y
|
||||
@@ -59,11 +67,13 @@ func NewLocalPartySaveData(partyCount int) (saveData LocalPartySaveData) {
|
||||
saveData.H1j, saveData.H2j = make([]*big.Int, partyCount), make([]*big.Int, partyCount)
|
||||
saveData.BigXj = make([]*crypto.ECPoint, partyCount)
|
||||
saveData.PaillierPKs = make([]*paillier.PublicKey, partyCount)
|
||||
saveData.AuthenticationPKs = make([]*MarshallableEcdsaPublicKey, partyCount)
|
||||
return
|
||||
}
|
||||
|
||||
func (preParams LocalPreParams) Validate() bool {
|
||||
return preParams.PaillierSK != nil &&
|
||||
preParams.AuthEcdsaPrivateKey != nil &&
|
||||
preParams.NTildei != nil &&
|
||||
preParams.H1i != nil &&
|
||||
preParams.H2i != nil
|
||||
@@ -98,6 +108,55 @@ func BuildLocalSaveDataSubset(sourceData LocalPartySaveData, sortedIDs tss.Sorte
|
||||
newData.H2j[j] = sourceData.H2j[savedIdx]
|
||||
newData.BigXj[j] = sourceData.BigXj[savedIdx]
|
||||
newData.PaillierPKs[j] = sourceData.PaillierPKs[savedIdx]
|
||||
newData.AuthenticationPKs[j] = sourceData.AuthenticationPKs[savedIdx]
|
||||
}
|
||||
return newData
|
||||
}
|
||||
|
||||
func (k MarshallableEcdsaPrivateKey) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(struct {
|
||||
PublicKey MarshallableEcdsaPublicKey
|
||||
D *big.Int
|
||||
}{
|
||||
PublicKey: (MarshallableEcdsaPublicKey)(k.PublicKey),
|
||||
D: k.D,
|
||||
})
|
||||
}
|
||||
|
||||
func (k *MarshallableEcdsaPrivateKey) UnmarshalJSON(b []byte) error {
|
||||
// PrivateKey represents an ECDSA private key.
|
||||
newKey := new(struct {
|
||||
PublicKey MarshallableEcdsaPublicKey
|
||||
D *big.Int
|
||||
})
|
||||
if err := json.Unmarshal(b, &newKey); err != nil {
|
||||
return err
|
||||
}
|
||||
k.D = newKey.D
|
||||
k.PublicKey = (ecdsa.PublicKey)(newKey.PublicKey)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (k MarshallableEcdsaPublicKey) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(struct {
|
||||
X, Y *big.Int
|
||||
}{
|
||||
X: k.X,
|
||||
Y: k.Y,
|
||||
})
|
||||
}
|
||||
|
||||
func (k *MarshallableEcdsaPublicKey) UnmarshalJSON(b []byte) error {
|
||||
newKey := new(struct {
|
||||
X, Y *big.Int
|
||||
})
|
||||
if err := json.Unmarshal(b, &newKey); err != nil {
|
||||
return err
|
||||
}
|
||||
k.X = newKey.X
|
||||
k.Y = newKey.Y
|
||||
k.Curve = tss.EC()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -18,8 +18,8 @@ message KGRound1Message {
|
||||
bytes paillier_n = 2;
|
||||
bytes authentication_ecdsa_public_key_x = 3;
|
||||
bytes authentication_ecdsa_public_key_y = 4;
|
||||
bytes authentication_ecdsa_sig_r = 5;
|
||||
bytes authentication_ecdsa_sig_s = 6;
|
||||
bytes authentication_paillier_sig_r = 5;
|
||||
bytes authentication_paillier_sig_s = 6;
|
||||
bytes n_tilde = 7;
|
||||
bytes h1 = 8;
|
||||
bytes h2 = 9;
|
||||
@@ -54,3 +54,23 @@ message KGRound3Message {
|
||||
ECPoint proof_xi_alpha = 2;
|
||||
bytes proof_xi_t = 3;
|
||||
}
|
||||
|
||||
message VSSShareWithAuthSigMessage {
|
||||
uint32 vss_threshold = 1;
|
||||
bytes vss_id = 2;
|
||||
bytes vss_sigma = 3;
|
||||
uint32 accused_party = 4;
|
||||
ECPoint auth_sig_pk = 5;
|
||||
bytes authEcdsaSignature_r = 6;
|
||||
bytes authEcdsaSignature_s = 7;
|
||||
repeated bytes KGDj = 8;
|
||||
}
|
||||
|
||||
/*
|
||||
* Represents a BROADCAST message sent to each party during Round 3 of the ECDSA TSS keygen protocol
|
||||
* when in abort mode.
|
||||
*/
|
||||
message KGRound3MessageAbortMode {
|
||||
uint32 plaintiff_party = 1;
|
||||
repeated VSSShareWithAuthSigMessage suspicious_vsss = 2;
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
28
tss/error.go
28
tss/error.go
@@ -19,6 +19,12 @@ type Error struct {
|
||||
culprits []*PartyID
|
||||
}
|
||||
|
||||
type VictimAndCulprit struct {
|
||||
Victim *PartyID
|
||||
Culprit *PartyID
|
||||
Message string
|
||||
}
|
||||
|
||||
func NewError(err error, task string, round int, victim *PartyID, culprits ...*PartyID) *Error {
|
||||
return &Error{cause: err, task: task, round: round, victim: victim, culprits: culprits}
|
||||
}
|
||||
@@ -47,6 +53,24 @@ func (err *Error) Error() string {
|
||||
return fmt.Sprintf("task %s, party %v, round %d, culprits %s: %s",
|
||||
err.task, err.victim, err.round, err.culprits, err.cause.Error())
|
||||
}
|
||||
return fmt.Sprintf("task %s, party %v, round %d: %s",
|
||||
err.task, err.victim, err.round, err.cause.Error())
|
||||
if err.victim != nil {
|
||||
return fmt.Sprintf("task %s, party %v, round %d: %s",
|
||||
err.task, err.victim, err.round, err.cause.Error())
|
||||
}
|
||||
return fmt.Sprintf("task %s, round %d: %s",
|
||||
err.task, err.round, err.cause.Error())
|
||||
}
|
||||
|
||||
func (vc *VictimAndCulprit) Error() string {
|
||||
message := ""
|
||||
if vc.Culprit != nil {
|
||||
message = fmt.Sprintf("culprit party: %s", vc.Culprit)
|
||||
}
|
||||
if vc.Victim != nil {
|
||||
message = message + fmt.Sprintf(" victim party: %s", vc.Victim)
|
||||
}
|
||||
if len(vc.Message) > 0 {
|
||||
message = message + " " + vc.Message
|
||||
}
|
||||
return message
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user