-
Notifications
You must be signed in to change notification settings - Fork 23
/
binary.go
105 lines (80 loc) · 2.32 KB
/
binary.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
package sm3
import (
"errors"
"encoding/binary"
)
const (
chunk = 64
magic256 = "sm3\x03"
marshaledSize = len(magic256) + 8*4 + chunk + 8
)
func (this *digest) MarshalBinary() ([]byte, error) {
b := make([]byte, 0, marshaledSize)
b = append(b, magic256...)
b = appendUint32(b, this.s[0])
b = appendUint32(b, this.s[1])
b = appendUint32(b, this.s[2])
b = appendUint32(b, this.s[3])
b = appendUint32(b, this.s[4])
b = appendUint32(b, this.s[5])
b = appendUint32(b, this.s[6])
b = appendUint32(b, this.s[7])
b = append(b, this.x[:this.len]...)
length := (this.nx * BlockSize) + uint64(this.len)
b = b[:len(b) + len(this.x) - int(this.len)]
b = appendUint64(b, length)
return b, nil
}
func (this *digest) UnmarshalBinary(b []byte) error {
if len(b) < len(magic256) || (string(b[:len(magic256)]) != magic256) {
return errors.New("sm3: invalid hash state identifier")
}
if len(b) != marshaledSize {
return errors.New("sm3: invalid hash state size")
}
b = b[len(magic256):]
b, this.s[0] = consumeUint32(b)
b, this.s[1] = consumeUint32(b)
b, this.s[2] = consumeUint32(b)
b, this.s[3] = consumeUint32(b)
b, this.s[4] = consumeUint32(b)
b, this.s[5] = consumeUint32(b)
b, this.s[6] = consumeUint32(b)
b, this.s[7] = consumeUint32(b)
b = b[copy(this.x[:], b):]
var length uint64
b, length = consumeUint64(b)
this.len = int(length % chunk)
this.nx = length / chunk
return nil
}
func appendUint64(b []byte, x uint64) []byte {
var a [8]byte
binary.BigEndian.PutUint64(a[:], x)
return append(b, a[:]...)
}
func appendUint32(b []byte, x uint32) []byte {
var a [4]byte
binary.BigEndian.PutUint32(a[:], x)
return append(b, a[:]...)
}
func consumeUint64(b []byte) ([]byte, uint64) {
_ = b[7]
x := uint64(b[7]) |
uint64(b[6]) << 8 |
uint64(b[5]) << 16 |
uint64(b[4]) << 24 |
uint64(b[3]) << 32 |
uint64(b[2]) << 40 |
uint64(b[1]) << 48 |
uint64(b[0]) << 56
return b[8:], x
}
func consumeUint32(b []byte) ([]byte, uint32) {
_ = b[3]
x := uint32(b[3]) |
uint32(b[2]) << 8 |
uint32(b[1]) << 16 |
uint32(b[0]) << 24
return b[4:], x
}