Skip to content

Commit

Permalink
Working DKG after new DealCertified()
Browse files Browse the repository at this point in the history
  • Loading branch information
CedricCook committed Dec 11, 2017
1 parent 780cc89 commit 470e0fe
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 67 deletions.
14 changes: 10 additions & 4 deletions share/dkg/rabin/dkg.go
Original file line number Diff line number Diff line change
Expand Up @@ -242,11 +242,17 @@ func (d *DistKeyGenerator) Deals() (map[int]*Deal, error) {
// already processed our own deal
continue
}
if resp, err := d.ProcessDeal(distd); err != nil {

resp, err := d.ProcessDeal(distd)
if err != nil {
panic(err)
} else if !resp.Response.Approved {
panic("dkg: own deal gave a complaint")
}

// If processed own deal correctly, set positive response in this
// DKG's dealer's own verifier
d.dealer.UnsafeSetResponseDKG(d.index, true)
continue
}
dd[i] = distd
Expand Down Expand Up @@ -281,9 +287,9 @@ func (d *DistKeyGenerator) ProcessDeal(dd *Deal) (*Response, error) {
return nil, err
}

// Set StatusApproval for the verifier that represents the participant
// that distibuted the Deal
d.verifiers[dd.Index].UnsafeSetResponseDKG(dd.Index, true)
// Set StatusApproval for the verifier that represents the participant
// that distibuted the Deal
d.verifiers[dd.Index].UnsafeSetResponseDKG(dd.Index, true)

return &Response{
Index: dd.Index,
Expand Down
64 changes: 37 additions & 27 deletions share/vss/rabin/vss.go
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,18 @@ func (d *Dealer) ProcessResponse(r *Response) (*Justification, error) {
return j, nil
}

// UnsafeSetResponseDKG is an UNSAFE bypass method to allow DKG to use VSS
// that works on basis of approval only.
func (d *Dealer) UnsafeSetResponseDKG(idx uint32, approval bool) {
r := &Response{
SessionID: d.aggregator.sid,
Index: uint32(idx),
Approved: approval,
}

d.aggregator.addResponse(r)
}

// SecretCommit returns the commitment of the secret being shared by this
// dealer. This function is only to be called once the deal has enough approvals
// and is verified otherwise it returns nil.
Expand Down Expand Up @@ -309,7 +321,7 @@ func (d *Dealer) SessionID() []byte {
// it calls cleanVerifiers which will take care of all Verifiers who have not
// responded until now.
func (d *Dealer) SetTimeout() {
d.aggregator.cleanVerifiers()
d.aggregator.cleanVerifiers()
}

// Verifier receives a Deal from a Dealer, can reply with a Complaint, and can
Expand Down Expand Up @@ -501,22 +513,21 @@ func RecoverSecret(suite Suite, deals []*Deal, n, t int) (kyber.Scalar, error) {
// it calls cleanVerifiers which will take care of all Verifiers who have not
// responded until now.
func (v *Verifier) SetTimeout() {
v.aggregator.cleanVerifiers()
v.aggregator.cleanVerifiers()
}

// UnsafeSetResponseDKG is an UNSAFE bypass method to allow DKG to use VSS
// that works on basis of approval only.
func (v *Verifier) UnsafeSetResponseDKG(idx uint32, approval bool) {
r := &Response{
SessionID: v.aggregator.sid,
Index: uint32(idx),
Approved: approval,
}
r := &Response{
SessionID: v.aggregator.sid,
Index: uint32(idx),
Approved: approval,
}

v.aggregator.addResponse(r)
v.aggregator.addResponse(r)
}


// aggregator is used to collect all deals, and responses for one protocol run.
// It brings common functionalities for both Dealer and Verifier structs.
type aggregator struct {
Expand Down Expand Up @@ -595,16 +606,16 @@ func (a *aggregator) VerifyDeal(d *Deal, inclusion bool) error {
// cleanVerifiers checks the aggregator's response array and creates a StatusComplaint
// response for all verifiers who have no response in the array.
func (a *aggregator) cleanVerifiers() {
for i := range a.verifiers {
if _, ok := a.responses[uint32(i)]; !ok {
a.responses[uint32(i)] = &Response{
SessionID: a.sid,
Index: uint32(i),
Approved: false,
}
}
}
}
for i := range a.verifiers {
if _, ok := a.responses[uint32(i)]; !ok {
a.responses[uint32(i)] = &Response{
SessionID: a.sid,
Index: uint32(i),
Approved: false,
}
}
}
}

func (a *aggregator) verifyResponse(r *Response) error {
if !bytes.Equal(r.SessionID, a.sid) {
Expand Down Expand Up @@ -676,14 +687,13 @@ func (a *aggregator) DealCertified() bool {
}

var verifiersUnstable int
// Check either a StatusApproval or StatusComplaint for all known verifiers
// i.e. make sure all verifiers are either timed-out or OK.
for i := range a.verifiers {
if _, ok := a.responses[uint32(i)]; !ok {
verifiersUnstable++
fmt.Println("Verifier ", i, " unstable")
}
}
// Check either a StatusApproval or StatusComplaint for all known verifiers
// i.e. make sure all verifiers are either timed-out or OK.
for i := range a.verifiers {
if _, ok := a.responses[uint32(i)]; !ok {
verifiersUnstable++
}
}

tooMuchComplaints := verifiersUnstable > 0 || a.badDealer
return a.EnoughApprovals() && !tooMuchComplaints
Expand Down
72 changes: 36 additions & 36 deletions share/vss/rabin/vss_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ func TestVSSShare(t *testing.T) {
aggr.responses[uint32(i)] = &Response{Approved: true}
}

ver.SetTimeout()
ver.SetTimeout()

// not enough approvals
assert.Nil(t, ver.Deal())
Expand All @@ -138,7 +138,7 @@ func TestVSSAggregatorEnoughApprovals(t *testing.T) {
aggr.responses[uint32(i)] = &Response{Approved: true}
}

dealer.SetTimeout()
dealer.SetTimeout()

assert.False(t, aggr.EnoughApprovals())
assert.Nil(t, dealer.SecretCommit())
Expand All @@ -161,7 +161,7 @@ func TestVSSAggregatorDealCertified(t *testing.T) {
aggr.responses[uint32(i)] = &Response{Approved: true}
}

dealer.SetTimeout()
dealer.SetTimeout()

assert.True(t, aggr.DealCertified())
assert.Equal(t, suite.Point().Mul(secret, nil), dealer.SecretCommit())
Expand Down Expand Up @@ -471,62 +471,62 @@ func TestVSSAggregatorAddComplaint(t *testing.T) {
}

func TestVSSAggregatorCleanVerifiers(t *testing.T) {
dealer := genDealer()
aggr := dealer.aggregator
dealer := genDealer()
aggr := dealer.aggregator

for i := 0; i < aggr.t; i++ {
aggr.responses[uint32(i)] = &Response{Approved: true}
}
for i := 0; i < aggr.t; i++ {
aggr.responses[uint32(i)] = &Response{Approved: true}
}

assert.True(t, aggr.EnoughApprovals())
assert.False(t, aggr.DealCertified())
assert.True(t, aggr.EnoughApprovals())
assert.False(t, aggr.DealCertified())

aggr.cleanVerifiers()
aggr.cleanVerifiers()

assert.True(t, aggr.DealCertified())
assert.True(t, aggr.DealCertified())
}

func TestVSSDealerSetTimeout(t *testing.T) {
dealer := genDealer()
aggr := dealer.aggregator
dealer := genDealer()
aggr := dealer.aggregator

for i := 0; i < aggr.t; i++ {
aggr.responses[uint32(i)] = &Response{Approved: true}
}
for i := 0; i < aggr.t; i++ {
aggr.responses[uint32(i)] = &Response{Approved: true}
}

assert.True(t, aggr.EnoughApprovals())
assert.False(t, aggr.DealCertified())
assert.True(t, aggr.EnoughApprovals())
assert.False(t, aggr.DealCertified())

dealer.SetTimeout()
dealer.SetTimeout()

assert.True(t, aggr.DealCertified())
assert.True(t, aggr.DealCertified())
}

func TestVSSVerifierSetTimeout(t *testing.T) {
dealer, verifiers := genAll()
ver := verifiers[0]
dealer, verifiers := genAll()
ver := verifiers[0]

encD, err := dealer.EncryptedDeal(0)
encD, err := dealer.EncryptedDeal(0)

require.Nil(t, err)
require.Nil(t, err)

resp, err := ver.ProcessEncryptedDeal(encD)
resp, err := ver.ProcessEncryptedDeal(encD)

require.Nil(t, err)
require.NotNil(t, resp)
require.Nil(t, err)
require.NotNil(t, resp)

aggr := ver.aggregator
aggr := ver.aggregator

for i := 0; i < aggr.t; i++ {
aggr.responses[uint32(i)] = &Response{Approved: true}
}
for i := 0; i < aggr.t; i++ {
aggr.responses[uint32(i)] = &Response{Approved: true}
}

assert.True(t, aggr.EnoughApprovals())
assert.False(t, aggr.DealCertified())
assert.True(t, aggr.EnoughApprovals())
assert.False(t, aggr.DealCertified())

ver.SetTimeout()
ver.SetTimeout()

assert.True(t, aggr.DealCertified())
assert.True(t, aggr.DealCertified())
}

func TestVSSSessionID(t *testing.T) {
Expand Down

0 comments on commit 470e0fe

Please sign in to comment.