...
1
2
3
4
5
6
7
8
9
10 package ripemd160
11
12
13
14
15
16 import (
17 "crypto"
18 "hash"
19 )
20
21 func init() {
22 crypto.RegisterHash(crypto.RIPEMD160, New)
23 }
24
25
26 const Size = 20
27
28
29 const BlockSize = 64
30
31 const (
32 _s0 = 0x67452301
33 _s1 = 0xefcdab89
34 _s2 = 0x98badcfe
35 _s3 = 0x10325476
36 _s4 = 0xc3d2e1f0
37 )
38
39
40 type digest struct {
41 s [5]uint32
42 x [BlockSize]byte
43 nx int
44 tc uint64
45 }
46
47 func (d *digest) Reset() {
48 d.s[0], d.s[1], d.s[2], d.s[3], d.s[4] = _s0, _s1, _s2, _s3, _s4
49 d.nx = 0
50 d.tc = 0
51 }
52
53
54 func New() hash.Hash {
55 result := new(digest)
56 result.Reset()
57 return result
58 }
59
60 func (d *digest) Size() int { return Size }
61
62 func (d *digest) BlockSize() int { return BlockSize }
63
64 func (d *digest) Write(p []byte) (nn int, err error) {
65 nn = len(p)
66 d.tc += uint64(nn)
67 if d.nx > 0 {
68 n := len(p)
69 if n > BlockSize-d.nx {
70 n = BlockSize - d.nx
71 }
72 for i := 0; i < n; i++ {
73 d.x[d.nx+i] = p[i]
74 }
75 d.nx += n
76 if d.nx == BlockSize {
77 _Block(d, d.x[0:])
78 d.nx = 0
79 }
80 p = p[n:]
81 }
82 n := _Block(d, p)
83 p = p[n:]
84 if len(p) > 0 {
85 d.nx = copy(d.x[:], p)
86 }
87 return
88 }
89
90 func (d0 *digest) Sum(in []byte) []byte {
91
92 d := *d0
93
94
95 tc := d.tc
96 var tmp [64]byte
97 tmp[0] = 0x80
98 if tc%64 < 56 {
99 d.Write(tmp[0 : 56-tc%64])
100 } else {
101 d.Write(tmp[0 : 64+56-tc%64])
102 }
103
104
105 tc <<= 3
106 for i := uint(0); i < 8; i++ {
107 tmp[i] = byte(tc >> (8 * i))
108 }
109 d.Write(tmp[0:8])
110
111 if d.nx != 0 {
112 panic("d.nx != 0")
113 }
114
115 var digest [Size]byte
116 for i, s := range d.s {
117 digest[i*4] = byte(s)
118 digest[i*4+1] = byte(s >> 8)
119 digest[i*4+2] = byte(s >> 16)
120 digest[i*4+3] = byte(s >> 24)
121 }
122
123 return append(in, digest[:]...)
124 }
125
View as plain text