github.com/aigarnetwork/aigar@v0.0.0-20191115204914-d59a6eb70f8e/crypto/blake2b/blake2b_generic.go (about) 1 // Copyright 2018 The go-ethereum Authors 2 // Copyright 2019 The go-aigar Authors 3 // This file is part of the go-aigar library. 4 // 5 // The go-aigar library is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Lesser General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // The go-aigar library is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Lesser General Public License for more details. 14 // 15 // You should have received a copy of the GNU Lesser General Public License 16 // along with the go-aigar library. If not, see <http://www.gnu.org/licenses/>. 17 18 package blake2b 19 20 import ( 21 "encoding/binary" 22 "math/bits" 23 ) 24 25 // the precomputed values for BLAKE2b 26 // there are 10 16-byte arrays - one for each round 27 // the entries are calculated from the sigma constants. 28 var precomputed = [10][16]byte{ 29 {0, 2, 4, 6, 1, 3, 5, 7, 8, 10, 12, 14, 9, 11, 13, 15}, 30 {14, 4, 9, 13, 10, 8, 15, 6, 1, 0, 11, 5, 12, 2, 7, 3}, 31 {11, 12, 5, 15, 8, 0, 2, 13, 10, 3, 7, 9, 14, 6, 1, 4}, 32 {7, 3, 13, 11, 9, 1, 12, 14, 2, 5, 4, 15, 6, 10, 0, 8}, 33 {9, 5, 2, 10, 0, 7, 4, 15, 14, 11, 6, 3, 1, 12, 8, 13}, 34 {2, 6, 0, 8, 12, 10, 11, 3, 4, 7, 15, 1, 13, 5, 14, 9}, 35 {12, 1, 14, 4, 5, 15, 13, 10, 0, 6, 9, 8, 7, 3, 2, 11}, 36 {13, 7, 12, 3, 11, 14, 1, 9, 5, 15, 8, 2, 0, 4, 6, 10}, 37 {6, 14, 11, 0, 15, 9, 3, 8, 12, 13, 1, 10, 2, 7, 4, 5}, 38 {10, 8, 7, 1, 2, 4, 6, 5, 15, 9, 3, 13, 11, 14, 12, 0}, 39 } 40 41 func hashBlocksGeneric(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte) { 42 var m [16]uint64 43 c0, c1 := c[0], c[1] 44 45 for i := 0; i < len(blocks); { 46 c0 += BlockSize 47 if c0 < BlockSize { 48 c1++ 49 } 50 for j := range m { 51 m[j] = binary.LittleEndian.Uint64(blocks[i:]) 52 i += 8 53 } 54 fGeneric(h, &m, c0, c1, flag, 12) 55 } 56 c[0], c[1] = c0, c1 57 } 58 59 func fGeneric(h *[8]uint64, m *[16]uint64, c0, c1 uint64, flag uint64, rounds uint64) { 60 v0, v1, v2, v3, v4, v5, v6, v7 := h[0], h[1], h[2], h[3], h[4], h[5], h[6], h[7] 61 v8, v9, v10, v11, v12, v13, v14, v15 := iv[0], iv[1], iv[2], iv[3], iv[4], iv[5], iv[6], iv[7] 62 v12 ^= c0 63 v13 ^= c1 64 v14 ^= flag 65 66 for i := 0; i < int(rounds); i++ { 67 s := &(precomputed[i%10]) 68 69 v0 += m[s[0]] 70 v0 += v4 71 v12 ^= v0 72 v12 = bits.RotateLeft64(v12, -32) 73 v8 += v12 74 v4 ^= v8 75 v4 = bits.RotateLeft64(v4, -24) 76 v1 += m[s[1]] 77 v1 += v5 78 v13 ^= v1 79 v13 = bits.RotateLeft64(v13, -32) 80 v9 += v13 81 v5 ^= v9 82 v5 = bits.RotateLeft64(v5, -24) 83 v2 += m[s[2]] 84 v2 += v6 85 v14 ^= v2 86 v14 = bits.RotateLeft64(v14, -32) 87 v10 += v14 88 v6 ^= v10 89 v6 = bits.RotateLeft64(v6, -24) 90 v3 += m[s[3]] 91 v3 += v7 92 v15 ^= v3 93 v15 = bits.RotateLeft64(v15, -32) 94 v11 += v15 95 v7 ^= v11 96 v7 = bits.RotateLeft64(v7, -24) 97 98 v0 += m[s[4]] 99 v0 += v4 100 v12 ^= v0 101 v12 = bits.RotateLeft64(v12, -16) 102 v8 += v12 103 v4 ^= v8 104 v4 = bits.RotateLeft64(v4, -63) 105 v1 += m[s[5]] 106 v1 += v5 107 v13 ^= v1 108 v13 = bits.RotateLeft64(v13, -16) 109 v9 += v13 110 v5 ^= v9 111 v5 = bits.RotateLeft64(v5, -63) 112 v2 += m[s[6]] 113 v2 += v6 114 v14 ^= v2 115 v14 = bits.RotateLeft64(v14, -16) 116 v10 += v14 117 v6 ^= v10 118 v6 = bits.RotateLeft64(v6, -63) 119 v3 += m[s[7]] 120 v3 += v7 121 v15 ^= v3 122 v15 = bits.RotateLeft64(v15, -16) 123 v11 += v15 124 v7 ^= v11 125 v7 = bits.RotateLeft64(v7, -63) 126 127 v0 += m[s[8]] 128 v0 += v5 129 v15 ^= v0 130 v15 = bits.RotateLeft64(v15, -32) 131 v10 += v15 132 v5 ^= v10 133 v5 = bits.RotateLeft64(v5, -24) 134 v1 += m[s[9]] 135 v1 += v6 136 v12 ^= v1 137 v12 = bits.RotateLeft64(v12, -32) 138 v11 += v12 139 v6 ^= v11 140 v6 = bits.RotateLeft64(v6, -24) 141 v2 += m[s[10]] 142 v2 += v7 143 v13 ^= v2 144 v13 = bits.RotateLeft64(v13, -32) 145 v8 += v13 146 v7 ^= v8 147 v7 = bits.RotateLeft64(v7, -24) 148 v3 += m[s[11]] 149 v3 += v4 150 v14 ^= v3 151 v14 = bits.RotateLeft64(v14, -32) 152 v9 += v14 153 v4 ^= v9 154 v4 = bits.RotateLeft64(v4, -24) 155 156 v0 += m[s[12]] 157 v0 += v5 158 v15 ^= v0 159 v15 = bits.RotateLeft64(v15, -16) 160 v10 += v15 161 v5 ^= v10 162 v5 = bits.RotateLeft64(v5, -63) 163 v1 += m[s[13]] 164 v1 += v6 165 v12 ^= v1 166 v12 = bits.RotateLeft64(v12, -16) 167 v11 += v12 168 v6 ^= v11 169 v6 = bits.RotateLeft64(v6, -63) 170 v2 += m[s[14]] 171 v2 += v7 172 v13 ^= v2 173 v13 = bits.RotateLeft64(v13, -16) 174 v8 += v13 175 v7 ^= v8 176 v7 = bits.RotateLeft64(v7, -63) 177 v3 += m[s[15]] 178 v3 += v4 179 v14 ^= v3 180 v14 = bits.RotateLeft64(v14, -16) 181 v9 += v14 182 v4 ^= v9 183 v4 = bits.RotateLeft64(v4, -63) 184 } 185 h[0] ^= v0 ^ v8 186 h[1] ^= v1 ^ v9 187 h[2] ^= v2 ^ v10 188 h[3] ^= v3 ^ v11 189 h[4] ^= v4 ^ v12 190 h[5] ^= v5 ^ v13 191 h[6] ^= v6 ^ v14 192 h[7] ^= v7 ^ v15 193 }