oxedyne/fe2o3/fe2o3_crypto/src/c/fips202.c
11.8 KiB, 1 run
created by r1870400018:196, which is this file's identity for as long as the history lasts, whatever it is later renamed to
download · who wrote it · its history
| 1 | /* Based on the public domain implementation in |
| 2 | * crypto_hash/keccakc512/simple/ from http://bench.cr.yp.to/supercop.html |
| 3 | * by Ronny Van Keer |
| 4 | * and the public domain "TweetFips202" implementation |
| 5 | * from https://twitter.com/tweetfips202 |
| 6 | * by Gilles Van Assche, Daniel J. Bernstein, and Peter Schwabe */ |
| 7 | |
| 8 | #include <stdint.h> |
| 9 | #include <assert.h> |
| 10 | #include "fips202.h" |
| 11 | |
| 12 | #define NROUNDS 24 |
| 13 | #define ROL(a, offset) ((a << offset) ^ (a >> (64 - offset))) |
| 14 | |
| 15 | static uint64_t load64(const unsigned char *x) |
| 16 | { |
| 17 | unsigned long long r = 0, i; |
| 18 | |
| 19 | for (i = 0; i < 8; ++i) |
| 20 | { |
| 21 | r |= (unsigned long long)x[i] << 8 * i; |
| 22 | } |
| 23 | return r; |
| 24 | } |
| 25 | |
| 26 | static void store64(uint8_t *x, uint64_t u) |
| 27 | { |
| 28 | unsigned int i; |
| 29 | |
| 30 | for (i = 0; i < 8; ++i) |
| 31 | { |
| 32 | x[i] = u; |
| 33 | u >>= 8; |
| 34 | } |
| 35 | } |
| 36 | |
| 37 | static const uint64_t KeccakF_RoundConstants[NROUNDS] = |
| 38 | { |
| 39 | (uint64_t)0x0000000000000001ULL, |
| 40 | (uint64_t)0x0000000000008082ULL, |
| 41 | (uint64_t)0x800000000000808aULL, |
| 42 | (uint64_t)0x8000000080008000ULL, |
| 43 | (uint64_t)0x000000000000808bULL, |
| 44 | (uint64_t)0x0000000080000001ULL, |
| 45 | (uint64_t)0x8000000080008081ULL, |
| 46 | (uint64_t)0x8000000000008009ULL, |
| 47 | (uint64_t)0x000000000000008aULL, |
| 48 | (uint64_t)0x0000000000000088ULL, |
| 49 | (uint64_t)0x0000000080008009ULL, |
| 50 | (uint64_t)0x000000008000000aULL, |
| 51 | (uint64_t)0x000000008000808bULL, |
| 52 | (uint64_t)0x800000000000008bULL, |
| 53 | (uint64_t)0x8000000000008089ULL, |
| 54 | (uint64_t)0x8000000000008003ULL, |
| 55 | (uint64_t)0x8000000000008002ULL, |
| 56 | (uint64_t)0x8000000000000080ULL, |
| 57 | (uint64_t)0x000000000000800aULL, |
| 58 | (uint64_t)0x800000008000000aULL, |
| 59 | (uint64_t)0x8000000080008081ULL, |
| 60 | (uint64_t)0x8000000000008080ULL, |
| 61 | (uint64_t)0x0000000080000001ULL, |
| 62 | (uint64_t)0x8000000080008008ULL}; |
| 63 | |
| 64 | static void KeccakF1600_StatePermute(uint64_t *state) |
| 65 | { |
| 66 | int round; |
| 67 | |
| 68 | uint64_t Aba, Abe, Abi, Abo, Abu; |
| 69 | uint64_t Aga, Age, Agi, Ago, Agu; |
| 70 | uint64_t Aka, Ake, Aki, Ako, Aku; |
| 71 | uint64_t Ama, Ame, Ami, Amo, Amu; |
| 72 | uint64_t Asa, Ase, Asi, Aso, Asu; |
| 73 | uint64_t BCa, BCe, BCi, BCo, BCu; |
| 74 | uint64_t Da, De, Di, Do, Du; |
| 75 | uint64_t Eba, Ebe, Ebi, Ebo, Ebu; |
| 76 | uint64_t Ega, Ege, Egi, Ego, Egu; |
| 77 | uint64_t Eka, Eke, Eki, Eko, Eku; |
| 78 | uint64_t Ema, Eme, Emi, Emo, Emu; |
| 79 | uint64_t Esa, Ese, Esi, Eso, Esu; |
| 80 | |
| 81 | //copyFromState(A, state) |
| 82 | Aba = state[0]; |
| 83 | Abe = state[1]; |
| 84 | Abi = state[2]; |
| 85 | Abo = state[3]; |
| 86 | Abu = state[4]; |
| 87 | Aga = state[5]; |
| 88 | Age = state[6]; |
| 89 | Agi = state[7]; |
| 90 | Ago = state[8]; |
| 91 | Agu = state[9]; |
| 92 | Aka = state[10]; |
| 93 | Ake = state[11]; |
| 94 | Aki = state[12]; |
| 95 | Ako = state[13]; |
| 96 | Aku = state[14]; |
| 97 | Ama = state[15]; |
| 98 | Ame = state[16]; |
| 99 | Ami = state[17]; |
| 100 | Amo = state[18]; |
| 101 | Amu = state[19]; |
| 102 | Asa = state[20]; |
| 103 | Ase = state[21]; |
| 104 | Asi = state[22]; |
| 105 | Aso = state[23]; |
| 106 | Asu = state[24]; |
| 107 | |
| 108 | for (round = 0; round < NROUNDS; round += 2) |
| 109 | { |
| 110 | // prepareTheta |
| 111 | BCa = Aba ^ Aga ^ Aka ^ Ama ^ Asa; |
| 112 | BCe = Abe ^ Age ^ Ake ^ Ame ^ Ase; |
| 113 | BCi = Abi ^ Agi ^ Aki ^ Ami ^ Asi; |
| 114 | BCo = Abo ^ Ago ^ Ako ^ Amo ^ Aso; |
| 115 | BCu = Abu ^ Agu ^ Aku ^ Amu ^ Asu; |
| 116 | |
| 117 | //thetaRhoPiChiIotaPrepareTheta(round , A, E) |
| 118 | Da = BCu ^ ROL(BCe, 1); |
| 119 | De = BCa ^ ROL(BCi, 1); |
| 120 | Di = BCe ^ ROL(BCo, 1); |
| 121 | Do = BCi ^ ROL(BCu, 1); |
| 122 | Du = BCo ^ ROL(BCa, 1); |
| 123 | |
| 124 | Aba ^= Da; |
| 125 | BCa = Aba; |
| 126 | Age ^= De; |
| 127 | BCe = ROL(Age, 44); |
| 128 | Aki ^= Di; |
| 129 | BCi = ROL(Aki, 43); |
| 130 | Amo ^= Do; |
| 131 | BCo = ROL(Amo, 21); |
| 132 | Asu ^= Du; |
| 133 | BCu = ROL(Asu, 14); |
| 134 | Eba = BCa ^ ((~BCe) & BCi); |
| 135 | Eba ^= (uint64_t)KeccakF_RoundConstants[round]; |
| 136 | Ebe = BCe ^ ((~BCi) & BCo); |
| 137 | Ebi = BCi ^ ((~BCo) & BCu); |
| 138 | Ebo = BCo ^ ((~BCu) & BCa); |
| 139 | Ebu = BCu ^ ((~BCa) & BCe); |
| 140 | |
| 141 | Abo ^= Do; |
| 142 | BCa = ROL(Abo, 28); |
| 143 | Agu ^= Du; |
| 144 | BCe = ROL(Agu, 20); |
| 145 | Aka ^= Da; |
| 146 | BCi = ROL(Aka, 3); |
| 147 | Ame ^= De; |
| 148 | BCo = ROL(Ame, 45); |
| 149 | Asi ^= Di; |
| 150 | BCu = ROL(Asi, 61); |
| 151 | Ega = BCa ^ ((~BCe) & BCi); |
| 152 | Ege = BCe ^ ((~BCi) & BCo); |
| 153 | Egi = BCi ^ ((~BCo) & BCu); |
| 154 | Ego = BCo ^ ((~BCu) & BCa); |
| 155 | Egu = BCu ^ ((~BCa) & BCe); |
| 156 | |
| 157 | Abe ^= De; |
| 158 | BCa = ROL(Abe, 1); |
| 159 | Agi ^= Di; |
| 160 | BCe = ROL(Agi, 6); |
| 161 | Ako ^= Do; |
| 162 | BCi = ROL(Ako, 25); |
| 163 | Amu ^= Du; |
| 164 | BCo = ROL(Amu, 8); |
| 165 | Asa ^= Da; |
| 166 | BCu = ROL(Asa, 18); |
| 167 | Eka = BCa ^ ((~BCe) & BCi); |
| 168 | Eke = BCe ^ ((~BCi) & BCo); |
| 169 | Eki = BCi ^ ((~BCo) & BCu); |
| 170 | Eko = BCo ^ ((~BCu) & BCa); |
| 171 | Eku = BCu ^ ((~BCa) & BCe); |
| 172 | |
| 173 | Abu ^= Du; |
| 174 | BCa = ROL(Abu, 27); |
| 175 | Aga ^= Da; |
| 176 | BCe = ROL(Aga, 36); |
| 177 | Ake ^= De; |
| 178 | BCi = ROL(Ake, 10); |
| 179 | Ami ^= Di; |
| 180 | BCo = ROL(Ami, 15); |
| 181 | Aso ^= Do; |
| 182 | BCu = ROL(Aso, 56); |
| 183 | Ema = BCa ^ ((~BCe) & BCi); |
| 184 | Eme = BCe ^ ((~BCi) & BCo); |
| 185 | Emi = BCi ^ ((~BCo) & BCu); |
| 186 | Emo = BCo ^ ((~BCu) & BCa); |
| 187 | Emu = BCu ^ ((~BCa) & BCe); |
| 188 | |
| 189 | Abi ^= Di; |
| 190 | BCa = ROL(Abi, 62); |
| 191 | Ago ^= Do; |
| 192 | BCe = ROL(Ago, 55); |
| 193 | Aku ^= Du; |
| 194 | BCi = ROL(Aku, 39); |
| 195 | Ama ^= Da; |
| 196 | BCo = ROL(Ama, 41); |
| 197 | Ase ^= De; |
| 198 | BCu = ROL(Ase, 2); |
| 199 | Esa = BCa ^ ((~BCe) & BCi); |
| 200 | Ese = BCe ^ ((~BCi) & BCo); |
| 201 | Esi = BCi ^ ((~BCo) & BCu); |
| 202 | Eso = BCo ^ ((~BCu) & BCa); |
| 203 | Esu = BCu ^ ((~BCa) & BCe); |
| 204 | |
| 205 | // prepareTheta |
| 206 | BCa = Eba ^ Ega ^ Eka ^ Ema ^ Esa; |
| 207 | BCe = Ebe ^ Ege ^ Eke ^ Eme ^ Ese; |
| 208 | BCi = Ebi ^ Egi ^ Eki ^ Emi ^ Esi; |
| 209 | BCo = Ebo ^ Ego ^ Eko ^ Emo ^ Eso; |
| 210 | BCu = Ebu ^ Egu ^ Eku ^ Emu ^ Esu; |
| 211 | |
| 212 | //thetaRhoPiChiIotaPrepareTheta(round+1, E, A) |
| 213 | Da = BCu ^ ROL(BCe, 1); |
| 214 | De = BCa ^ ROL(BCi, 1); |
| 215 | Di = BCe ^ ROL(BCo, 1); |
| 216 | Do = BCi ^ ROL(BCu, 1); |
| 217 | Du = BCo ^ ROL(BCa, 1); |
| 218 | |
| 219 | Eba ^= Da; |
| 220 | BCa = Eba; |
| 221 | Ege ^= De; |
| 222 | BCe = ROL(Ege, 44); |
| 223 | Eki ^= Di; |
| 224 | BCi = ROL(Eki, 43); |
| 225 | Emo ^= Do; |
| 226 | BCo = ROL(Emo, 21); |
| 227 | Esu ^= Du; |
| 228 | BCu = ROL(Esu, 14); |
| 229 | Aba = BCa ^ ((~BCe) & BCi); |
| 230 | Aba ^= (uint64_t)KeccakF_RoundConstants[round + 1]; |
| 231 | Abe = BCe ^ ((~BCi) & BCo); |
| 232 | Abi = BCi ^ ((~BCo) & BCu); |
| 233 | Abo = BCo ^ ((~BCu) & BCa); |
| 234 | Abu = BCu ^ ((~BCa) & BCe); |
| 235 | |
| 236 | Ebo ^= Do; |
| 237 | BCa = ROL(Ebo, 28); |
| 238 | Egu ^= Du; |
| 239 | BCe = ROL(Egu, 20); |
| 240 | Eka ^= Da; |
| 241 | BCi = ROL(Eka, 3); |
| 242 | Eme ^= De; |
| 243 | BCo = ROL(Eme, 45); |
| 244 | Esi ^= Di; |
| 245 | BCu = ROL(Esi, 61); |
| 246 | Aga = BCa ^ ((~BCe) & BCi); |
| 247 | Age = BCe ^ ((~BCi) & BCo); |
| 248 | Agi = BCi ^ ((~BCo) & BCu); |
| 249 | Ago = BCo ^ ((~BCu) & BCa); |
| 250 | Agu = BCu ^ ((~BCa) & BCe); |
| 251 | |
| 252 | Ebe ^= De; |
| 253 | BCa = ROL(Ebe, 1); |
| 254 | Egi ^= Di; |
| 255 | BCe = ROL(Egi, 6); |
| 256 | Eko ^= Do; |
| 257 | BCi = ROL(Eko, 25); |
| 258 | Emu ^= Du; |
| 259 | BCo = ROL(Emu, 8); |
| 260 | Esa ^= Da; |
| 261 | BCu = ROL(Esa, 18); |
| 262 | Aka = BCa ^ ((~BCe) & BCi); |
| 263 | Ake = BCe ^ ((~BCi) & BCo); |
| 264 | Aki = BCi ^ ((~BCo) & BCu); |
| 265 | Ako = BCo ^ ((~BCu) & BCa); |
| 266 | Aku = BCu ^ ((~BCa) & BCe); |
| 267 | |
| 268 | Ebu ^= Du; |
| 269 | BCa = ROL(Ebu, 27); |
| 270 | Ega ^= Da; |
| 271 | BCe = ROL(Ega, 36); |
| 272 | Eke ^= De; |
| 273 | BCi = ROL(Eke, 10); |
| 274 | Emi ^= Di; |
| 275 | BCo = ROL(Emi, 15); |
| 276 | Eso ^= Do; |
| 277 | BCu = ROL(Eso, 56); |
| 278 | Ama = BCa ^ ((~BCe) & BCi); |
| 279 | Ame = BCe ^ ((~BCi) & BCo); |
| 280 | Ami = BCi ^ ((~BCo) & BCu); |
| 281 | Amo = BCo ^ ((~BCu) & BCa); |
| 282 | Amu = BCu ^ ((~BCa) & BCe); |
| 283 | |
| 284 | Ebi ^= Di; |
| 285 | BCa = ROL(Ebi, 62); |
| 286 | Ego ^= Do; |
| 287 | BCe = ROL(Ego, 55); |
| 288 | Eku ^= Du; |
| 289 | BCi = ROL(Eku, 39); |
| 290 | Ema ^= Da; |
| 291 | BCo = ROL(Ema, 41); |
| 292 | Ese ^= De; |
| 293 | BCu = ROL(Ese, 2); |
| 294 | Asa = BCa ^ ((~BCe) & BCi); |
| 295 | Ase = BCe ^ ((~BCi) & BCo); |
| 296 | Asi = BCi ^ ((~BCo) & BCu); |
| 297 | Aso = BCo ^ ((~BCu) & BCa); |
| 298 | Asu = BCu ^ ((~BCa) & BCe); |
| 299 | } |
| 300 | |
| 301 | //copyToState(state, A) |
| 302 | state[0] = Aba; |
| 303 | state[1] = Abe; |
| 304 | state[2] = Abi; |
| 305 | state[3] = Abo; |
| 306 | state[4] = Abu; |
| 307 | state[5] = Aga; |
| 308 | state[6] = Age; |
| 309 | state[7] = Agi; |
| 310 | state[8] = Ago; |
| 311 | state[9] = Agu; |
| 312 | state[10] = Aka; |
| 313 | state[11] = Ake; |
| 314 | state[12] = Aki; |
| 315 | state[13] = Ako; |
| 316 | state[14] = Aku; |
| 317 | state[15] = Ama; |
| 318 | state[16] = Ame; |
| 319 | state[17] = Ami; |
| 320 | state[18] = Amo; |
| 321 | state[19] = Amu; |
| 322 | state[20] = Asa; |
| 323 | state[21] = Ase; |
| 324 | state[22] = Asi; |
| 325 | state[23] = Aso; |
| 326 | state[24] = Asu; |
| 327 | |
| 328 | #undef round |
| 329 | } |
| 330 | |
| 331 | #include <string.h> |
| 332 | #define MIN(a, b) ((a) < (b) ? (a) : (b)) |
| 333 | |
| 334 | static void keccak_absorb(uint64_t *s, |
| 335 | unsigned int r, |
| 336 | const unsigned char *m, unsigned long long int mlen, |
| 337 | unsigned char p) |
| 338 | { |
| 339 | unsigned long long i; |
| 340 | unsigned char t[200]; |
| 341 | |
| 342 | while (mlen >= r) |
| 343 | { |
| 344 | for (i = 0; i < r / 8; ++i) |
| 345 | s[i] ^= load64(m + 8 * i); |
| 346 | |
| 347 | KeccakF1600_StatePermute(s); |
| 348 | mlen -= r; |
| 349 | m += r; |
| 350 | } |
| 351 | |
| 352 | for (i = 0; i < r; ++i) |
| 353 | t[i] = 0; |
| 354 | for (i = 0; i < mlen; ++i) |
| 355 | t[i] = m[i]; |
| 356 | t[i] = p; |
| 357 | t[r - 1] |= 128; |
| 358 | for (i = 0; i < r / 8; ++i) |
| 359 | s[i] ^= load64(t + 8 * i); |
| 360 | } |
| 361 | |
| 362 | static void keccak_squeezeblocks(unsigned char *h, unsigned long long int nblocks, |
| 363 | uint64_t *s, |
| 364 | unsigned int r) |
| 365 | { |
| 366 | unsigned int i; |
| 367 | while (nblocks > 0) |
| 368 | { |
| 369 | KeccakF1600_StatePermute(s); |
| 370 | for (i = 0; i < (r >> 3); i++) |
| 371 | { |
| 372 | store64(h + 8 * i, s[i]); |
| 373 | } |
| 374 | h += r; |
| 375 | nblocks--; |
| 376 | } |
| 377 | } |
| 378 | |
| 379 | /* |
| 380 | static void saber_shake128_absorb(uint64_t *s, const unsigned char *input, unsigned int inputByteLen) |
| 381 | { |
| 382 | keccak_absorb(s, SHAKE128_RATE, input, inputByteLen, 0x1F); |
| 383 | } |
| 384 | */ |
| 385 | |
| 386 | void saber_shake128(unsigned char *output, unsigned long long outlen, |
| 387 | const unsigned char *input, unsigned long long inlen) |
| 388 | { |
| 389 | uint64_t s[25]; |
| 390 | unsigned char t[SHAKE128_RATE]; |
| 391 | unsigned long long nblocks = outlen / SHAKE128_RATE; |
| 392 | size_t i; |
| 393 | |
| 394 | for (i = 0; i < 25; ++i) |
| 395 | s[i] = 0; |
| 396 | |
| 397 | /* Absorb input */ |
| 398 | keccak_absorb(s, SHAKE128_RATE, input, inlen, 0x1F); |
| 399 | |
| 400 | /* Squeeze output */ |
| 401 | keccak_squeezeblocks(output, nblocks, s, SHAKE128_RATE); |
| 402 | |
| 403 | output += nblocks * SHAKE128_RATE; |
| 404 | outlen -= nblocks * SHAKE128_RATE; |
| 405 | |
| 406 | if (outlen) |
| 407 | { |
| 408 | keccak_squeezeblocks(t, 1, s, SHAKE128_RATE); |
| 409 | for (i = 0; i < outlen; i++) |
| 410 | output[i] = t[i]; |
| 411 | } |
| 412 | } |
| 413 | |
| 414 | // void csaber_shake128_simple_absorb(uint64_t s[25], |
| 415 | // uint16_t cstm, // 2-byte domain separator |
| 416 | // const unsigned char *in, unsigned long long inlen) |
| 417 | // { |
| 418 | // unsigned char *sep = (unsigned char *)s; |
| 419 | // unsigned int i; |
| 420 | |
| 421 | // for(i=0;i<25;i++) |
| 422 | // s[i] = 0; |
| 423 | |
| 424 | // /* Absorb customization (domain-separation) string */ |
| 425 | // sep[0] = 0x01; |
| 426 | // sep[1] = 0xa8; |
| 427 | // sep[2] = 0x01; |
| 428 | // sep[3] = 0x00; |
| 429 | // sep[4] = 0x01; |
| 430 | // sep[5] = 16; // fixed bitlen of cstm |
| 431 | // sep[6] = cstm & 0xff; |
| 432 | // sep[7] = cstm >> 8; |
| 433 | |
| 434 | // KeccakF1600_StatePermute(s); |
| 435 | |
| 436 | // /* Absorb input */ |
| 437 | // keccak_absorb(s, SHAKE128_RATE, in, inlen, 0x04); |
| 438 | // } |
| 439 | |
| 440 | // void csaber_shake128_simple_squeezeblocks(unsigned char *output, unsigned long long nblocks, uint64_t *s) |
| 441 | // { |
| 442 | // keccak_squeezeblocks(output, nblocks, s, SHAKE128_RATE); |
| 443 | // } |
| 444 | |
| 445 | // void csaber_shake128_simple(unsigned char *output, unsigned long long outlen, |
| 446 | // uint16_t cstm, // 2-byte domain separator |
| 447 | // const unsigned char *in, unsigned long long inlen) |
| 448 | // { |
| 449 | // uint64_t s[25]; |
| 450 | // unsigned char t[SHAKE128_RATE]; |
| 451 | // unsigned int i; |
| 452 | |
| 453 | // csaber_shake128_simple_absorb(s,cstm,in,inlen); |
| 454 | |
| 455 | // /* Squeeze output */ |
| 456 | // keccak_squeezeblocks(output, outlen/SHAKE128_RATE, s, SHAKE128_RATE); |
| 457 | // output+=(outlen/SHAKE128_RATE)*SHAKE128_RATE; |
| 458 | |
| 459 | // if(outlen%SHAKE128_RATE) |
| 460 | // { |
| 461 | // keccak_squeezeblocks(t, 1, s, SHAKE128_RATE); |
| 462 | // for(i=0;i<outlen%SHAKE128_RATE;i++) |
| 463 | // output[i] = t[i]; |
| 464 | // } |
| 465 | // } |
| 466 | |
| 467 | void saber_sha3_256(unsigned char *output, const unsigned char *input, unsigned long long inlen) |
| 468 | { |
| 469 | uint64_t s[25]; |
| 470 | unsigned char t[SHA3_256_RATE]; |
| 471 | size_t i; |
| 472 | |
| 473 | for (i = 0; i < 25; ++i) |
| 474 | s[i] = 0; |
| 475 | |
| 476 | /* Absorb input */ |
| 477 | keccak_absorb(s, SHA3_256_RATE, input, inlen, 0x06); |
| 478 | |
| 479 | /* Squeeze output */ |
| 480 | keccak_squeezeblocks(t, 1, s, SHA3_256_RATE); |
| 481 | |
| 482 | for (i = 0; i < 32; i++) |
| 483 | output[i] = t[i]; |
| 484 | } |
| 485 | |
| 486 | void saber_sha3_512(unsigned char *output, const unsigned char *input, unsigned long long inlen) |
| 487 | { |
| 488 | uint64_t s[25]; |
| 489 | unsigned char t[SHA3_512_RATE]; |
| 490 | size_t i; |
| 491 | |
| 492 | for (i = 0; i < 25; ++i) |
| 493 | s[i] = 0; |
| 494 | |
| 495 | /* Absorb input */ |
| 496 | keccak_absorb(s, SHA3_512_RATE, input, inlen, 0x06); |
| 497 | |
| 498 | /* Squeeze output */ |
| 499 | keccak_squeezeblocks(t, 1, s, SHA3_512_RATE); |
| 500 | |
| 501 | for (i = 0; i < 64; i++) |
| 502 | output[i] = t[i]; |
| 503 | } |