OSDN Git Service

edit dup sup link struct (#1988)
[bytom/bytom.git] / protocol / verfication.go
1 package protocol
2
3 import (
4         "bytes"
5         "encoding/binary"
6         "encoding/hex"
7         "errors"
8
9         "github.com/bytom/bytom/crypto/ed25519/chainkd"
10         "github.com/bytom/bytom/crypto/sha3pool"
11         "github.com/bytom/bytom/protocol/bc"
12 )
13
14 var errVerifySignature = errors.New("signature of verification message is invalid")
15
16 // Verification represent a verification message for the block
17 // source hash and target hash point to the checkpoint, and the source checkpoint is the target checkpoint's parent(not be directly)
18 // the vector <sourceHash, targetHash, sourceHeight, targetHeight, pubKey> as the message of signature
19 type Verification struct {
20         SourceHash   bc.Hash
21         TargetHash   bc.Hash
22         SourceHeight uint64
23         TargetHeight uint64
24         Signature    []byte
25         PubKey       string
26 }
27
28 // Sign used to sign the verification by specified xPrv
29 func (v *Verification) Sign(xPrv chainkd.XPrv) error {
30         message, err := v.encodeMessage()
31         if err != nil {
32                 return err
33         }
34
35         v.Signature = xPrv.Sign(message)
36         return nil
37 }
38
39 // VerifySignature verify the signature of encode message of verification
40 func (v *Verification) VerifySignature() error {
41         pubKey, err := hex.DecodeString(v.PubKey)
42         if err != nil {
43                 return err
44         }
45
46         message, err := v.encodeMessage()
47         if err != nil {
48                 return err
49         }
50
51         var xPub chainkd.XPub
52         copy(xPub[:], pubKey)
53         if !xPub.Verify(message, v.Signature) {
54                 return errVerifySignature
55         }
56
57         return nil
58 }
59
60 // encodeMessage encode the verification for the validators to sign or verify
61 func (v *Verification) encodeMessage() ([]byte, error) {
62         buff := new(bytes.Buffer)
63         if _, err := v.SourceHash.WriteTo(buff); err != nil {
64                 return nil, err
65         }
66
67         if _, err := v.TargetHash.WriteTo(buff); err != nil {
68                 return nil, err
69         }
70
71         uint64Buff := make([]byte, 8)
72
73         binary.LittleEndian.PutUint64(uint64Buff, v.SourceHeight)
74         if _, err := buff.Write(uint64Buff); err != nil {
75                 return nil, err
76         }
77
78         binary.LittleEndian.PutUint64(uint64Buff, v.TargetHeight)
79         if _, err := buff.Write(uint64Buff); err != nil {
80                 return nil, err
81         }
82
83         return sha3Hash(buff.Bytes())
84 }
85
86 func sha3Hash(message []byte) ([]byte, error) {
87         sha3 := sha3pool.Get256()
88         defer sha3pool.Put256(sha3)
89
90         if _, err := sha3.Write(message); err != nil {
91                 return nil, err
92         }
93
94         hash := &bc.Hash{}
95         if _, err := hash.ReadFrom(sha3); err != nil {
96                 return nil, err
97         }
98
99         return hash.Bytes(), nil
100 }