Source file src/pkg/crypto/md5/md5block.go
1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 // MD5 block step.
6 // In its own file so that a faster assembly or C version
7 // can be substituted easily.
8
9 package md5
10
11 // table[i] = int((1<<32) * abs(sin(i+1 radians))).
12 var table = []uint32{
13 // round 1
14 0xd76aa478,
15 0xe8c7b756,
16 0x242070db,
17 0xc1bdceee,
18 0xf57c0faf,
19 0x4787c62a,
20 0xa8304613,
21 0xfd469501,
22 0x698098d8,
23 0x8b44f7af,
24 0xffff5bb1,
25 0x895cd7be,
26 0x6b901122,
27 0xfd987193,
28 0xa679438e,
29 0x49b40821,
30
31 // round 2
32 0xf61e2562,
33 0xc040b340,
34 0x265e5a51,
35 0xe9b6c7aa,
36 0xd62f105d,
37 0x2441453,
38 0xd8a1e681,
39 0xe7d3fbc8,
40 0x21e1cde6,
41 0xc33707d6,
42 0xf4d50d87,
43 0x455a14ed,
44 0xa9e3e905,
45 0xfcefa3f8,
46 0x676f02d9,
47 0x8d2a4c8a,
48
49 // round3
50 0xfffa3942,
51 0x8771f681,
52 0x6d9d6122,
53 0xfde5380c,
54 0xa4beea44,
55 0x4bdecfa9,
56 0xf6bb4b60,
57 0xbebfbc70,
58 0x289b7ec6,
59 0xeaa127fa,
60 0xd4ef3085,
61 0x4881d05,
62 0xd9d4d039,
63 0xe6db99e5,
64 0x1fa27cf8,
65 0xc4ac5665,
66
67 // round 4
68 0xf4292244,
69 0x432aff97,
70 0xab9423a7,
71 0xfc93a039,
72 0x655b59c3,
73 0x8f0ccc92,
74 0xffeff47d,
75 0x85845dd1,
76 0x6fa87e4f,
77 0xfe2ce6e0,
78 0xa3014314,
79 0x4e0811a1,
80 0xf7537e82,
81 0xbd3af235,
82 0x2ad7d2bb,
83 0xeb86d391,
84 }
85
86 var shift1 = []uint{7, 12, 17, 22}
87 var shift2 = []uint{5, 9, 14, 20}
88 var shift3 = []uint{4, 11, 16, 23}
89 var shift4 = []uint{6, 10, 15, 21}
90
91 func _Block(dig *digest, p []byte) int {
92 a := dig.s[0]
93 b := dig.s[1]
94 c := dig.s[2]
95 d := dig.s[3]
96 n := 0
97 var X [16]uint32
98 for len(p) >= _Chunk {
99 aa, bb, cc, dd := a, b, c, d
100
101 j := 0
102 for i := 0; i < 16; i++ {
103 X[i] = uint32(p[j]) | uint32(p[j+1])<<8 | uint32(p[j+2])<<16 | uint32(p[j+3])<<24
104 j += 4
105 }
106
107 // If this needs to be made faster in the future,
108 // the usual trick is to unroll each of these
109 // loops by a factor of 4; that lets you replace
110 // the shift[] lookups with constants and,
111 // with suitable variable renaming in each
112 // unrolled body, delete the a, b, c, d = d, a, b, c
113 // (or you can let the optimizer do the renaming).
114 //
115 // The index variables are uint so that % by a power
116 // of two can be optimized easily by a compiler.
117
118 // Round 1.
119 for i := uint(0); i < 16; i++ {
120 x := i
121 s := shift1[i%4]
122 f := ((c ^ d) & b) ^ d
123 a += f + X[x] + table[i]
124 a = a<<s | a>>(32-s) + b
125 a, b, c, d = d, a, b, c
126 }
127
128 // Round 2.
129 for i := uint(0); i < 16; i++ {
130 x := (1 + 5*i) % 16
131 s := shift2[i%4]
132 g := ((b ^ c) & d) ^ c
133 a += g + X[x] + table[i+16]
134 a = a<<s | a>>(32-s) + b
135 a, b, c, d = d, a, b, c
136 }
137
138 // Round 3.
139 for i := uint(0); i < 16; i++ {
140 x := (5 + 3*i) % 16
141 s := shift3[i%4]
142 h := b ^ c ^ d
143 a += h + X[x] + table[i+32]
144 a = a<<s | a>>(32-s) + b
145 a, b, c, d = d, a, b, c
146 }
147
148 // Round 4.
149 for i := uint(0); i < 16; i++ {
150 x := (7 * i) % 16
151 s := shift4[i%4]
152 j := c ^ (b | ^d)
153 a += j + X[x] + table[i+48]
154 a = a<<s | a>>(32-s) + b
155 a, b, c, d = d, a, b, c
156 }
157
158 a += aa
159 b += bb
160 c += cc
161 d += dd
162
163 p = p[_Chunk:]
164 n += _Chunk
165 }
166
167 dig.s[0] = a
168 dig.s[1] = b
169 dig.s[2] = c
170 dig.s[3] = d
171 return n
172 }