OSDN Git Service

new repo
[bytom/vapor.git] / vendor / github.com / tendermint / go-crypto / nano / sign.go
1 package nano
2
3 import (
4         "bytes"
5         "crypto/sha512"
6
7         "github.com/pkg/errors"
8 )
9
10 const (
11         App       = 0x80
12         Init      = 0x00
13         Update    = 0x01
14         Digest    = 0x02
15         MaxChunk  = 253
16         KeyLength = 32
17         SigLength = 64
18 )
19
20 var separator = []byte{0, 0xCA, 0xFE, 0}
21
22 func generateSignRequests(payload []byte) [][]byte {
23         // nice one-shot
24         digest := []byte{App, Digest}
25         if len(payload) < MaxChunk {
26                 return [][]byte{append(digest, payload...)}
27         }
28
29         // large payload is multi-chunk
30         result := [][]byte{{App, Init}}
31         update := []byte{App, Update}
32         for len(payload) > MaxChunk {
33                 msg := append(update, payload[:MaxChunk]...)
34                 payload = payload[MaxChunk:]
35                 result = append(result, msg)
36         }
37         result = append(result, append(update, payload...))
38         result = append(result, digest)
39         return result
40 }
41
42 func parseDigest(resp []byte) (key, sig []byte, err error) {
43         if resp[0] != App || resp[1] != Digest {
44                 return nil, nil, errors.New("Invalid header")
45         }
46         resp = resp[2:]
47         if len(resp) != KeyLength+SigLength+len(separator) {
48                 return nil, nil, errors.Errorf("Incorrect length: %d", len(resp))
49         }
50
51         key, resp = resp[:KeyLength], resp[KeyLength:]
52         if !bytes.Equal(separator, resp[:len(separator)]) {
53                 return nil, nil, errors.New("Cannot find 0xCAFE")
54         }
55
56         sig = resp[len(separator):]
57         return key, sig, nil
58 }
59
60 func hashMsg(data []byte) []byte {
61         res := sha512.Sum512(data)
62         return res[:]
63 }