aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/dexon-foundation/dexon-consensus/core/crypto/dkg/utils.go
blob: 9e470f0cf1b8e29f4a5b2d401d73a93df4a7f9ab (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
// Copyright 2018 The dexon-consensus Authors
// This file is part of the dexon-consensus library.
//
// The dexon-consensus library is free software: you can redistribute it
// and/or modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// The dexon-consensus library is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
// General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the dexon-consensus library. If not, see
// <http://www.gnu.org/licenses/>.

package dkg

import (
    "encoding/binary"
    "fmt"
    "math/rand"

    "github.com/dexon-foundation/bls/ffi/go/bls"

    "github.com/dexon-foundation/dexon-consensus/core/crypto"
)

// PartialSignature is a partial signature in DKG+TSIG protocol.
type PartialSignature crypto.Signature

var (
    // ErrEmptySignature is reported if the signature is empty.
    ErrEmptySignature = fmt.Errorf("invalid empty signature")
)

// RecoverSignature recovers TSIG signature.
func RecoverSignature(sigs []PartialSignature, signerIDs IDs) (
    crypto.Signature, error) {
    blsSigs := make([]bls.Sign, len(sigs))
    for i, sig := range sigs {
        if len(sig.Signature) == 0 {
            return crypto.Signature{}, ErrEmptySignature
        }
        if err := blsSigs[i].Deserialize([]byte(sig.Signature)); err != nil {
            return crypto.Signature{}, err
        }
    }
    var recoverSig bls.Sign
    if err := recoverSig.Recover(blsSigs, []bls.ID(signerIDs)); err != nil {
        return crypto.Signature{}, err
    }
    return crypto.Signature{
        Type:      cryptoType,
        Signature: recoverSig.Serialize()}, nil
}

// RecoverGroupPublicKey recovers group public key.
func RecoverGroupPublicKey(pubShares []*PublicKeyShares) *PublicKey {
    var pub *PublicKey
    for _, pubShare := range pubShares {
        pk0 := pubShare.masterPublicKey[0]
        if pub == nil {
            pub = &PublicKey{
                publicKey: pk0,
            }
        } else {
            pub.publicKey.Add(&pk0)
        }
    }
    return pub
}

// NewRandomPrivateKeyShares constructs a private key shares randomly.
func NewRandomPrivateKeyShares() *PrivateKeyShares {
    // Generate IDs.
    rndIDs := make(IDs, 0, 10)
    for i := range rndIDs {
        id := make([]byte, 8)
        binary.LittleEndian.PutUint64(id, rand.Uint64())
        rndIDs[i] = NewID(id)
    }
    prvShares := NewEmptyPrivateKeyShares()
    prvShares.SetParticipants(rndIDs)
    for _, id := range rndIDs {
        if err := prvShares.AddShare(id, NewPrivateKey()); err != nil {
            panic(err)
        }
    }
    return prvShares
}