git.sr.ht/~pingoo/stdx@v0.0.0-20240218134121-094174641f6e/crypto/chacha/chacha_generic.go (about) 1 // Copyright (c) 2016 Andreas Auernhammer. All rights reserved. 2 // Use of this source code is governed by a license that can be 3 // found in the LICENSE file. 4 5 package chacha 6 7 import ( 8 "encoding/binary" 9 ) 10 11 func xorKeyStreamGeneric(dst, src []byte, block, state *[64]byte, rounds int) int { 12 for len(src) >= 64 { 13 chachaGeneric(block, state, rounds) 14 15 for i, v := range block { 16 dst[i] = src[i] ^ v 17 } 18 src = src[64:] 19 dst = dst[64:] 20 } 21 22 n := len(src) 23 if n > 0 { 24 chachaGeneric(block, state, rounds) 25 for i, v := range src { 26 dst[i] = v ^ block[i] 27 } 28 } 29 return n 30 } 31 32 func chachaGeneric(dst *[64]byte, state *[64]byte, rounds int) { 33 v00 := binary.LittleEndian.Uint32(state[0:]) 34 v01 := binary.LittleEndian.Uint32(state[4:]) 35 v02 := binary.LittleEndian.Uint32(state[8:]) 36 v03 := binary.LittleEndian.Uint32(state[12:]) 37 v04 := binary.LittleEndian.Uint32(state[16:]) 38 v05 := binary.LittleEndian.Uint32(state[20:]) 39 v06 := binary.LittleEndian.Uint32(state[24:]) 40 v07 := binary.LittleEndian.Uint32(state[28:]) 41 v08 := binary.LittleEndian.Uint32(state[32:]) 42 v09 := binary.LittleEndian.Uint32(state[36:]) 43 v10 := binary.LittleEndian.Uint32(state[40:]) 44 v11 := binary.LittleEndian.Uint32(state[44:]) 45 v12 := binary.LittleEndian.Uint32(state[48:]) 46 v13 := binary.LittleEndian.Uint32(state[52:]) 47 v14 := binary.LittleEndian.Uint32(state[56:]) 48 v15 := binary.LittleEndian.Uint32(state[60:]) 49 50 s00, s01, s02, s03, s04, s05, s06, s07 := v00, v01, v02, v03, v04, v05, v06, v07 51 s08, s09, s10, s11, s12, s13, s14, s15 := v08, v09, v10, v11, v12, v13, v14, v15 52 53 for i := 0; i < rounds; i += 2 { 54 v00 += v04 55 v12 ^= v00 56 v12 = (v12 << 16) | (v12 >> 16) 57 v08 += v12 58 v04 ^= v08 59 v04 = (v04 << 12) | (v04 >> 20) 60 v00 += v04 61 v12 ^= v00 62 v12 = (v12 << 8) | (v12 >> 24) 63 v08 += v12 64 v04 ^= v08 65 v04 = (v04 << 7) | (v04 >> 25) 66 v01 += v05 67 v13 ^= v01 68 v13 = (v13 << 16) | (v13 >> 16) 69 v09 += v13 70 v05 ^= v09 71 v05 = (v05 << 12) | (v05 >> 20) 72 v01 += v05 73 v13 ^= v01 74 v13 = (v13 << 8) | (v13 >> 24) 75 v09 += v13 76 v05 ^= v09 77 v05 = (v05 << 7) | (v05 >> 25) 78 v02 += v06 79 v14 ^= v02 80 v14 = (v14 << 16) | (v14 >> 16) 81 v10 += v14 82 v06 ^= v10 83 v06 = (v06 << 12) | (v06 >> 20) 84 v02 += v06 85 v14 ^= v02 86 v14 = (v14 << 8) | (v14 >> 24) 87 v10 += v14 88 v06 ^= v10 89 v06 = (v06 << 7) | (v06 >> 25) 90 v03 += v07 91 v15 ^= v03 92 v15 = (v15 << 16) | (v15 >> 16) 93 v11 += v15 94 v07 ^= v11 95 v07 = (v07 << 12) | (v07 >> 20) 96 v03 += v07 97 v15 ^= v03 98 v15 = (v15 << 8) | (v15 >> 24) 99 v11 += v15 100 v07 ^= v11 101 v07 = (v07 << 7) | (v07 >> 25) 102 v00 += v05 103 v15 ^= v00 104 v15 = (v15 << 16) | (v15 >> 16) 105 v10 += v15 106 v05 ^= v10 107 v05 = (v05 << 12) | (v05 >> 20) 108 v00 += v05 109 v15 ^= v00 110 v15 = (v15 << 8) | (v15 >> 24) 111 v10 += v15 112 v05 ^= v10 113 v05 = (v05 << 7) | (v05 >> 25) 114 v01 += v06 115 v12 ^= v01 116 v12 = (v12 << 16) | (v12 >> 16) 117 v11 += v12 118 v06 ^= v11 119 v06 = (v06 << 12) | (v06 >> 20) 120 v01 += v06 121 v12 ^= v01 122 v12 = (v12 << 8) | (v12 >> 24) 123 v11 += v12 124 v06 ^= v11 125 v06 = (v06 << 7) | (v06 >> 25) 126 v02 += v07 127 v13 ^= v02 128 v13 = (v13 << 16) | (v13 >> 16) 129 v08 += v13 130 v07 ^= v08 131 v07 = (v07 << 12) | (v07 >> 20) 132 v02 += v07 133 v13 ^= v02 134 v13 = (v13 << 8) | (v13 >> 24) 135 v08 += v13 136 v07 ^= v08 137 v07 = (v07 << 7) | (v07 >> 25) 138 v03 += v04 139 v14 ^= v03 140 v14 = (v14 << 16) | (v14 >> 16) 141 v09 += v14 142 v04 ^= v09 143 v04 = (v04 << 12) | (v04 >> 20) 144 v03 += v04 145 v14 ^= v03 146 v14 = (v14 << 8) | (v14 >> 24) 147 v09 += v14 148 v04 ^= v09 149 v04 = (v04 << 7) | (v04 >> 25) 150 } 151 152 v00 += s00 153 v01 += s01 154 v02 += s02 155 v03 += s03 156 v04 += s04 157 v05 += s05 158 v06 += s06 159 v07 += s07 160 v08 += s08 161 v09 += s09 162 v10 += s10 163 v11 += s11 164 v12 += s12 165 v13 += s13 166 v14 += s14 167 v15 += s15 168 169 s12++ 170 binary.LittleEndian.PutUint32(state[48:], s12) 171 if s12 == 0 { // indicates overflow 172 s13++ 173 binary.LittleEndian.PutUint32(state[52:], s13) 174 } 175 176 binary.LittleEndian.PutUint32(dst[0:], v00) 177 binary.LittleEndian.PutUint32(dst[4:], v01) 178 binary.LittleEndian.PutUint32(dst[8:], v02) 179 binary.LittleEndian.PutUint32(dst[12:], v03) 180 binary.LittleEndian.PutUint32(dst[16:], v04) 181 binary.LittleEndian.PutUint32(dst[20:], v05) 182 binary.LittleEndian.PutUint32(dst[24:], v06) 183 binary.LittleEndian.PutUint32(dst[28:], v07) 184 binary.LittleEndian.PutUint32(dst[32:], v08) 185 binary.LittleEndian.PutUint32(dst[36:], v09) 186 binary.LittleEndian.PutUint32(dst[40:], v10) 187 binary.LittleEndian.PutUint32(dst[44:], v11) 188 binary.LittleEndian.PutUint32(dst[48:], v12) 189 binary.LittleEndian.PutUint32(dst[52:], v13) 190 binary.LittleEndian.PutUint32(dst[56:], v14) 191 binary.LittleEndian.PutUint32(dst[60:], v15) 192 } 193 194 // func hChaCha20Generic(out *[32]byte, nonce *[16]byte, key *[32]byte) { 195 // v00 := sigma[0] 196 // v01 := sigma[1] 197 // v02 := sigma[2] 198 // v03 := sigma[3] 199 // v04 := binary.LittleEndian.Uint32(key[0:]) 200 // v05 := binary.LittleEndian.Uint32(key[4:]) 201 // v06 := binary.LittleEndian.Uint32(key[8:]) 202 // v07 := binary.LittleEndian.Uint32(key[12:]) 203 // v08 := binary.LittleEndian.Uint32(key[16:]) 204 // v09 := binary.LittleEndian.Uint32(key[20:]) 205 // v10 := binary.LittleEndian.Uint32(key[24:]) 206 // v11 := binary.LittleEndian.Uint32(key[28:]) 207 // v12 := binary.LittleEndian.Uint32(nonce[0:]) 208 // v13 := binary.LittleEndian.Uint32(nonce[4:]) 209 // v14 := binary.LittleEndian.Uint32(nonce[8:]) 210 // v15 := binary.LittleEndian.Uint32(nonce[12:]) 211 212 // for i := 0; i < 20; i += 2 { 213 // v00 += v04 214 // v12 ^= v00 215 // v12 = (v12 << 16) | (v12 >> 16) 216 // v08 += v12 217 // v04 ^= v08 218 // v04 = (v04 << 12) | (v04 >> 20) 219 // v00 += v04 220 // v12 ^= v00 221 // v12 = (v12 << 8) | (v12 >> 24) 222 // v08 += v12 223 // v04 ^= v08 224 // v04 = (v04 << 7) | (v04 >> 25) 225 // v01 += v05 226 // v13 ^= v01 227 // v13 = (v13 << 16) | (v13 >> 16) 228 // v09 += v13 229 // v05 ^= v09 230 // v05 = (v05 << 12) | (v05 >> 20) 231 // v01 += v05 232 // v13 ^= v01 233 // v13 = (v13 << 8) | (v13 >> 24) 234 // v09 += v13 235 // v05 ^= v09 236 // v05 = (v05 << 7) | (v05 >> 25) 237 // v02 += v06 238 // v14 ^= v02 239 // v14 = (v14 << 16) | (v14 >> 16) 240 // v10 += v14 241 // v06 ^= v10 242 // v06 = (v06 << 12) | (v06 >> 20) 243 // v02 += v06 244 // v14 ^= v02 245 // v14 = (v14 << 8) | (v14 >> 24) 246 // v10 += v14 247 // v06 ^= v10 248 // v06 = (v06 << 7) | (v06 >> 25) 249 // v03 += v07 250 // v15 ^= v03 251 // v15 = (v15 << 16) | (v15 >> 16) 252 // v11 += v15 253 // v07 ^= v11 254 // v07 = (v07 << 12) | (v07 >> 20) 255 // v03 += v07 256 // v15 ^= v03 257 // v15 = (v15 << 8) | (v15 >> 24) 258 // v11 += v15 259 // v07 ^= v11 260 // v07 = (v07 << 7) | (v07 >> 25) 261 // v00 += v05 262 // v15 ^= v00 263 // v15 = (v15 << 16) | (v15 >> 16) 264 // v10 += v15 265 // v05 ^= v10 266 // v05 = (v05 << 12) | (v05 >> 20) 267 // v00 += v05 268 // v15 ^= v00 269 // v15 = (v15 << 8) | (v15 >> 24) 270 // v10 += v15 271 // v05 ^= v10 272 // v05 = (v05 << 7) | (v05 >> 25) 273 // v01 += v06 274 // v12 ^= v01 275 // v12 = (v12 << 16) | (v12 >> 16) 276 // v11 += v12 277 // v06 ^= v11 278 // v06 = (v06 << 12) | (v06 >> 20) 279 // v01 += v06 280 // v12 ^= v01 281 // v12 = (v12 << 8) | (v12 >> 24) 282 // v11 += v12 283 // v06 ^= v11 284 // v06 = (v06 << 7) | (v06 >> 25) 285 // v02 += v07 286 // v13 ^= v02 287 // v13 = (v13 << 16) | (v13 >> 16) 288 // v08 += v13 289 // v07 ^= v08 290 // v07 = (v07 << 12) | (v07 >> 20) 291 // v02 += v07 292 // v13 ^= v02 293 // v13 = (v13 << 8) | (v13 >> 24) 294 // v08 += v13 295 // v07 ^= v08 296 // v07 = (v07 << 7) | (v07 >> 25) 297 // v03 += v04 298 // v14 ^= v03 299 // v14 = (v14 << 16) | (v14 >> 16) 300 // v09 += v14 301 // v04 ^= v09 302 // v04 = (v04 << 12) | (v04 >> 20) 303 // v03 += v04 304 // v14 ^= v03 305 // v14 = (v14 << 8) | (v14 >> 24) 306 // v09 += v14 307 // v04 ^= v09 308 // v04 = (v04 << 7) | (v04 >> 25) 309 // } 310 311 // binary.LittleEndian.PutUint32(out[0:], v00) 312 // binary.LittleEndian.PutUint32(out[4:], v01) 313 // binary.LittleEndian.PutUint32(out[8:], v02) 314 // binary.LittleEndian.PutUint32(out[12:], v03) 315 // binary.LittleEndian.PutUint32(out[16:], v12) 316 // binary.LittleEndian.PutUint32(out[20:], v13) 317 // binary.LittleEndian.PutUint32(out[24:], v14) 318 // binary.LittleEndian.PutUint32(out[28:], v15) 319 // }