mirror of
https://github.com/SwingbyProtocol/tss-lib.git
synced 2026-01-09 13:57:58 -05:00
keygen: adding a Schnorr proof in round 1. Adding missing ridi and rid. Adding Xi and Ai to the hashes and messages. Adding Schnorr zkp in round 3. Adding proof verifications in round 4.
This commit is contained in:
@@ -54,20 +54,59 @@ func NewProof(X *crypto.ECPoint, x *big.Int) (*ProofSch, error) {
|
||||
return &ProofSch{A: A, Z: z}, nil
|
||||
}
|
||||
|
||||
// NewProof implements proofsch
|
||||
func NewProofWithAlpha(X *crypto.ECPoint, x *big.Int, alpha *big.Int, aux *big.Int) (*ProofSch, error) {
|
||||
if x == nil || X == nil || !X.ValidateBasic() {
|
||||
return nil, errors.New("zkpsch constructor received nil or invalid value(s)")
|
||||
}
|
||||
ec := X.Curve()
|
||||
q := ec.Params().N
|
||||
g := crypto.NewECPointNoCurveCheck(ec, ec.Params().Gx, ec.Params().Gy) // already on the curve.
|
||||
|
||||
// Fig 22.1
|
||||
A := crypto.ScalarBaseMult(ec, alpha)
|
||||
|
||||
// Fig 22.2 e
|
||||
var e *big.Int
|
||||
{
|
||||
eHash := common.SHA512_256i(X.X(), X.Y(), g.X(), g.Y(), A.X(), A.Y(), aux)
|
||||
e = common.RejectionSample(q, eHash)
|
||||
}
|
||||
|
||||
// Fig 22.3
|
||||
z := new(big.Int).Mul(e, x)
|
||||
z = common.ModInt(q).Add(alpha, z)
|
||||
|
||||
return &ProofSch{A: A, Z: z}, nil
|
||||
}
|
||||
|
||||
func NewProofCommitment(X *crypto.ECPoint, x *big.Int) (*crypto.ECPoint, *big.Int, error) {
|
||||
if x == nil || X == nil || !X.ValidateBasic() {
|
||||
return nil, nil, errors.New("zkpsch constructor received nil or invalid value(s)")
|
||||
}
|
||||
ec := X.Curve()
|
||||
q := ec.Params().N
|
||||
|
||||
// Fig 22.1
|
||||
alpha := common.GetRandomPositiveInt(q)
|
||||
A := crypto.ScalarBaseMult(ec, alpha)
|
||||
return A, alpha, nil
|
||||
}
|
||||
|
||||
func NewProofFromBytes(ec elliptic.Curve, bzs [][]byte) (*ProofSch, error) {
|
||||
if !common.NonEmptyMultiBytes(bzs, ProofSchBytesParts) {
|
||||
return nil, fmt.Errorf("expected %d byte parts to construct ProofSch", ProofSchBytesParts)
|
||||
}
|
||||
if !common.NonEmptyMultiBytes(bzs, ProofSchBytesParts) {
|
||||
return nil, fmt.Errorf("expected %d byte parts to construct ProofSch", ProofSchBytesParts)
|
||||
}
|
||||
point, err := crypto.NewECPoint(ec,
|
||||
new(big.Int).SetBytes(bzs[0]),
|
||||
new(big.Int).SetBytes(bzs[1]))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &ProofSch{
|
||||
A: point,
|
||||
Z: new(big.Int).SetBytes(bzs[2]),
|
||||
}, nil
|
||||
new(big.Int).SetBytes(bzs[0]),
|
||||
new(big.Int).SetBytes(bzs[1]))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &ProofSch{
|
||||
A: point,
|
||||
Z: new(big.Int).SetBytes(bzs[2]),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (pf *ProofSch) Verify(X *crypto.ECPoint) bool {
|
||||
@@ -97,14 +136,41 @@ func (pf *ProofSch) Verify(X *crypto.ECPoint) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (pf *ProofSch) VerifyWithAux(X *crypto.ECPoint, aux *big.Int) bool {
|
||||
if pf == nil || !pf.ValidateBasic() || X == nil {
|
||||
return false
|
||||
}
|
||||
ec := X.Curve()
|
||||
q := ec.Params().N
|
||||
g := crypto.NewECPointNoCurveCheck(ec, ec.Params().Gx, ec.Params().Gy)
|
||||
|
||||
var e *big.Int
|
||||
{
|
||||
eHash := common.SHA512_256i(X.X(), X.Y(), g.X(), g.Y(), pf.A.X(), pf.A.Y(), aux)
|
||||
e = common.RejectionSample(q, eHash)
|
||||
}
|
||||
|
||||
// Fig 22. Verification
|
||||
left := crypto.ScalarBaseMult(ec, pf.Z)
|
||||
XEXPe := X.ScalarMult(e)
|
||||
right, err := pf.A.Add(XEXPe)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
if right.X().Cmp(left.X()) != 0 || right.Y().Cmp(left.Y()) != 0 {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (pf *ProofSch) ValidateBasic() bool {
|
||||
return pf.Z != nil && pf.A != nil
|
||||
}
|
||||
|
||||
func (pf *ProofSch) Bytes() [ProofSchBytesParts][]byte {
|
||||
return [...][]byte{
|
||||
pf.A.X().Bytes(),
|
||||
pf.A.Y().Bytes(),
|
||||
pf.Z.Bytes(),
|
||||
}
|
||||
return [...][]byte{
|
||||
pf.A.X().Bytes(),
|
||||
pf.A.Y().Bytes(),
|
||||
pf.Z.Bytes(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.27.1
|
||||
// protoc v3.17.3
|
||||
// protoc v3.18.1
|
||||
// source: protob/ecdsa-keygen.proto
|
||||
|
||||
package keygen
|
||||
@@ -87,6 +87,9 @@ type KGRound2Message struct {
|
||||
NTilde []byte `protobuf:"bytes,3,opt,name=n_tilde,json=nTilde,proto3" json:"n_tilde,omitempty"`
|
||||
H1 []byte `protobuf:"bytes,4,opt,name=h1,proto3" json:"h1,omitempty"`
|
||||
H2 []byte `protobuf:"bytes,5,opt,name=h2,proto3" json:"h2,omitempty"`
|
||||
Ridi []byte `protobuf:"bytes,6,opt,name=ridi,proto3" json:"ridi,omitempty"`
|
||||
Ai [][]byte `protobuf:"bytes,7,rep,name=Ai,proto3" json:"Ai,omitempty"`
|
||||
Xi [][]byte `protobuf:"bytes,8,rep,name=Xi,proto3" json:"Xi,omitempty"`
|
||||
}
|
||||
|
||||
func (x *KGRound2Message) Reset() {
|
||||
@@ -156,6 +159,27 @@ func (x *KGRound2Message) GetH2() []byte {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *KGRound2Message) GetRidi() []byte {
|
||||
if x != nil {
|
||||
return x.Ridi
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *KGRound2Message) GetAi() [][]byte {
|
||||
if x != nil {
|
||||
return x.Ai
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *KGRound2Message) GetXi() [][]byte {
|
||||
if x != nil {
|
||||
return x.Xi
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//
|
||||
// Represents a P2P message sent to each party during Round 2 of the ECDSA TSS keygen protocol.
|
||||
type KGRound3Message struct {
|
||||
@@ -163,9 +187,10 @@ type KGRound3Message struct {
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Share []byte `protobuf:"bytes,1,opt,name=share,proto3" json:"share,omitempty"`
|
||||
ModProof [][]byte `protobuf:"bytes,2,rep,name=mod_proof,json=modProof,proto3" json:"mod_proof,omitempty"`
|
||||
PrmProof [][]byte `protobuf:"bytes,3,rep,name=prm_proof,json=prmProof,proto3" json:"prm_proof,omitempty"`
|
||||
Share []byte `protobuf:"bytes,1,opt,name=share,proto3" json:"share,omitempty"`
|
||||
ModProof [][]byte `protobuf:"bytes,2,rep,name=mod_proof,json=modProof,proto3" json:"mod_proof,omitempty"`
|
||||
PrmProof [][]byte `protobuf:"bytes,3,rep,name=prm_proof,json=prmProof,proto3" json:"prm_proof,omitempty"`
|
||||
PsiiProof [][]byte `protobuf:"bytes,4,rep,name=psii_proof,json=psiiProof,proto3" json:"psii_proof,omitempty"`
|
||||
}
|
||||
|
||||
func (x *KGRound3Message) Reset() {
|
||||
@@ -221,6 +246,13 @@ func (x *KGRound3Message) GetPrmProof() [][]byte {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *KGRound3Message) GetPsiiProof() [][]byte {
|
||||
if x != nil {
|
||||
return x.PsiiProof
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//
|
||||
// Represents a BROADCAST message sent to each party during Round 3 of the ECDSA TSS keygen protocol.
|
||||
type KGRound4Message struct {
|
||||
@@ -279,24 +311,30 @@ var file_protob_ecdsa_keygen_proto_rawDesc = []byte{
|
||||
0x61, 0x2e, 0x6b, 0x65, 0x79, 0x67, 0x65, 0x6e, 0x22, 0x27, 0x0a, 0x0f, 0x4b, 0x47, 0x52, 0x6f,
|
||||
0x75, 0x6e, 0x64, 0x31, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x56,
|
||||
0x48, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x56, 0x48, 0x61, 0x73,
|
||||
0x68, 0x22, 0x79, 0x0a, 0x0f, 0x4b, 0x47, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x32, 0x4d, 0x65, 0x73,
|
||||
0x73, 0x61, 0x67, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x76, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c,
|
||||
0x52, 0x02, 0x76, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x61, 0x69, 0x6c, 0x6c, 0x69, 0x65, 0x72,
|
||||
0x5f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x70, 0x61, 0x69, 0x6c, 0x6c, 0x69,
|
||||
0x65, 0x72, 0x4e, 0x12, 0x17, 0x0a, 0x07, 0x6e, 0x5f, 0x74, 0x69, 0x6c, 0x64, 0x65, 0x18, 0x03,
|
||||
0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6e, 0x54, 0x69, 0x6c, 0x64, 0x65, 0x12, 0x0e, 0x0a, 0x02,
|
||||
0x68, 0x31, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x68, 0x31, 0x12, 0x0e, 0x0a, 0x02,
|
||||
0x68, 0x32, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x68, 0x32, 0x22, 0x61, 0x0a, 0x0f,
|
||||
0x4b, 0x47, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x33, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12,
|
||||
0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05,
|
||||
0x73, 0x68, 0x61, 0x72, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x6f, 0x64, 0x5f, 0x70, 0x72, 0x6f,
|
||||
0x6f, 0x66, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x08, 0x6d, 0x6f, 0x64, 0x50, 0x72, 0x6f,
|
||||
0x6f, 0x66, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x72, 0x6d, 0x5f, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x18,
|
||||
0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x08, 0x70, 0x72, 0x6d, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x22,
|
||||
0x27, 0x0a, 0x0f, 0x4b, 0x47, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x34, 0x4d, 0x65, 0x73, 0x73, 0x61,
|
||||
0x67, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x18, 0x01, 0x20, 0x03, 0x28,
|
||||
0x0c, 0x52, 0x05, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x42, 0x0e, 0x5a, 0x0c, 0x65, 0x63, 0x64, 0x73,
|
||||
0x61, 0x2f, 0x6b, 0x65, 0x79, 0x67, 0x65, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x68, 0x22, 0xad, 0x01, 0x0a, 0x0f, 0x4b, 0x47, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x32, 0x4d, 0x65,
|
||||
0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x76, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28,
|
||||
0x0c, 0x52, 0x02, 0x76, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x61, 0x69, 0x6c, 0x6c, 0x69, 0x65,
|
||||
0x72, 0x5f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x70, 0x61, 0x69, 0x6c, 0x6c,
|
||||
0x69, 0x65, 0x72, 0x4e, 0x12, 0x17, 0x0a, 0x07, 0x6e, 0x5f, 0x74, 0x69, 0x6c, 0x64, 0x65, 0x18,
|
||||
0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6e, 0x54, 0x69, 0x6c, 0x64, 0x65, 0x12, 0x0e, 0x0a,
|
||||
0x02, 0x68, 0x31, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x68, 0x31, 0x12, 0x0e, 0x0a,
|
||||
0x02, 0x68, 0x32, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x68, 0x32, 0x12, 0x12, 0x0a,
|
||||
0x04, 0x72, 0x69, 0x64, 0x69, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x72, 0x69, 0x64,
|
||||
0x69, 0x12, 0x0e, 0x0a, 0x02, 0x41, 0x69, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x02, 0x41,
|
||||
0x69, 0x12, 0x0e, 0x0a, 0x02, 0x58, 0x69, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x02, 0x58,
|
||||
0x69, 0x22, 0x80, 0x01, 0x0a, 0x0f, 0x4b, 0x47, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x33, 0x4d, 0x65,
|
||||
0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x65, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x6d,
|
||||
0x6f, 0x64, 0x5f, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x08,
|
||||
0x6d, 0x6f, 0x64, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x72, 0x6d, 0x5f,
|
||||
0x70, 0x72, 0x6f, 0x6f, 0x66, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x08, 0x70, 0x72, 0x6d,
|
||||
0x50, 0x72, 0x6f, 0x6f, 0x66, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x73, 0x69, 0x69, 0x5f, 0x70, 0x72,
|
||||
0x6f, 0x6f, 0x66, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x09, 0x70, 0x73, 0x69, 0x69, 0x50,
|
||||
0x72, 0x6f, 0x6f, 0x66, 0x22, 0x27, 0x0a, 0x0f, 0x4b, 0x47, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x34,
|
||||
0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x72, 0x6f, 0x6f, 0x66,
|
||||
0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x05, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x42, 0x0e, 0x5a,
|
||||
0x0c, 0x65, 0x63, 0x64, 0x73, 0x61, 0x2f, 0x6b, 0x65, 0x79, 0x67, 0x65, 0x6e, 0x62, 0x06, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
|
||||
@@ -41,16 +41,25 @@ type (
|
||||
|
||||
localTempData struct {
|
||||
// temp data (thrown away after keygen)
|
||||
ui *big.Int // used for tests
|
||||
shares vss.Shares
|
||||
vs vss.Vs
|
||||
ui *big.Int // used for tests
|
||||
ridi *big.Int // used for tests
|
||||
rid *big.Int
|
||||
shares vss.Shares
|
||||
vs vss.Vs
|
||||
Ai *crypto.ECPoint
|
||||
Xi *crypto.ECPoint
|
||||
τ *big.Int
|
||||
|
||||
r1msgVHashs []*big.Int
|
||||
r2msgVss [][]*crypto.ECPoint
|
||||
r3msgxij []*big.Int
|
||||
r3msgpfmod []*zkpmod.ProofMod
|
||||
r3msgpfprm []*zkpprm.ProofPrm
|
||||
r4msgpf []*zkpsch.ProofSch
|
||||
r1msgVHashs []*big.Int
|
||||
r2msgVss [][]*crypto.ECPoint
|
||||
r2msgAj []*crypto.ECPoint
|
||||
r2msgXj []*crypto.ECPoint
|
||||
r2msgRidj []*big.Int
|
||||
r3msgxij []*big.Int
|
||||
r3msgpfmod []*zkpmod.ProofMod
|
||||
r3msgpfprm []*zkpprm.ProofPrm
|
||||
r3msgpfsch []*zkpsch.ProofSch
|
||||
r4msgpf []*zkpsch.ProofSch
|
||||
}
|
||||
)
|
||||
|
||||
@@ -84,9 +93,13 @@ func NewLocalParty(
|
||||
// msgs data init
|
||||
p.temp.r1msgVHashs = make([]*big.Int, partyCount)
|
||||
p.temp.r2msgVss = make([][]*crypto.ECPoint, partyCount)
|
||||
p.temp.r2msgAj = make([]*crypto.ECPoint, partyCount)
|
||||
p.temp.r2msgXj = make([]*crypto.ECPoint, partyCount)
|
||||
p.temp.r2msgRidj = make([]*big.Int, partyCount)
|
||||
p.temp.r3msgxij = make([]*big.Int, partyCount)
|
||||
p.temp.r3msgpfmod = make([]*zkpmod.ProofMod, partyCount)
|
||||
p.temp.r3msgpfprm = make([]*zkpprm.ProofPrm, partyCount)
|
||||
p.temp.r3msgpfsch = make([]*zkpsch.ProofSch, partyCount)
|
||||
p.temp.r4msgpf = make([]*zkpsch.ProofSch, partyCount)
|
||||
return p
|
||||
}
|
||||
@@ -145,6 +158,9 @@ func (p *LocalParty) StoreMessage(msg tss.ParsedMessage) (bool, *tss.Error) {
|
||||
p.data.H1j[fromPIdx], p.data.H2j[fromPIdx] = r2msg.UnmarshalH1(), r2msg.UnmarshalH2()
|
||||
var err error
|
||||
p.temp.r2msgVss[fromPIdx], err = r2msg.UnmarshalVs(p.params.EC())
|
||||
p.temp.r2msgAj[fromPIdx], err = r2msg.UnmarshalAi(p.params.EC())
|
||||
p.temp.r2msgXj[fromPIdx], err = r2msg.UnmarshalXi(p.params.EC())
|
||||
p.temp.r2msgRidj[fromPIdx] = r2msg.UnmarshalRidi()
|
||||
if err != nil {
|
||||
return false, p.WrapError(err)
|
||||
}
|
||||
@@ -174,6 +190,11 @@ func (p *LocalParty) StoreMessage(msg tss.ParsedMessage) (bool, *tss.Error) {
|
||||
// }
|
||||
p.temp.r3msgpfprm[fromPIdx] = proofPrm
|
||||
|
||||
proofSch, err := r3msg.UnmarshalProofSch(p.params.EC())
|
||||
if err != nil {
|
||||
return false, p.WrapError(err, p.params.Parties().IDs()[fromPIdx])
|
||||
}
|
||||
p.temp.r3msgpfsch[fromPIdx] = proofSch
|
||||
case *KGRound4Message:
|
||||
//p.temp.kgRound4Messages[fromPIdx] = msg
|
||||
r4msg := msg.Content().(*KGRound4Message)
|
||||
|
||||
@@ -65,7 +65,8 @@ func NewKGRound2Message(
|
||||
from *tss.PartyID,
|
||||
vs vss.Vs,
|
||||
paillierPK *paillier.PublicKey,
|
||||
nTildeI, h1I, h2I *big.Int,
|
||||
nTildeI, h1I, h2I, ridi *big.Int,
|
||||
Ai, Xi *crypto.ECPoint,
|
||||
) tss.ParsedMessage {
|
||||
meta := tss.MessageRouting{
|
||||
From: from,
|
||||
@@ -73,15 +74,20 @@ func NewKGRound2Message(
|
||||
}
|
||||
vs_flat, _ := crypto.FlattenECPoints(vs)
|
||||
vsbzs := make([][]byte, len(vs_flat))
|
||||
for i, item := range(vs_flat) {
|
||||
for i, item := range vs_flat {
|
||||
vsbzs[i] = item.Bytes()
|
||||
}
|
||||
aiBytes := Ai.Bytes()
|
||||
XiBytes := Xi.Bytes()
|
||||
content := &KGRound2Message{
|
||||
Vs: vsbzs[:],
|
||||
PaillierN: paillierPK.N.Bytes(),
|
||||
NTilde: nTildeI.Bytes(),
|
||||
H1: h1I.Bytes(),
|
||||
H2: h2I.Bytes(),
|
||||
Vs: vsbzs[:],
|
||||
PaillierN: paillierPK.N.Bytes(),
|
||||
NTilde: nTildeI.Bytes(),
|
||||
H1: h1I.Bytes(),
|
||||
H2: h2I.Bytes(),
|
||||
Ridi: ridi.Bytes(),
|
||||
Ai: aiBytes[:],
|
||||
Xi: XiBytes[:],
|
||||
}
|
||||
msg := tss.NewMessageWrapper(meta, content)
|
||||
return tss.NewMessage(meta, content, msg)
|
||||
@@ -92,13 +98,15 @@ func (m *KGRound2Message) ValidateBasic() bool {
|
||||
common.NonEmptyBytes(m.GetPaillierN()) &&
|
||||
common.NonEmptyBytes(m.GetNTilde()) &&
|
||||
common.NonEmptyBytes(m.GetH1()) &&
|
||||
common.NonEmptyBytes(m.GetH2())
|
||||
common.NonEmptyBytes(m.GetH2()) &&
|
||||
common.NonEmptyMultiBytes(m.GetAi()) &&
|
||||
common.NonEmptyMultiBytes(m.GetXi())
|
||||
}
|
||||
|
||||
func (m *KGRound2Message) UnmarshalVs(ec elliptic.Curve) ([]*crypto.ECPoint, error) {
|
||||
bzs := m.GetVs()
|
||||
vs_points := make([]*big.Int, len(bzs))
|
||||
for i, item := range(m.GetVs()) {
|
||||
for i, item := range m.GetVs() {
|
||||
vs_points[i] = new(big.Int).SetBytes(item)
|
||||
}
|
||||
vs, err := crypto.UnFlattenECPoints(ec, vs_points)
|
||||
@@ -124,6 +132,18 @@ func (m *KGRound2Message) UnmarshalH2() *big.Int {
|
||||
return new(big.Int).SetBytes(m.GetH2())
|
||||
}
|
||||
|
||||
func (m *KGRound2Message) UnmarshalAi(ec elliptic.Curve) (*crypto.ECPoint, error) {
|
||||
return crypto.NewECPointFromBytes(ec, m.GetAi())
|
||||
}
|
||||
|
||||
func (m *KGRound2Message) UnmarshalXi(ec elliptic.Curve) (*crypto.ECPoint, error) {
|
||||
return crypto.NewECPointFromBytes(ec, m.GetXi())
|
||||
}
|
||||
|
||||
func (m *KGRound2Message) UnmarshalRidi() *big.Int {
|
||||
return new(big.Int).SetBytes(m.GetRidi())
|
||||
}
|
||||
|
||||
// ----- //
|
||||
|
||||
func NewKGRound3Message(
|
||||
@@ -131,6 +151,7 @@ func NewKGRound3Message(
|
||||
share *big.Int,
|
||||
proofMod *zkpmod.ProofMod,
|
||||
proofPrm *zkpprm.ProofPrm,
|
||||
ψi *zkpsch.ProofSch,
|
||||
) tss.ParsedMessage {
|
||||
meta := tss.MessageRouting{
|
||||
From: from,
|
||||
@@ -139,10 +160,12 @@ func NewKGRound3Message(
|
||||
}
|
||||
proofModBzs := proofMod.Bytes()
|
||||
proofPrmBzs := proofPrm.Bytes()
|
||||
proofPsiiBzs := ψi.Bytes()
|
||||
content := &KGRound3Message{
|
||||
Share: share.Bytes(),
|
||||
ModProof: proofModBzs[:],
|
||||
PrmProof: proofPrmBzs[:],
|
||||
Share: share.Bytes(),
|
||||
ModProof: proofModBzs[:],
|
||||
PrmProof: proofPrmBzs[:],
|
||||
PsiiProof: proofPsiiBzs[:],
|
||||
}
|
||||
msg := tss.NewMessageWrapper(meta, content)
|
||||
return tss.NewMessage(meta, content, msg)
|
||||
@@ -152,7 +175,8 @@ func (m *KGRound3Message) ValidateBasic() bool {
|
||||
return m != nil &&
|
||||
common.NonEmptyBytes(m.GetShare()) &&
|
||||
common.NonEmptyMultiBytes(m.GetModProof(), zkpmod.ProofModBytesParts) &&
|
||||
common.NonEmptyMultiBytes(m.GetPrmProof(), zkpprm.ProofPrmBytesParts)
|
||||
common.NonEmptyMultiBytes(m.GetPrmProof(), zkpprm.ProofPrmBytesParts) &&
|
||||
common.NonEmptyMultiBytes(m.GetPsiiProof(), zkpsch.ProofSchBytesParts)
|
||||
}
|
||||
|
||||
func (m *KGRound3Message) UnmarshalShare() *big.Int {
|
||||
@@ -167,6 +191,10 @@ func (m *KGRound3Message) UnmarshalProofPrm() (*zkpprm.ProofPrm, error) {
|
||||
return zkpprm.NewProofFromBytes(m.GetPrmProof())
|
||||
}
|
||||
|
||||
func (m *KGRound3Message) UnmarshalProofSch(ec elliptic.Curve) (*zkpsch.ProofSch, error) {
|
||||
return zkpsch.NewProofFromBytes(ec, m.GetPsiiProof())
|
||||
}
|
||||
|
||||
// ----- //
|
||||
|
||||
func NewKGRound4Message(
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
"github.com/binance-chain/tss-lib/common"
|
||||
"github.com/binance-chain/tss-lib/crypto"
|
||||
"github.com/binance-chain/tss-lib/crypto/vss"
|
||||
zkpsch "github.com/binance-chain/tss-lib/crypto/zkp/sch"
|
||||
"github.com/binance-chain/tss-lib/tss"
|
||||
)
|
||||
|
||||
@@ -38,6 +39,7 @@ func (round *round1) Start() *tss.Error {
|
||||
round.ok[i] = true
|
||||
|
||||
// Fig 5. Round 1. private key part
|
||||
ridi := common.GetRandomPositiveInt(round.EC().Params().N)
|
||||
ui := common.GetRandomPositiveInt(round.EC().Params().N)
|
||||
|
||||
// Fig 5. Round 1. pub key part, vss shares
|
||||
@@ -46,6 +48,9 @@ func (round *round1) Start() *tss.Error {
|
||||
if err != nil {
|
||||
return round.WrapError(err, Pi)
|
||||
}
|
||||
xi := new(big.Int).Set(shares[i].Share)
|
||||
Xi := crypto.ScalarBaseMult(round.EC(), xi)
|
||||
Ai, τ, _ := zkpsch.NewProofCommitment(Xi, xi)
|
||||
|
||||
// Fig 6. Round 1.
|
||||
var preParams *LocalPreParams
|
||||
@@ -62,7 +67,7 @@ func (round *round1) Start() *tss.Error {
|
||||
if err != nil {
|
||||
return round.WrapError(err, Pi)
|
||||
}
|
||||
listToHash = append(listToHash, preParams.PaillierSK.PublicKey.N, preParams.NTildei, preParams.H1i, preParams.H2i)
|
||||
listToHash = append(listToHash, preParams.PaillierSK.PublicKey.N, ridi, Xi.X(), Xi.Y(), Ai.X(), Ai.Y(), preParams.NTildei, preParams.H1i, preParams.H2i)
|
||||
VHash := common.SHA512_256i(listToHash...)
|
||||
{
|
||||
msg := NewKGRound1Message(round.PartyID(), VHash)
|
||||
@@ -70,7 +75,10 @@ func (round *round1) Start() *tss.Error {
|
||||
}
|
||||
|
||||
round.temp.vs = vs
|
||||
round.temp.ridi = ridi
|
||||
round.temp.ui = ui
|
||||
round.temp.Ai = Ai
|
||||
round.temp.τ = τ
|
||||
round.save.Ks = ids
|
||||
round.save.LocalPreParams = *preParams
|
||||
round.save.NTildej[i] = preParams.NTildei
|
||||
|
||||
@@ -8,7 +8,9 @@ package keygen
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"math/big"
|
||||
|
||||
"github.com/binance-chain/tss-lib/crypto"
|
||||
"github.com/binance-chain/tss-lib/tss"
|
||||
)
|
||||
|
||||
@@ -26,7 +28,10 @@ func (round *round2) Start() *tss.Error {
|
||||
|
||||
// Fig 5. Round 2. / Fig 6. Round 2.
|
||||
{
|
||||
msg := NewKGRound2Message(round.PartyID(), round.temp.vs, &round.save.PaillierSK.PublicKey, round.save.NTildei, round.save.H1i, round.save.H2i)
|
||||
xi := new(big.Int).Set(round.temp.shares[i].Share)
|
||||
Xi := crypto.ScalarBaseMult(round.EC(), xi)
|
||||
msg := NewKGRound2Message(round.PartyID(), round.temp.vs, &round.save.PaillierSK.PublicKey, round.save.NTildei,
|
||||
round.save.H1i, round.save.H2i, round.temp.ridi, round.temp.Ai, Xi)
|
||||
round.out <- msg
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
|
||||
"github.com/binance-chain/tss-lib/common"
|
||||
"github.com/binance-chain/tss-lib/crypto"
|
||||
zkpsch "github.com/binance-chain/tss-lib/crypto/zkp/sch"
|
||||
"github.com/binance-chain/tss-lib/tss"
|
||||
|
||||
zkpmod "github.com/binance-chain/tss-lib/crypto/zkp/mod"
|
||||
@@ -38,11 +39,13 @@ func (round *round3) Start() *tss.Error {
|
||||
// Fig 5. Round 3.1 / Fig 6. Round 3.1
|
||||
toCmp := new(big.Int).Lsh(big.NewInt(1), 1024)
|
||||
errChs := make(chan *tss.Error, (len(round.Parties().IDs())-1)*3)
|
||||
rid := round.temp.ridi
|
||||
wg := sync.WaitGroup{}
|
||||
for j, Pj := range round.Parties().IDs() {
|
||||
if j == i {
|
||||
continue
|
||||
}
|
||||
rid = new(big.Int).Xor(rid, round.temp.r2msgRidj[j])
|
||||
wg.Add(1)
|
||||
go func(j int, Pj *tss.PartyID) {
|
||||
defer wg.Done()
|
||||
@@ -60,7 +63,10 @@ func (round *round3) Start() *tss.Error {
|
||||
errChs <- round.WrapError(err, Pj)
|
||||
return
|
||||
}
|
||||
listToHash = append(listToHash, round.save.PaillierPKs[j].N, round.save.NTildej[j], round.save.H1j[j], round.save.H2j[j])
|
||||
listToHash = append(listToHash, round.save.PaillierPKs[j].N, round.temp.r2msgRidj[j],
|
||||
round.temp.r2msgXj[j].X(), round.temp.r2msgXj[j].Y(),
|
||||
round.temp.r2msgAj[j].X(), round.temp.r2msgAj[j].Y(), round.save.NTildej[j], round.save.H1j[j],
|
||||
round.save.H2j[j])
|
||||
VjHash := common.SHA512_256i(listToHash...)
|
||||
if VjHash.Cmp(round.temp.r1msgVHashs[j]) != 0 {
|
||||
errChs <- round.WrapError(errors.New("verify hash failed"), Pj)
|
||||
@@ -68,6 +74,7 @@ func (round *round3) Start() *tss.Error {
|
||||
}
|
||||
}(j, Pj)
|
||||
}
|
||||
round.temp.rid = rid
|
||||
wg.Wait()
|
||||
close(errChs)
|
||||
culprits := make([]*tss.PartyID, 0)
|
||||
@@ -88,6 +95,12 @@ func (round *round3) Start() *tss.Error {
|
||||
if err != nil {
|
||||
return round.WrapError(errors.New("create proofPrm failed"))
|
||||
}
|
||||
xi := new(big.Int).Set(round.temp.shares[i].Share)
|
||||
Xi := crypto.ScalarBaseMult(round.EC(), xi)
|
||||
ψi, err := zkpsch.NewProofWithAlpha(Xi, xi, round.temp.τ, rid)
|
||||
if err != nil {
|
||||
return round.WrapError(errors.New("create proofSch failed"))
|
||||
}
|
||||
|
||||
errChs = make(chan *tss.Error, len(round.Parties().IDs())-1)
|
||||
wg = sync.WaitGroup{}
|
||||
@@ -104,8 +117,8 @@ func (round *round3) Start() *tss.Error {
|
||||
errChs <- round.WrapError(errors.New("encrypt error"), Pi)
|
||||
return
|
||||
}
|
||||
|
||||
r3msg := NewKGRound3Message(Pj, round.PartyID(), Cij, proofMod, proofPrm)
|
||||
|
||||
r3msg := NewKGRound3Message(Pj, round.PartyID(), Cij, proofMod, proofPrm, ψi)
|
||||
round.out <- r3msg
|
||||
}(j, Pj)
|
||||
}
|
||||
|
||||
@@ -45,6 +45,14 @@ func (round *round4) Start() *tss.Error {
|
||||
}
|
||||
}(j, Pj)
|
||||
|
||||
wg.Add(1)
|
||||
go func(j int, Pj *tss.PartyID) {
|
||||
defer wg.Done()
|
||||
if ok := round.temp.r3msgpfsch[j].A.Equals(round.temp.r2msgAj[j]); !ok { // Verify A^j = Aj
|
||||
errChs <- round.WrapError(errors.New(" A^j != Aj"), Pj)
|
||||
}
|
||||
}(j, Pj)
|
||||
|
||||
wg.Add(1)
|
||||
go func(j int, Pj *tss.PartyID) {
|
||||
defer wg.Done()
|
||||
@@ -132,6 +140,20 @@ func (round *round4) Start() *tss.Error {
|
||||
return round.WrapError(errors.New("adding Vc[c].ScalarMult(z) to BigXj resulted in a point not on the curve"), culprits...)
|
||||
}
|
||||
}
|
||||
{
|
||||
culprits := make([]*tss.PartyID, 0)
|
||||
for j, Pj := range round.Parties().IDs() {
|
||||
if j == i {
|
||||
continue
|
||||
}
|
||||
if ok := round.temp.r3msgpfsch[j].VerifyWithAux(round.temp.r2msgXj[j], round.temp.rid); !ok {
|
||||
culprits = append(culprits, Pj)
|
||||
}
|
||||
}
|
||||
if len(culprits) > 0 {
|
||||
return round.WrapError(errors.New("schnorr verification failed"), culprits...)
|
||||
}
|
||||
}
|
||||
|
||||
// Compute and SAVE the ECDSA public key `y`
|
||||
ecdsaPubKey, err := crypto.NewECPoint(round.Params().EC(), Vc[0].X(), Vc[0].Y())
|
||||
|
||||
@@ -24,6 +24,9 @@ message KGRound2Message {
|
||||
bytes n_tilde = 3;
|
||||
bytes h1 = 4;
|
||||
bytes h2 = 5;
|
||||
bytes ridi = 6;
|
||||
repeated bytes Ai = 7;
|
||||
repeated bytes Xi = 8;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -33,6 +36,7 @@ message KGRound3Message {
|
||||
bytes share = 1;
|
||||
repeated bytes mod_proof = 2;
|
||||
repeated bytes prm_proof = 3;
|
||||
repeated bytes psii_proof = 4;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user