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 }