-
Notifications
You must be signed in to change notification settings - Fork 2
/
hasher.go
122 lines (102 loc) · 2.83 KB
/
hasher.go
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package cryptkit
import (
"hash"
"io"
"github.com/insolar/vanilla/iokit"
"github.com/insolar/vanilla/longbits"
"github.com/insolar/vanilla/throw"
)
var _ hash.Hash = DigestHasher{}
type DigestHasher struct {
BasicDigester
hash.Hash
}
func (v DigestHasher) DigestReader(r io.Reader) DigestHasher {
if _, err := io.Copy(v.Hash, r); err != nil {
panic(err)
}
return v
}
func (v DigestHasher) DigestOf(w io.WriterTo) DigestHasher {
if _, err := w.WriteTo(v.Hash); err != nil {
panic(err)
}
return v
}
func (v DigestHasher) DigestBytes(b []byte) DigestHasher {
if _, err := v.Hash.Write(b); err != nil {
panic(err)
}
return v
}
func (v DigestHasher) SumToDigest() Digest {
return DigestOfHash(v.BasicDigester, v.Hash)
}
func (v DigestHasher) SumToDigestBytes(b []byte) {
HashToBytes(v.Hash, b)
}
func (v DigestHasher) SumToSignature(signer DataSigner) Signature {
digest := v.SumToDigest()
return signer.SignDigest(digest)
}
func HashToBytes(hasher hash.Hash, b []byte) {
n := len(b)
if h := hasher.Sum(b[:0:n]); len(h) != n {
panic(throw.IllegalValue())
}
}
func ByteDigestOfHash(digester BasicDigester, hasher hash.Hash) []byte {
n := digester.GetDigestSize()
h := hasher.Sum(make([]byte, 0, n))
if len(h) < n {
panic(throw.IllegalValue())
}
return h[:n]
}
func DigestOfHash(digester BasicDigester, hasher hash.Hash) Digest {
h := ByteDigestOfHash(digester, hasher)
return NewDigest(longbits.WrapBytes(h), digester.GetDigestMethod())
}
func NewHashingTeeReader(hasher DigestHasher, r io.Reader) HashingTeeReader {
tr := HashingTeeReader{}
tr.BasicDigester = hasher.BasicDigester
tr.CopyTo = hasher.Hash
tr.R = r
return tr
}
type HashingTeeReader struct {
BasicDigester
iokit.TeeReader
}
func (v HashingTeeReader) SumToDigest() Digest {
return DigestOfHash(v.BasicDigester, v.CopyTo.(hash.Hash))
}
func (v *HashingTeeReader) SumToDigestAndSignature(m SigningMethod) (d Digest, s Signature, err error) {
d = DigestOfHash(v.BasicDigester, v.CopyTo.(hash.Hash))
s, err = v.ReadSignature(m)
return
}
func (v *HashingTeeReader) ReadSignatureBytes() ([]byte, error) {
b := make([]byte, v.GetDigestSize())
n, err := io.ReadFull(&v.TeeReader, b)
return b[:n], err
}
func (v *HashingTeeReader) ReadSignature(m SigningMethod) (Signature, error) {
b, err := v.ReadSignatureBytes()
if err != nil {
return Signature{}, err
}
return NewSignature(longbits.WrapBytes(b), v.GetDigestMethod().SignedBy(m)), nil
}
func (v *HashingTeeReader) ReadAndVerifySignature(verifier DataSignatureVerifier) ([]byte, error) {
d := DigestOfHash(v.BasicDigester, v.CopyTo.(hash.Hash))
b, err := v.ReadSignatureBytes()
if err != nil {
return nil, err
}
s := NewSignature(longbits.WrapBytes(b), verifier.GetDefaultSignatureMethod())
if !verifier.IsValidDigestSignature(d, s) {
err = throw.RemoteBreach("packet signature mismatch")
}
return b, err
}