github.com/gnolang/gno@v0.0.0-20240520182011-228e9d0192ce/gnovm/stdlibs/crypto/chacha20/chacha/chacha_generic.gno (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 "encoding/binary" 8 9 var sigma = [4]uint32{0x61707865, 0x3320646e, 0x79622d32, 0x6b206574} 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 }