Scott Baker | 8487c5d | 2019-10-18 12:49:46 -0700 | [diff] [blame^] | 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 | // MD4 block step. |
| 6 | // In its own file so that a faster assembly or C version |
| 7 | // can be substituted easily. |
| 8 | |
| 9 | package md4 |
| 10 | |
| 11 | var shift1 = []uint{3, 7, 11, 19} |
| 12 | var shift2 = []uint{3, 5, 9, 13} |
| 13 | var shift3 = []uint{3, 9, 11, 15} |
| 14 | |
| 15 | var xIndex2 = []uint{0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15} |
| 16 | var xIndex3 = []uint{0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15} |
| 17 | |
| 18 | func _Block(dig *digest, p []byte) int { |
| 19 | a := dig.s[0] |
| 20 | b := dig.s[1] |
| 21 | c := dig.s[2] |
| 22 | d := dig.s[3] |
| 23 | n := 0 |
| 24 | var X [16]uint32 |
| 25 | for len(p) >= _Chunk { |
| 26 | aa, bb, cc, dd := a, b, c, d |
| 27 | |
| 28 | j := 0 |
| 29 | for i := 0; i < 16; i++ { |
| 30 | X[i] = uint32(p[j]) | uint32(p[j+1])<<8 | uint32(p[j+2])<<16 | uint32(p[j+3])<<24 |
| 31 | j += 4 |
| 32 | } |
| 33 | |
| 34 | // If this needs to be made faster in the future, |
| 35 | // the usual trick is to unroll each of these |
| 36 | // loops by a factor of 4; that lets you replace |
| 37 | // the shift[] lookups with constants and, |
| 38 | // with suitable variable renaming in each |
| 39 | // unrolled body, delete the a, b, c, d = d, a, b, c |
| 40 | // (or you can let the optimizer do the renaming). |
| 41 | // |
| 42 | // The index variables are uint so that % by a power |
| 43 | // of two can be optimized easily by a compiler. |
| 44 | |
| 45 | // Round 1. |
| 46 | for i := uint(0); i < 16; i++ { |
| 47 | x := i |
| 48 | s := shift1[i%4] |
| 49 | f := ((c ^ d) & b) ^ d |
| 50 | a += f + X[x] |
| 51 | a = a<<s | a>>(32-s) |
| 52 | a, b, c, d = d, a, b, c |
| 53 | } |
| 54 | |
| 55 | // Round 2. |
| 56 | for i := uint(0); i < 16; i++ { |
| 57 | x := xIndex2[i] |
| 58 | s := shift2[i%4] |
| 59 | g := (b & c) | (b & d) | (c & d) |
| 60 | a += g + X[x] + 0x5a827999 |
| 61 | a = a<<s | a>>(32-s) |
| 62 | a, b, c, d = d, a, b, c |
| 63 | } |
| 64 | |
| 65 | // Round 3. |
| 66 | for i := uint(0); i < 16; i++ { |
| 67 | x := xIndex3[i] |
| 68 | s := shift3[i%4] |
| 69 | h := b ^ c ^ d |
| 70 | a += h + X[x] + 0x6ed9eba1 |
| 71 | a = a<<s | a>>(32-s) |
| 72 | a, b, c, d = d, a, b, c |
| 73 | } |
| 74 | |
| 75 | a += aa |
| 76 | b += bb |
| 77 | c += cc |
| 78 | d += dd |
| 79 | |
| 80 | p = p[_Chunk:] |
| 81 | n += _Chunk |
| 82 | } |
| 83 | |
| 84 | dig.s[0] = a |
| 85 | dig.s[1] = b |
| 86 | dig.s[2] = c |
| 87 | dig.s[3] = d |
| 88 | return n |
| 89 | } |