github.com/annchain/OG@v0.0.9/consensus/dkg/dkg_context.go (about) 1 // Copyright © 2019 Annchain Authors <EMAIL ADDRESS> 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 package dkg 15 16 import ( 17 "errors" 18 "github.com/annchain/kyber/v3" 19 "github.com/annchain/kyber/v3/pairing/bn256" 20 "github.com/annchain/kyber/v3/share" 21 "github.com/annchain/kyber/v3/share/dkg/pedersen" 22 "github.com/annchain/kyber/v3/sign/bls" 23 "github.com/annchain/kyber/v3/sign/tbls" 24 ) 25 26 // DkgContext stores the DKG info collected from other peers. 27 // It can sign messages individually and recover the joint sig once enough peers share their partSigs 28 // It is the core algorithm of DKG 29 type DkgContext struct { 30 SessionId uint32 31 MyIndex uint32 32 Me PartSec 33 PartPubs []PartPub // must be ordered from the outside 34 35 //CandidatePartSec []kyber.Scalar 36 //CandidatePublicKey [][]byte 37 //addressIndex map[common.Address]int 38 //SecretKeyContribution map[common.Address]kyber.Scalar 39 Suite *bn256.Suite 40 Dkger *dkg.DistKeyGenerator // backend algorithm 41 //Resps map[common.Address]*dkg.Response 42 //dealsIndex map[uint32]bool 43 Threshold int 44 NbParticipants int 45 JointPubKey kyber.Point 46 //responseNumber int 47 //SigShares [][]byte 48 KeyShare *dkg.DistKeyShare // cache of the DistKeyShare to avoid recovery multiple times 49 } 50 51 func NewDkgContext(s *bn256.Suite, termId uint32) *DkgContext { 52 c := &DkgContext{ 53 Suite: s, 54 //addressIndex: make(map[common.Address]int), 55 //SecretKeyContribution: make(map[common.Address]kyber.Scalar), 56 //Resps: make(map[common.Address]*dkg.Response), 57 SessionId: termId, 58 //dealsIndex: make(map[uint32]bool), 59 } 60 return c 61 } 62 63 // GenerateDKGer inits a dkg by all part-public keys and my part-private key 64 // Then it is possible to sign and verify data. 65 func (p *DkgContext) GenerateDKGer() error { 66 // use all partPubs and my partSec to generate a dkg 67 log.WithField("partPubLen", len(p.PartPubs)).Debug("generating DKGer") 68 participants := PartPubs(p.PartPubs).Points() 69 dkger, err := dkg.NewDistKeyGenerator(p.Suite, p.Me.Scalar, participants, p.Threshold) 70 if err != nil { 71 log.WithField("dkger", dkger).WithError(err).Error("generate dkg error") 72 return err 73 } 74 p.Dkger = dkger 75 p.KeyShare = nil 76 return nil 77 } 78 79 func (p *DkgContext) ensureKeyShare() (err error) { 80 dks := p.KeyShare 81 if dks == nil { 82 dks, err = p.Dkger.DistKeyShare() 83 if err != nil { 84 return 85 } 86 p.KeyShare = dks 87 } 88 return nil 89 } 90 91 // VerifyByPubPoly verifies signature for msg 92 func (p *DkgContext) VerifyByPubPoly(msg []byte, sig []byte) (err error) { 93 if err = p.ensureKeyShare(); err != nil { 94 return 95 } 96 pubPoly := share.NewPubPoly(p.Suite, p.Suite.Point().Base(), p.KeyShare.Commitments()) 97 98 //TODO: remove these check. It is only for debugging 99 if pubPoly.Commit() != p.KeyShare.Public() { 100 err = errors.New("PubPoly not aligned to dksPublic") 101 return 102 } 103 104 err = bls.Verify(p.Suite, pubPoly.Commit(), msg, sig) 105 log.Tracef(" pubPolyCommit [%s] dksPublic [%s] dksCommitments [%s]\n", 106 pubPoly.Commit(), p.KeyShare.Public(), p.KeyShare.Commitments()) 107 return 108 } 109 110 // VerifyByDksPublic verifies signature for msg 111 func (p *DkgContext) VerifyByDksPublic(msg []byte, sig []byte) (err error) { 112 if err = p.ensureKeyShare(); err != nil { 113 return 114 } 115 err = bls.Verify(p.Suite, p.KeyShare.Public(), msg, sig) 116 return 117 } 118 119 // RecoverSig builds a jointSignature from sigShares collected from enough participants 120 func (p *DkgContext) RecoverSig(msg []byte, sigShares [][]byte) (jointSig []byte, err error) { 121 if err = p.ensureKeyShare(); err != nil { 122 return 123 } 124 pubPoly := share.NewPubPoly(p.Suite, p.Suite.Point().Base(), p.KeyShare.Commitments()) 125 jointSig, err = tbls.Recover(p.Suite, pubPoly, msg, sigShares, p.Threshold, p.NbParticipants) 126 return 127 } 128 129 // RecoverPub builds a joint public key from keyshares collected from all other participants 130 func (p *DkgContext) RecoverPub() (jointPubKey kyber.Point, err error) { 131 if err = p.ensureKeyShare(); err != nil { 132 return 133 } 134 pubPoly := share.NewPubPoly(p.Suite, p.Suite.Point().Base(), p.KeyShare.Commitments()) 135 jointPubKey = pubPoly.Commit() 136 p.JointPubKey = jointPubKey 137 return 138 } 139 140 // PartSig signs the message into a single sigShare. 141 func (p *DkgContext) PartSig(msg []byte) (partSig []byte, err error) { 142 if err = p.ensureKeyShare(); err != nil { 143 return 144 } 145 partSig, err = tbls.Sign(p.Suite, p.KeyShare.PriShare(), msg) 146 return 147 }