Harald Welte | 8bd9d5d | 2023-05-28 09:36:50 +0200 | [diff] [blame] | 1 | /* ----------------------------------------------------------------------- |
| 2 | * code extracted from 3GPP TS 35.231, annex E for Keccak core functions |
| 3 | * https://portal.3gpp.org/desktopmodules/Specifications/SpecificationDetails.aspx?specificationId=2402 |
| 4 | *-----------------------------------------------------------------------*/ |
| 5 | |
| 6 | /* This code may be freely used or adapted. |
| 7 | */ |
| 8 | |
| 9 | #include "KeccakP-1600-3gpp.h" |
| 10 | |
| 11 | |
| 12 | const uint8_t Rho[25] = {0,1,62,28,27,36,44,6,55,20,3,10,43,25,39,41,45, |
| 13 | 15,21,8,18,2,61,56,14}; |
| 14 | |
| 15 | const uint8_t Pi[25] = {0,6,12,18,24,3,9,10,16,22,1,7,13,19,20,4,5,11,17, |
| 16 | 23,2,8,14,15,21}; |
| 17 | |
| 18 | const uint8_t Iota[24] = {1,146,218,112,155,33,241,89,138,136,57,42,187,203, |
| 19 | 217,83,82,192,26,106,241,208,33,120}; |
| 20 | |
| 21 | #define ROTATE64(value, n) \ |
| 22 | ((((uint64_t)(value))<<(n)) | (((uint64_t)(value))>>(64-(n)))) |
| 23 | |
| 24 | /* --------------------------------------------------------------------- |
| 25 | 64-bit version of Keccak_f(1600) |
| 26 | --------------------------------------------------------------------- |
| 27 | */ |
| 28 | void Keccak_f_64(uint64_t s[25]) |
| 29 | { uint64_t t[5]; |
| 30 | uint8_t i, j, round; |
| 31 | |
| 32 | for(round=0; round<24; ++round) |
| 33 | { /* Theta function */ |
| 34 | for(i=0; i<5; ++i) |
| 35 | t[i] = s[i] ^ s[5+i] ^ s[10+i] ^ s[15+i] ^ s[20+i]; |
| 36 | for(i=0; i<5; ++i, s+=5) |
| 37 | { s[0] ^= t[4] ^ ROTATE64(t[1], 1); |
| 38 | s[1] ^= t[0] ^ ROTATE64(t[2], 1); |
| 39 | s[2] ^= t[1] ^ ROTATE64(t[3], 1); |
| 40 | s[3] ^= t[2] ^ ROTATE64(t[4], 1); |
| 41 | s[4] ^= t[3] ^ ROTATE64(t[0], 1); |
| 42 | } |
| 43 | s -= 25; |
| 44 | |
| 45 | /* Rho function */ |
| 46 | for(i=1; i<25; ++i) |
| 47 | s[i] = ROTATE64(s[i], Rho[i]); |
| 48 | |
| 49 | /* Pi function */ |
| 50 | for(t[1] = s[i=1]; (j=Pi[i]) > 1; s[i]=s[j], i=j); |
| 51 | s[i] = t[1]; |
| 52 | |
| 53 | /* Chi function */ |
| 54 | for(i=0; i<5; ++i, s += 5) |
| 55 | { t[0] = (~s[1]) & s[2]; |
| 56 | t[1] = (~s[2]) & s[3]; |
| 57 | t[2] = (~s[3]) & s[4]; |
| 58 | t[3] = (~s[4]) & s[0]; |
| 59 | t[4] = (~s[0]) & s[1]; |
| 60 | for(j=0; j<5; ++j) s[j] ^= t[j]; |
| 61 | } |
| 62 | s -= 25; |
| 63 | |
| 64 | /* Iota function */ |
| 65 | t[0] = Iota[round]; |
| 66 | *s ^= (t[0] | (t[0]<<11) | (t[0]<<26) | (t[0]<<57)) |
| 67 | & 0x800000008000808BULL; /* set & mask bits 0,1,3,7,15,31,63 */ |
| 68 | } |
| 69 | } |
| 70 | |
| 71 | |
| 72 | /* --------------------------------------------------------------------- |
| 73 | 8-bit version of Keccak_f(1600) |
| 74 | --------------------------------------------------------------------- |
| 75 | */ |
| 76 | void Keccak_f_8(uint8_t s[200]) |
| 77 | { uint8_t t[40], i, j, k, round; |
| 78 | |
| 79 | for(round=0; round<24; ++round) |
| 80 | { /* Theta function */ |
| 81 | for(i=0; i<40; ++i) |
| 82 | t[i]=s[i]^s[40+i]^s[80+i]^s[120+i]^s[160+i]; |
| 83 | for(i=0; i<200; i+=8) |
| 84 | for(j = (i+32)%40, k=0; k<8; ++k) |
| 85 | s[i+k] ^= t[j+k]; |
| 86 | for(i=0; i<40; t[i] = (t[i]<<1)|j, i+=8) |
| 87 | for(j = t[i+7]>>7, k=7; k; --k) |
| 88 | t[i+k] = (t[i+k]<<1)|(t[i+k-1]>>7); |
| 89 | for(i=0; i<200; i+=8) |
| 90 | for(j = (i+8)%40, k=0; k<8; ++k) |
| 91 | s[i+k] ^= t[j+k]; |
| 92 | |
| 93 | /* Rho function */ |
| 94 | for(i=8; i<200; i+=8) |
| 95 | { for(j = Rho[i>>3]>>3, k=0; k<8; ++k) /* j:=bytes to shift, s->t */ |
| 96 | t[(k+j)&7] = s[i+k]; |
| 97 | for(j = Rho[i>>3]&7, k=7; k; --k) /* j:=bits to shift, t->s */ |
| 98 | s[i+k] = (t[k]<<j) | (t[k-1]>>(8-j)); |
| 99 | s[i] = (t[0]<<j) | (t[7]>>(8-j)); |
| 100 | } |
| 101 | |
| 102 | /* Pi function */ |
| 103 | for(k=8; k<16; ++k) t[k] = s[k]; /* =memcpy(t+8, s+8, 8) */ |
| 104 | for(i=1; (j=Pi[i])>1; i=j) |
| 105 | for(k=0; k<8; ++k) /* =memcpy(s+(i<<3), s+(j<<3), 8) */ |
| 106 | s[(i<<3)|k] = s[(j<<3)|k]; |
| 107 | for(k=0; k<8; ++k) /* =memcpy(s+(i<<3), t+8, 8) */ |
| 108 | s[(i<<3)|k] = t[k+8]; |
| 109 | |
| 110 | /* Chi function */ |
| 111 | for(i=0; i<200; i+=40) |
| 112 | { for(j=0; j<40; ++j) |
| 113 | t[j]=(~s[i+(j+8)%40]) & s[i+(j+16)%40]; |
| 114 | for(j=0; j<40; ++j) s[i+j]^=t[j]; |
| 115 | } |
| 116 | |
| 117 | /* Iota function */ |
| 118 | k = Iota[round]; |
| 119 | s[0] ^= k & 0x8B; /* bits 0, 1, 3, 7 */ |
| 120 | s[1] ^= (k<<3)&0x80; /* bit 15 */ |
| 121 | s[3] ^= (k<<2)&0x80; /* bit 31 */ |
| 122 | s[7] ^= (k<<1)&0x80; /* bit 63 */ |
| 123 | |
| 124 | } |
| 125 | } |
| 126 | |
| 127 | /* --------------------------------------------------------------------- |
| 128 | 32-bit version of Keccak_f(1600) |
| 129 | --------------------------------------------------------------------- |
| 130 | */ |
| 131 | void Keccak_f_32(uint32_t s[50]) |
| 132 | { uint32_t t[10]; |
| 133 | uint8_t i, j, round, k; |
| 134 | |
| 135 | for(round=0; round<24; ++round) |
| 136 | { /* Theta function */ |
| 137 | for(i=0; i<10; ++i) |
| 138 | t[i] = s[i] ^ s[10+i] ^ s[20+i] ^ s[30+i] ^ s[40+i]; |
| 139 | for(i=0; i<5; ++i) |
| 140 | for(j=8, k=2; ; j%=10, k=(k+2)%10) |
| 141 | { *s++ ^= t[j++] ^ ((t[k]<<1)|(t[k+1]>>31)); |
| 142 | *s++ ^= t[j++] ^ ((t[k+1]<<1)|(t[k]>>31)); |
| 143 | if(j==8) break; |
| 144 | } |
| 145 | s -= 50; |
| 146 | |
| 147 | /* Rho function */ |
| 148 | for(i=2; i<50; i+=2) |
| 149 | { k = Rho[i>>1] & 0x1f; |
| 150 | t[0] = (s[i+1] << k) | (s[i] >> (32-k)); |
| 151 | t[1] = (s[i] << k) | (s[i+1] >> (32-k)); |
| 152 | k = Rho[i>>1] >> 5; |
| 153 | s[i] = t[1-k], s[i+1] = t[k]; |
| 154 | } |
| 155 | |
| 156 | /* Pi function */ |
| 157 | for(i=2, t[0]=s[2], t[1]=s[3]; (j=(Pi[i>>1]<<1))>2; i=j) |
| 158 | s[i]=s[j], s[i+1]=s[j+1]; |
| 159 | s[i]=t[0], s[i+1]=t[1]; |
| 160 | |
| 161 | /* Chi function */ |
| 162 | for(i=0; i<5; ++i, s+=10) |
| 163 | { for(j=0; j<10; ++j) |
| 164 | t[j] = (~s[(j+2)%10]) & s[(j+4)%10]; |
| 165 | for(j=0; j<10; ++j) |
| 166 | s[j] ^= t[j]; |
| 167 | } |
| 168 | s -= 50; |
| 169 | |
| 170 | /* Iota function */ |
| 171 | t[0] = Iota[round]; |
| 172 | s[0] ^= (t[0] | (t[0]<<11) | (t[0]<<26)) & 0x8000808B; |
| 173 | s[1] ^= (t[0]<<25) & 0x80000000; |
| 174 | } |
| 175 | } |
| 176 | |