├── .travis.yml ├── KeccakF-1600-interface.h ├── KeccakF-1600-reference.c ├── KeccakF-1600-reference32BI.c ├── KeccakF-reference.h ├── KeccakHash.c ├── KeccakHash.h ├── KeccakSponge.c ├── KeccakSponge.h ├── LICENSE ├── SnP-FBWL-default.c ├── SnP-FBWL-default.h ├── SnP-interface.h ├── brg_endian.h ├── config.m4 ├── config.w32 ├── displayIntermediateValues.c ├── displayIntermediateValues.h ├── php_sha3.c ├── php_sha3.h ├── readme.md └── tests ├── sha3_224.phpt ├── sha3_256.phpt ├── sha3_384.phpt ├── sha3_512.phpt └── test_helper.php /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | php: 3 | - '5.6' 4 | - '7.0' 5 | - '7.1' 6 | - '7.2' 7 | env: 8 | - NO_INTERACTION=1 9 | matrix: 10 | include: 11 | - os: osx 12 | language: generic 13 | php: '7.2' 14 | before_install: 15 | - brew update 16 | - brew install php 17 | before_script: 18 | - phpize 19 | - ./configure --enable-sha3 20 | - make 21 | script: make test 22 | -------------------------------------------------------------------------------- /KeccakF-1600-interface.h: -------------------------------------------------------------------------------- 1 | /* 2 | Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, 3 | Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby 4 | denoted as "the implementer". 5 | 6 | For more information, feedback or questions, please refer to our websites: 7 | http://keccak.noekeon.org/ 8 | http://keyak.noekeon.org/ 9 | http://ketje.noekeon.org/ 10 | 11 | To the extent possible under law, the implementer has waived all copyright 12 | and related or neighboring rights to the source code in this file. 13 | http://creativecommons.org/publicdomain/zero/1.0/ 14 | */ 15 | 16 | #ifndef _KeccakF1600Interface_h_ 17 | #define _KeccakF1600Interface_h_ 18 | 19 | #include 20 | 21 | #define KeccakF_width 1600 22 | #define KeccakF_laneInBytes 8 23 | #define KeccakF_stateSizeInBytes (KeccakF_width/8) 24 | #define KeccakF_1600 25 | 26 | void KeccakF1600_Initialize( void ); 27 | void KeccakF1600_StateInitialize(void *state); 28 | void KeccakF1600_StateXORBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length); 29 | void KeccakF1600_StateOverwriteBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length); 30 | void KeccakF1600_StateOverwriteWithZeroes(void *state, unsigned int byteCount); 31 | void KeccakF1600_StateComplementBit(void *state, unsigned int position); 32 | void KeccakF1600_StatePermute(void *state); 33 | void KeccakF1600_StateExtractBytes(const void *state, unsigned char *data, unsigned int offset, unsigned int length); 34 | void KeccakF1600_StateExtractAndXORBytes(const void *state, unsigned char *data, unsigned int offset, unsigned int length); 35 | size_t KeccakF1600_FBWL_Absorb(void *state, unsigned int laneCount, const unsigned char *data, size_t dataByteLen, unsigned char trailingBits); 36 | size_t KeccakF1600_FBWL_Squeeze(void *state, unsigned int laneCount, unsigned char *data, size_t dataByteLen); 37 | size_t KeccakF1600_FBWL_Wrap(void *state, unsigned int laneCount, const unsigned char *dataIn, unsigned char *dataOut, size_t dataByteLen, unsigned char trailingBits); 38 | size_t KeccakF1600_FBWL_Unwrap(void *state, unsigned int laneCount, const unsigned char *dataIn, unsigned char *dataOut, size_t dataByteLen, unsigned char trailingBits); 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /KeccakF-1600-reference.c: -------------------------------------------------------------------------------- 1 | /* 2 | Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, 3 | Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby 4 | denoted as "the implementer". 5 | 6 | For more information, feedback or questions, please refer to our websites: 7 | http://keccak.noekeon.org/ 8 | http://keyak.noekeon.org/ 9 | http://ketje.noekeon.org/ 10 | 11 | To the extent possible under law, the implementer has waived all copyright 12 | and related or neighboring rights to the source code in this file. 13 | http://creativecommons.org/publicdomain/zero/1.0/ 14 | */ 15 | 16 | #include 17 | #include 18 | #include 19 | #include "brg_endian.h" 20 | #include "displayIntermediateValues.h" 21 | 22 | typedef unsigned char UINT8; 23 | typedef unsigned long long UINT64; 24 | typedef UINT64 tKeccakLane; 25 | 26 | #define nrRounds 24 27 | tKeccakLane KeccakRoundConstants[nrRounds]; 28 | #define nrLanes 25 29 | unsigned int KeccakRhoOffsets[nrLanes]; 30 | 31 | /* ---------------------------------------------------------------- */ 32 | 33 | void KeccakF1600_InitializeRoundConstants(); 34 | void KeccakF1600_InitializeRhoOffsets(); 35 | int LFSR86540(UINT8 *LFSR); 36 | 37 | void KeccakF1600_Initialize() 38 | { 39 | if (sizeof(tKeccakLane) != 8) { 40 | printf("tKeccakLane should be 64-bit wide\n"); 41 | abort(); 42 | } 43 | KeccakF1600_InitializeRoundConstants(); 44 | KeccakF1600_InitializeRhoOffsets(); 45 | } 46 | 47 | void KeccakF1600_InitializeRoundConstants() 48 | { 49 | UINT8 LFSRstate = 0x01; 50 | unsigned int i, j, bitPosition; 51 | 52 | for(i=0; i> (8*j)) & 0xFF; 181 | } 182 | 183 | void KeccakF1600OnWords(tKeccakLane *state) 184 | { 185 | unsigned int i; 186 | 187 | displayStateAsLanes(3, "Same, with lanes as 64-bit words", state); 188 | 189 | for(i=0; i> (64-offset))) : a) 214 | 215 | void theta(tKeccakLane *A) 216 | { 217 | unsigned int x, y; 218 | tKeccakLane C[5], D[5]; 219 | 220 | for(x=0; x<5; x++) { 221 | C[x] = 0; 222 | for(y=0; y<5; y++) 223 | C[x] ^= A[index(x, y)]; 224 | } 225 | for(x=0; x<5; x++) 226 | D[x] = ROL64(C[(x+1)%5], 1) ^ C[(x+4)%5]; 227 | for(x=0; x<5; x++) 228 | for(y=0; y<5; y++) 229 | A[index(x, y)] ^= D[x]; 230 | } 231 | 232 | void rho(tKeccakLane *A) 233 | { 234 | unsigned int x, y; 235 | 236 | for(x=0; x<5; x++) for(y=0; y<5; y++) 237 | A[index(x, y)] = ROL64(A[index(x, y)], KeccakRhoOffsets[index(x, y)]); 238 | } 239 | 240 | void K_pi(tKeccakLane *A) 241 | { 242 | unsigned int x, y; 243 | tKeccakLane tempA[25]; 244 | 245 | for(x=0; x<5; x++) for(y=0; y<5; y++) 246 | tempA[index(x, y)] = A[index(x, y)]; 247 | for(x=0; x<5; x++) for(y=0; y<5; y++) 248 | A[index(0*x+1*y, 2*x+3*y)] = tempA[index(x, y)]; 249 | } 250 | 251 | void chi(tKeccakLane *A) 252 | { 253 | unsigned int x, y; 254 | tKeccakLane C[5]; 255 | 256 | for(y=0; y<5; y++) { 257 | for(x=0; x<5; x++) 258 | C[x] = A[index(x, y)] ^ ((~A[index(x+1, y)]) & A[index(x+2, y)]); 259 | for(x=0; x<5; x++) 260 | A[index(x, y)] = C[x]; 261 | } 262 | } 263 | 264 | void iota(tKeccakLane *A, unsigned int indexRound) 265 | { 266 | A[index(0, 0)] ^= KeccakRoundConstants[indexRound]; 267 | } 268 | 269 | /* ---------------------------------------------------------------- */ 270 | 271 | void KeccakF1600_StateExtractBytes(const void *state, unsigned char *data, unsigned int offset, unsigned int length) 272 | { 273 | memcpy(data, (unsigned char*)state+offset, length); 274 | } 275 | 276 | /* ---------------------------------------------------------------- */ 277 | 278 | void KeccakF1600_StateExtractAndXORBytes(const void *state, unsigned char *data, unsigned int offset, unsigned int length) 279 | { 280 | unsigned int i; 281 | 282 | for(i=0; i> 32)); 295 | fprintf(f, "%08X", (unsigned int)(KeccakRoundConstants[i] & 0xFFFFFFFFULL)); 296 | fprintf(f, "\n"); 297 | } 298 | fprintf(f, "\n"); 299 | } 300 | 301 | void displayRhoOffsets(FILE *f) 302 | { 303 | unsigned int x, y; 304 | 305 | for(y=0; y<5; y++) for(x=0; x<5; x++) { 306 | fprintf(f, "RhoOffset[%i][%i] = ", x, y); 307 | fprintf(f, "%2i", KeccakRhoOffsets[index(x, y)]); 308 | fprintf(f, "\n"); 309 | } 310 | fprintf(f, "\n"); 311 | } 312 | -------------------------------------------------------------------------------- /KeccakF-1600-reference32BI.c: -------------------------------------------------------------------------------- 1 | /* 2 | Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, 3 | Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby 4 | denoted as "the implementer". 5 | 6 | For more information, feedback or questions, please refer to our websites: 7 | http://keccak.noekeon.org/ 8 | http://keyak.noekeon.org/ 9 | http://ketje.noekeon.org/ 10 | 11 | To the extent possible under law, the implementer has waived all copyright 12 | and related or neighboring rights to the source code in this file. 13 | http://creativecommons.org/publicdomain/zero/1.0/ 14 | */ 15 | 16 | #include 17 | #include 18 | #include "brg_endian.h" 19 | #include "displayIntermediateValues.h" 20 | #include "KeccakF-1600-interface.h" 21 | 22 | typedef unsigned char UINT8; 23 | typedef unsigned int UINT32; 24 | // WARNING: on 8-bit and 16-bit platforms, this should be replaced by: 25 | //typedef unsigned long UINT32; 26 | 27 | #define nrRounds 24 28 | UINT32 KeccakRoundConstants[nrRounds][2]; 29 | #define nrLanes 25 30 | unsigned int KeccakRhoOffsets[nrLanes]; 31 | 32 | /* ---------------------------------------------------------------- */ 33 | 34 | void toBitInterleaving(UINT32 low, UINT32 high, UINT32 *even, UINT32 *odd); 35 | void fromBitInterleaving(UINT32 even, UINT32 odd, UINT32 *low, UINT32 *high); 36 | 37 | void toBitInterleaving(UINT32 low, UINT32 high, UINT32 *even, UINT32 *odd) 38 | { 39 | unsigned int i; 40 | 41 | *even = 0; 42 | *odd = 0; 43 | for(i=0; i<64; i++) { 44 | unsigned int inBit; 45 | if (i < 32) 46 | inBit = (low >> i) & 1; 47 | else 48 | inBit = (high >> (i-32)) & 1; 49 | if ((i % 2) == 0) 50 | *even |= inBit << (i/2); 51 | else 52 | *odd |= inBit << ((i-1)/2); 53 | } 54 | } 55 | 56 | void fromBitInterleaving(UINT32 even, UINT32 odd, UINT32 *low, UINT32 *high) 57 | { 58 | unsigned int i; 59 | 60 | *low = 0; 61 | *high = 0; 62 | for(i=0; i<64; i++) { 63 | unsigned int inBit; 64 | if ((i % 2) == 0) 65 | inBit = (even >> (i/2)) & 1; 66 | else 67 | inBit = (odd >> ((i-1)/2)) & 1; 68 | if (i < 32) 69 | *low |= inBit << i; 70 | else 71 | *high |= inBit << (i-32); 72 | } 73 | } 74 | 75 | /* ---------------------------------------------------------------- */ 76 | 77 | void KeccakF1600_InitializeRoundConstants(); 78 | void KeccakF1600_InitializeRhoOffsets(); 79 | int LFSR86540(UINT8 *LFSR); 80 | 81 | void KeccakF1600_Initialize() 82 | { 83 | KeccakF1600_InitializeRoundConstants(); 84 | KeccakF1600_InitializeRhoOffsets(); 85 | } 86 | 87 | void KeccakF1600_InitializeRoundConstants() 88 | { 89 | UINT8 LFSRstate = 0x01; 90 | unsigned int i, j, bitPosition; 91 | UINT32 low, high; 92 | 93 | for(i=0; i 0) { 175 | unsigned int bytesInLane = 8 - offsetInLane; 176 | if (bytesInLane > length) 177 | bytesInLane = length; 178 | KeccakF1600_StateXORBytesInLane(state, lanePosition, data, offsetInLane, bytesInLane); 179 | length -= bytesInLane; 180 | lanePosition++; 181 | offsetInLane = 0; 182 | data += bytesInLane; 183 | } 184 | } 185 | } 186 | 187 | /* ---------------------------------------------------------------- */ 188 | 189 | void KeccakF1600_StateExtractBytesInLane(const void *state, unsigned int lanePosition, unsigned char *data, unsigned int offset, unsigned int length); 190 | 191 | void KeccakF1600_StateOverwriteBytesInLane(void *state, unsigned int lanePosition, const unsigned char *data, unsigned int offset, unsigned int length) 192 | { 193 | if ((lanePosition < 25) && (offset < 8) && (offset+length <= 8)) { 194 | UINT8 laneAsBytes[8]; 195 | UINT32 low, high; 196 | UINT32 lane[2]; 197 | UINT32 *stateAsHalfLanes; 198 | 199 | KeccakF1600_StateExtractBytesInLane(state, lanePosition, laneAsBytes, 0, 8); 200 | memcpy(laneAsBytes+offset, data, length); 201 | low = laneAsBytes[0] 202 | | ((UINT32)(laneAsBytes[1]) << 8) 203 | | ((UINT32)(laneAsBytes[2]) << 16) 204 | | ((UINT32)(laneAsBytes[3]) << 24); 205 | high = laneAsBytes[4] 206 | | ((UINT32)(laneAsBytes[5]) << 8) 207 | | ((UINT32)(laneAsBytes[6]) << 16) 208 | | ((UINT32)(laneAsBytes[7]) << 24); 209 | toBitInterleaving(low, high, lane, lane+1); 210 | stateAsHalfLanes = (UINT32*)state; 211 | stateAsHalfLanes[lanePosition*2+0] = lane[0]; 212 | stateAsHalfLanes[lanePosition*2+1] = lane[1]; 213 | } 214 | } 215 | 216 | void KeccakF1600_StateOverwriteBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length) 217 | { 218 | if ((offset < 200) && (offset+length <= 200)) { 219 | unsigned int lanePosition = offset/8; 220 | unsigned int offsetInLane = offset%8; 221 | while(length > 0) { 222 | unsigned int bytesInLane = 8 - offsetInLane; 223 | if (bytesInLane > length) 224 | bytesInLane = length; 225 | KeccakF1600_StateOverwriteBytesInLane(state, lanePosition, data, offsetInLane, bytesInLane); 226 | length -= bytesInLane; 227 | lanePosition++; 228 | offsetInLane = 0; 229 | data += bytesInLane; 230 | } 231 | } 232 | } 233 | 234 | /* ---------------------------------------------------------------- */ 235 | 236 | void KeccakF1600_StateOverwriteWithZeroes(void *state, unsigned int byteCount) 237 | { 238 | if (byteCount <= 200) { 239 | UINT8 laneAsBytes[8]; 240 | unsigned int lanePosition = 0; 241 | 242 | memset(laneAsBytes, 0, 8); 243 | while(byteCount > 0) { 244 | if (byteCount < 8) { 245 | KeccakF1600_StateOverwriteBytesInLane(state, lanePosition, laneAsBytes, 0, byteCount); 246 | byteCount = 0; 247 | } 248 | else { 249 | UINT32 *stateAsHalfLanes = (UINT32*)state; 250 | stateAsHalfLanes[lanePosition*2+0] = 0; 251 | stateAsHalfLanes[lanePosition*2+1] = 0; 252 | byteCount -= 8; 253 | lanePosition++; 254 | } 255 | } 256 | } 257 | } 258 | 259 | /* ---------------------------------------------------------------- */ 260 | 261 | void KeccakF1600_StateComplementBit(void *state, unsigned int position) 262 | { 263 | if (position < 1600) { 264 | UINT32 *stateAsHalfLanes = (UINT32*)state; 265 | unsigned int lanePosition = position/64; 266 | unsigned int zeta = position%2; 267 | unsigned int bitInLane = (position%64)/2; 268 | stateAsHalfLanes[lanePosition*2+zeta] ^= (UINT32)1 << bitInLane; 269 | } 270 | } 271 | 272 | /* ---------------------------------------------------------------- */ 273 | 274 | void KeccakF1600_PermutationOnWords(UINT32 *state); 275 | void theta(UINT32 *A); 276 | void rho(UINT32 *A); 277 | void pi(UINT32 *A); 278 | void chi(UINT32 *A); 279 | void iota(UINT32 *A, unsigned int indexRound); 280 | void KeccakF1600_StateExtractBytes(const void *state, unsigned char *data, unsigned int offset, unsigned int length); 281 | 282 | void KeccakF1600_StatePermute(void *state) 283 | { 284 | UINT32 *stateAsHalfLanes = (UINT32*)state; 285 | { 286 | UINT8 stateAsBytes[KeccakF_width/8]; 287 | KeccakF1600_StateExtractBytes(state, stateAsBytes, 0, KeccakF_width/8); 288 | displayStateAsBytes(1, "Input of permutation", stateAsBytes); 289 | } 290 | KeccakF1600_PermutationOnWords(stateAsHalfLanes); 291 | { 292 | UINT8 stateAsBytes[KeccakF_width/8]; 293 | KeccakF1600_StateExtractBytes(state, stateAsBytes, 0, KeccakF_width/8); 294 | displayStateAsBytes(1, "State after permutation", stateAsBytes); 295 | } 296 | } 297 | 298 | void KeccakF1600_PermutationOnWords(UINT32 *state) 299 | { 300 | unsigned int i; 301 | 302 | displayStateAs32bitWords(3, "Same, with lanes as pairs of 32-bit words (bit interleaving)", state); 303 | 304 | for(i=0; i> (32-offset))) : a) 326 | 327 | void ROL64(UINT32 inEven, UINT32 inOdd, UINT32 *outEven, UINT32 *outOdd, unsigned int offset) 328 | { 329 | if ((offset % 2) == 0) { 330 | *outEven = ROL32(inEven, offset/2); 331 | *outOdd = ROL32(inOdd, offset/2); 332 | } 333 | else { 334 | *outEven = ROL32(inOdd, (offset+1)/2); 335 | *outOdd = ROL32(inEven, (offset-1)/2); 336 | } 337 | } 338 | 339 | void theta(UINT32 *A) 340 | { 341 | unsigned int x, y, z; 342 | UINT32 C[5][2], D[5][2]; 343 | 344 | for(x=0; x<5; x++) { 345 | for(z=0; z<2; z++) { 346 | C[x][z] = 0; 347 | for(y=0; y<5; y++) 348 | C[x][z] ^= A[index(x, y, z)]; 349 | } 350 | } 351 | for(x=0; x<5; x++) { 352 | ROL64(C[(x+1)%5][0], C[(x+1)%5][1], &(D[x][0]), &(D[x][1]), 1); 353 | for(z=0; z<2; z++) 354 | D[x][z] ^= C[(x+4)%5][z]; 355 | } 356 | for(x=0; x<5; x++) 357 | for(y=0; y<5; y++) 358 | for(z=0; z<2; z++) 359 | A[index(x, y, z)] ^= D[x][z]; 360 | } 361 | 362 | void rho(UINT32 *A) 363 | { 364 | unsigned int x, y; 365 | 366 | for(x=0; x<5; x++) for(y=0; y<5; y++) 367 | ROL64(A[index(x, y, 0)], A[index(x, y, 1)], &(A[index(x, y, 0)]), &(A[index(x, y, 1)]), KeccakRhoOffsets[5*y+x]); 368 | } 369 | 370 | void pi(UINT32 *A) 371 | { 372 | unsigned int x, y, z; 373 | UINT32 tempA[50]; 374 | 375 | for(x=0; x<5; x++) for(y=0; y<5; y++) for(z=0; z<2; z++) 376 | tempA[index(x, y, z)] = A[index(x, y, z)]; 377 | for(x=0; x<5; x++) for(y=0; y<5; y++) for(z=0; z<2; z++) 378 | A[index(0*x+1*y, 2*x+3*y, z)] = tempA[index(x, y, z)]; 379 | } 380 | 381 | void chi(UINT32 *A) 382 | { 383 | unsigned int x, y, z; 384 | UINT32 C[5][2]; 385 | 386 | for(y=0; y<5; y++) { 387 | for(x=0; x<5; x++) 388 | for(z=0; z<2; z++) 389 | C[x][z] = A[index(x, y, z)] ^ ((~A[index(x+1, y, z)]) & A[index(x+2, y, z)]); 390 | for(x=0; x<5; x++) 391 | for(z=0; z<2; z++) 392 | A[index(x, y, z)] = C[x][z]; 393 | } 394 | } 395 | 396 | void iota(UINT32 *A, unsigned int indexRound) 397 | { 398 | A[index(0, 0, 0)] ^= KeccakRoundConstants[indexRound][0]; 399 | A[index(0, 0, 1)] ^= KeccakRoundConstants[indexRound][1]; 400 | } 401 | 402 | /* ---------------------------------------------------------------- */ 403 | 404 | void KeccakF1600_StateExtractBytesInLane(const void *state, unsigned int lanePosition, unsigned char *data, unsigned int offset, unsigned int length) 405 | { 406 | if ((lanePosition < 25) && (offset < 8) && (offset+length <= 8)) { 407 | UINT32 *stateAsHalfLanes = (UINT32*)state; 408 | UINT32 lane[2]; 409 | UINT8 laneAsBytes[8]; 410 | fromBitInterleaving(stateAsHalfLanes[lanePosition*2], stateAsHalfLanes[lanePosition*2+1], lane, lane+1); 411 | laneAsBytes[0] = lane[0] & 0xFF; 412 | laneAsBytes[1] = (lane[0] >> 8) & 0xFF; 413 | laneAsBytes[2] = (lane[0] >> 16) & 0xFF; 414 | laneAsBytes[3] = (lane[0] >> 24) & 0xFF; 415 | laneAsBytes[4] = lane[1] & 0xFF; 416 | laneAsBytes[5] = (lane[1] >> 8) & 0xFF; 417 | laneAsBytes[6] = (lane[1] >> 16) & 0xFF; 418 | laneAsBytes[7] = (lane[1] >> 24) & 0xFF; 419 | memcpy(data, laneAsBytes+offset, length); 420 | } 421 | } 422 | 423 | void KeccakF1600_StateExtractBytes(const void *state, unsigned char *data, unsigned int offset, unsigned int length) 424 | { 425 | if ((offset < 200) && (offset+length <= 200)) { 426 | unsigned int lanePosition = offset/8; 427 | unsigned int offsetInLane = offset%8; 428 | while(length > 0) { 429 | unsigned int bytesInLane = 8 - offsetInLane; 430 | if (bytesInLane > length) 431 | bytesInLane = length; 432 | KeccakF1600_StateExtractBytesInLane(state, lanePosition, data, offsetInLane, bytesInLane); 433 | length -= bytesInLane; 434 | lanePosition++; 435 | offsetInLane = 0; 436 | data += bytesInLane; 437 | } 438 | } 439 | } 440 | 441 | /* ---------------------------------------------------------------- */ 442 | 443 | void KeccakF1600_StateExtractAndXORBytesInLane(const void *state, unsigned int lanePosition, unsigned char *data, unsigned int offset, unsigned int length) 444 | { 445 | if ((lanePosition < 25) && (offset < 8) && (offset+length <= 8)) { 446 | UINT8 laneAsBytes[8]; 447 | unsigned int i; 448 | 449 | KeccakF1600_StateExtractBytesInLane(state, lanePosition, laneAsBytes, offset, length); 450 | for(i=0; i 0) { 461 | unsigned int bytesInLane = 8 - offsetInLane; 462 | if (bytesInLane > length) 463 | bytesInLane = length; 464 | KeccakF1600_StateExtractAndXORBytesInLane(state, lanePosition, data, offsetInLane, bytesInLane); 465 | length -= bytesInLane; 466 | lanePosition++; 467 | offsetInLane = 0; 468 | data += bytesInLane; 469 | } 470 | } 471 | } 472 | 473 | /* ---------------------------------------------------------------- */ 474 | 475 | void displayRoundConstants(FILE *f) 476 | { 477 | unsigned int i; 478 | 479 | for(i=0; i 17 | #include "KeccakHash.h" 18 | 19 | /* ---------------------------------------------------------------- */ 20 | 21 | HashReturn Keccak_HashInitialize(Keccak_HashInstance *instance, unsigned int rate, unsigned int capacity, unsigned int hashbitlen, unsigned char delimitedSuffix) 22 | { 23 | HashReturn result; 24 | 25 | if (delimitedSuffix == 0) 26 | return SHA3_FAIL; 27 | result = (HashReturn)Keccak_SpongeInitialize(&instance->sponge, rate, capacity); 28 | if (result != SHA3_SUCCESS) 29 | return result; 30 | instance->fixedOutputLength = hashbitlen; 31 | instance->delimitedSuffix = delimitedSuffix; 32 | return SHA3_SUCCESS; 33 | } 34 | 35 | /* ---------------------------------------------------------------- */ 36 | 37 | HashReturn Keccak_HashUpdate(Keccak_HashInstance *instance, const BitSequence *data, DataLength databitlen) 38 | { 39 | if ((databitlen % 8) == 0) 40 | return (HashReturn)Keccak_SpongeAbsorb(&instance->sponge, data, databitlen/8); 41 | else { 42 | HashReturn ret = (HashReturn)Keccak_SpongeAbsorb(&instance->sponge, data, databitlen/8); 43 | if (ret == SHA3_SUCCESS) { 44 | // The last partial byte is assumed to be aligned on the least significant bits 45 | unsigned char lastByte = data[databitlen/8]; 46 | // Concatenate the last few bits provided here with those of the suffix 47 | unsigned short delimitedLastBytes = (unsigned short)lastByte | ((unsigned short)instance->delimitedSuffix << (databitlen % 8)); 48 | if ((delimitedLastBytes & 0xFF00) == 0x0000) { 49 | instance->delimitedSuffix = delimitedLastBytes & 0xFF; 50 | } 51 | else { 52 | unsigned char oneByte[1]; 53 | oneByte[0] = delimitedLastBytes & 0xFF; 54 | ret = (HashReturn)Keccak_SpongeAbsorb(&instance->sponge, oneByte, 1); 55 | instance->delimitedSuffix = (delimitedLastBytes >> 8) & 0xFF; 56 | } 57 | } 58 | return ret; 59 | } 60 | } 61 | 62 | /* ---------------------------------------------------------------- */ 63 | 64 | HashReturn Keccak_HashFinal(Keccak_HashInstance *instance, BitSequence *hashval) 65 | { 66 | HashReturn ret = (HashReturn)Keccak_SpongeAbsorbLastFewBits(&instance->sponge, instance->delimitedSuffix); 67 | if (ret == SHA3_SUCCESS) 68 | return (HashReturn)Keccak_SpongeSqueeze(&instance->sponge, hashval, instance->fixedOutputLength/8); 69 | else 70 | return ret; 71 | } 72 | 73 | /* ---------------------------------------------------------------- */ 74 | 75 | HashReturn Keccak_HashSqueeze(Keccak_HashInstance *instance, BitSequence *data, DataLength databitlen) 76 | { 77 | if ((databitlen % 8) != 0) 78 | return SHA3_FAIL; 79 | return (HashReturn)Keccak_SpongeSqueeze(&instance->sponge, data, databitlen/8); 80 | } 81 | -------------------------------------------------------------------------------- /KeccakHash.h: -------------------------------------------------------------------------------- 1 | /* 2 | Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, 3 | Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby 4 | denoted as "the implementer". 5 | 6 | For more information, feedback or questions, please refer to our websites: 7 | http://keccak.noekeon.org/ 8 | http://keyak.noekeon.org/ 9 | http://ketje.noekeon.org/ 10 | 11 | To the extent possible under law, the implementer has waived all copyright 12 | and related or neighboring rights to the source code in this file. 13 | http://creativecommons.org/publicdomain/zero/1.0/ 14 | */ 15 | 16 | #ifndef _KeccakHashInterface_h_ 17 | #define _KeccakHashInterface_h_ 18 | 19 | #include "KeccakSponge.h" 20 | #include 21 | 22 | typedef unsigned char BitSequence; 23 | typedef size_t DataLength; 24 | typedef enum { SHA3_SUCCESS = 0, SHA3_FAIL = 1, SHA3_BAD_HASHLEN = 2 } HashReturn; 25 | 26 | typedef struct { 27 | Keccak_SpongeInstance sponge; 28 | unsigned int fixedOutputLength; 29 | unsigned char delimitedSuffix; 30 | } Keccak_HashInstance; 31 | 32 | /** 33 | * Function to initialize the Keccak[r, c] sponge function instance used in sequential hashing mode. 34 | * @param hashInstance Pointer to the hash instance to be initialized. 35 | * @param rate The value of the rate r. 36 | * @param capacity The value of the capacity c. 37 | * @param hashbitlen The desired number of output bits, 38 | * or 0 for an arbitrarily-long output. 39 | * @param delimitedSuffix Bits that will be automatically appended to the end 40 | * of the input message, as in domain separation. 41 | * This is a byte containing from 0 to 7 bits 42 | * formatted like the @a delimitedData parameter of 43 | * the Keccak_SpongeAbsorbLastFewBits() function. 44 | * @pre One must have r+c=1600 and the rate a multiple of 8 bits in this implementation. 45 | * @return SUCCESS if successful, FAIL otherwise. 46 | */ 47 | HashReturn Keccak_HashInitialize(Keccak_HashInstance *hashInstance, unsigned int rate, unsigned int capacity, unsigned int hashbitlen, unsigned char delimitedSuffix); 48 | 49 | /** Macro to initialize a SHAKE128 instance as specified in the FIPS 202 draft. 50 | */ 51 | #define Keccak_HashInitialize_SHAKE128(hashInstance) Keccak_HashInitialize(hashInstance, 1344, 256, 0, 0x1F) 52 | 53 | /** Macro to initialize a SHAKE256 instance as specified in the FIPS 202 draft. 54 | */ 55 | #define Keccak_HashInitialize_SHAKE256(hashInstance) Keccak_HashInitialize(hashInstance, 1088, 512, 0, 0x1F) 56 | 57 | /** Macro to initialize a SHA3-224 instance as specified in the FIPS 202 draft. 58 | */ 59 | #define Keccak_HashInitialize_SHA3_224(hashInstance) Keccak_HashInitialize(hashInstance, 1152, 448, 224, 0x06) 60 | 61 | /** Macro to initialize a SHA3-256 instance as specified in the FIPS 202 draft. 62 | */ 63 | #define Keccak_HashInitialize_SHA3_256(hashInstance) Keccak_HashInitialize(hashInstance, 1088, 512, 256, 0x06) 64 | 65 | /** Macro to initialize a SHA3-384 instance as specified in the FIPS 202 draft. 66 | */ 67 | #define Keccak_HashInitialize_SHA3_384(hashInstance) Keccak_HashInitialize(hashInstance, 832, 768, 384, 0x06) 68 | 69 | /** Macro to initialize a SHA3-512 instance as specified in the FIPS 202 draft. 70 | */ 71 | #define Keccak_HashInitialize_SHA3_512(hashInstance) Keccak_HashInitialize(hashInstance, 576, 1024, 512, 0x06) 72 | 73 | /** 74 | * Function to give input data to be absorbed. 75 | * @param hashInstance Pointer to the hash instance initialized by Keccak_HashInitialize(). 76 | * @param data Pointer to the input data. 77 | * When @a databitLen is not a multiple of 8, the last bits of data must be 78 | * in the least significant bits of the last byte (little-endian convention). 79 | * @param databitLen The number of input bits provided in the input data. 80 | * @pre In the previous call to Keccak_HashUpdate(), databitlen was a multiple of 8. 81 | * @return SUCCESS if successful, FAIL otherwise. 82 | */ 83 | HashReturn Keccak_HashUpdate(Keccak_HashInstance *hashInstance, const BitSequence *data, DataLength databitlen); 84 | 85 | /** 86 | * Function to call after all input blocks have been input and to get 87 | * output bits if the length was specified when calling Keccak_HashInitialize(). 88 | * @param hashInstance Pointer to the hash instance initialized by Keccak_HashInitialize(). 89 | * If @a hashbitlen was not 0 in the call to Keccak_HashInitialize(), the number of 90 | * output bits is equal to @a hashbitlen. 91 | * If @a hashbitlen was 0 in the call to Keccak_HashInitialize(), the output bits 92 | * must be extracted using the Keccak_HashSqueeze() function. 93 | * @param state Pointer to the state of the sponge function initialized by Init(). 94 | * @param hashval Pointer to the buffer where to store the output data. 95 | * @return SUCCESS if successful, FAIL otherwise. 96 | */ 97 | HashReturn Keccak_HashFinal(Keccak_HashInstance *hashInstance, BitSequence *hashval); 98 | 99 | /** 100 | * Function to squeeze output data. 101 | * @param hashInstance Pointer to the hash instance initialized by Keccak_HashInitialize(). 102 | * @param data Pointer to the buffer where to store the output data. 103 | * @param databitlen The number of output bits desired (must be a multiple of 8). 104 | * @pre Keccak_HashFinal() must have been already called. 105 | * @pre @a databitlen is a multiple of 8. 106 | * @return SUCCESS if successful, FAIL otherwise. 107 | */ 108 | HashReturn Keccak_HashSqueeze(Keccak_HashInstance *hashInstance, BitSequence *data, DataLength databitlen); 109 | 110 | #endif 111 | -------------------------------------------------------------------------------- /KeccakSponge.c: -------------------------------------------------------------------------------- 1 | /* 2 | Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, 3 | Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby 4 | denoted as "the implementer". 5 | 6 | For more information, feedback or questions, please refer to our websites: 7 | http://keccak.noekeon.org/ 8 | http://keyak.noekeon.org/ 9 | http://ketje.noekeon.org/ 10 | 11 | To the extent possible under law, the implementer has waived all copyright 12 | and related or neighboring rights to the source code in this file. 13 | http://creativecommons.org/publicdomain/zero/1.0/ 14 | */ 15 | 16 | #include 17 | #include "KeccakSponge.h" 18 | #include "SnP-interface.h" 19 | #ifdef KeccakReference 20 | #include "displayIntermediateValues.h" 21 | #endif 22 | 23 | /* ---------------------------------------------------------------- */ 24 | 25 | int Keccak_SpongeInitialize(Keccak_SpongeInstance *instance, unsigned int rate, unsigned int capacity) 26 | { 27 | if (rate+capacity != SnP_width) 28 | return 1; 29 | if ((rate <= 0) || (rate > SnP_width) || ((rate % 8) != 0)) 30 | return 1; 31 | SnP_StaticInitialize(); 32 | SnP_Initialize(instance->state); 33 | instance->rate = rate; 34 | instance->byteIOIndex = 0; 35 | instance->squeezing = 0; 36 | 37 | return 0; 38 | } 39 | 40 | /* ---------------------------------------------------------------- */ 41 | 42 | int Keccak_SpongeAbsorb(Keccak_SpongeInstance *instance, const unsigned char *data, size_t dataByteLen) 43 | { 44 | size_t i, j; 45 | unsigned int partialBlock; 46 | const unsigned char *curData; 47 | unsigned int rateInBytes = instance->rate/8; 48 | 49 | if (instance->squeezing) 50 | return 1; // Too late for additional input 51 | 52 | i = 0; 53 | curData = data; 54 | while(i < dataByteLen) { 55 | if ((instance->byteIOIndex == 0) && (dataByteLen >= (i + rateInBytes))) { 56 | // processing full blocks first 57 | if ((rateInBytes % SnP_laneLengthInBytes) == 0) { 58 | // fast lane: whole lane rate 59 | j = SnP_FBWL_Absorb(instance->state, rateInBytes/SnP_laneLengthInBytes, curData, dataByteLen - i, 0); 60 | i += j; 61 | curData += j; 62 | } 63 | else { 64 | for(j=dataByteLen-i; j>=rateInBytes; j-=rateInBytes) { 65 | #ifdef KeccakReference 66 | displayBytes(1, "Block to be absorbed", curData, rateInBytes); 67 | #endif 68 | SnP_XORBytes(instance->state, curData, 0, rateInBytes); 69 | SnP_Permute(instance->state); 70 | curData+=rateInBytes; 71 | } 72 | i = dataByteLen - j; 73 | } 74 | } 75 | else { 76 | // normal lane: using the message queue 77 | partialBlock = (unsigned int)(dataByteLen - i); 78 | if (partialBlock+instance->byteIOIndex > rateInBytes) 79 | partialBlock = rateInBytes-instance->byteIOIndex; 80 | #ifdef KeccakReference 81 | displayBytes(1, "Block to be absorbed (part)", curData, partialBlock); 82 | #endif 83 | i += partialBlock; 84 | 85 | SnP_XORBytes(instance->state, curData, instance->byteIOIndex, partialBlock); 86 | curData += partialBlock; 87 | instance->byteIOIndex += partialBlock; 88 | if (instance->byteIOIndex == rateInBytes) { 89 | SnP_Permute(instance->state); 90 | instance->byteIOIndex = 0; 91 | } 92 | } 93 | } 94 | return 0; 95 | } 96 | 97 | /* ---------------------------------------------------------------- */ 98 | 99 | int Keccak_SpongeAbsorbLastFewBits(Keccak_SpongeInstance *instance, unsigned char delimitedData) 100 | { 101 | unsigned char delimitedData1[1]; 102 | unsigned int rateInBytes = instance->rate/8; 103 | 104 | if (delimitedData == 0) 105 | return 1; 106 | if (instance->squeezing) 107 | return 1; // Too late for additional input 108 | 109 | delimitedData1[0] = delimitedData; 110 | #ifdef KeccakReference 111 | displayBytes(1, "Block to be absorbed (last few bits + first bit of padding)", delimitedData1, 1); 112 | #endif 113 | // Last few bits, whose delimiter coincides with first bit of padding 114 | SnP_XORBytes(instance->state, delimitedData1, instance->byteIOIndex, 1); 115 | // If the first bit of padding is at position rate-1, we need a whole new block for the second bit of padding 116 | if ((delimitedData >= 0x80) && (instance->byteIOIndex == (rateInBytes-1))) 117 | SnP_Permute(instance->state); 118 | // Second bit of padding 119 | SnP_ComplementBit(instance->state, rateInBytes*8-1); 120 | #ifdef KeccakReference 121 | { 122 | unsigned char block[SnP_width/8]; 123 | memset(block, 0, SnP_width/8); 124 | block[rateInBytes-1] = 0x80; 125 | displayBytes(1, "Second bit of padding", block, rateInBytes); 126 | } 127 | #endif 128 | SnP_Permute(instance->state); 129 | instance->byteIOIndex = 0; 130 | instance->squeezing = 1; 131 | #ifdef KeccakReference 132 | displayText(1, "--- Switching to squeezing phase ---"); 133 | #endif 134 | return 0; 135 | } 136 | 137 | /* ---------------------------------------------------------------- */ 138 | 139 | int Keccak_SpongeSqueeze(Keccak_SpongeInstance *instance, unsigned char *data, size_t dataByteLen) 140 | { 141 | size_t i, j; 142 | unsigned int partialBlock; 143 | unsigned int rateInBytes = instance->rate/8; 144 | unsigned char *curData; 145 | 146 | if (!instance->squeezing) 147 | Keccak_SpongeAbsorbLastFewBits(instance, 0x01); 148 | 149 | i = 0; 150 | curData = data; 151 | while(i < dataByteLen) { 152 | if ((instance->byteIOIndex == rateInBytes) && (dataByteLen >= (i + rateInBytes))) { 153 | // processing full blocks first 154 | if ((rateInBytes % SnP_laneLengthInBytes) == 0) { 155 | // fast lane: whole lane rate 156 | j = SnP_FBWL_Squeeze(instance->state, rateInBytes/SnP_laneLengthInBytes, curData, dataByteLen - i); 157 | i += j; 158 | curData += j; 159 | } 160 | else { 161 | for(j=dataByteLen-i; j>=rateInBytes; j-=rateInBytes) { 162 | SnP_Permute(instance->state); 163 | SnP_ExtractBytes(instance->state, curData, 0, rateInBytes); 164 | #ifdef KeccakReference 165 | displayBytes(1, "Squeezed block", curData, rateInBytes); 166 | #endif 167 | curData+=rateInBytes; 168 | } 169 | i = dataByteLen - j; 170 | } 171 | } 172 | else { 173 | // normal lane: using the message queue 174 | if (instance->byteIOIndex == rateInBytes) { 175 | SnP_Permute(instance->state); 176 | instance->byteIOIndex = 0; 177 | } 178 | partialBlock = (unsigned int)(dataByteLen - i); 179 | if (partialBlock+instance->byteIOIndex > rateInBytes) 180 | partialBlock = rateInBytes-instance->byteIOIndex; 181 | i += partialBlock; 182 | 183 | SnP_ExtractBytes(instance->state, curData, instance->byteIOIndex, partialBlock); 184 | #ifdef KeccakReference 185 | displayBytes(1, "Squeezed block (part)", curData, partialBlock); 186 | #endif 187 | curData += partialBlock; 188 | instance->byteIOIndex += partialBlock; 189 | } 190 | } 191 | return 0; 192 | } 193 | -------------------------------------------------------------------------------- /KeccakSponge.h: -------------------------------------------------------------------------------- 1 | /* 2 | Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, 3 | Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby 4 | denoted as "the implementer". 5 | 6 | For more information, feedback or questions, please refer to our websites: 7 | http://keccak.noekeon.org/ 8 | http://keyak.noekeon.org/ 9 | http://ketje.noekeon.org/ 10 | 11 | To the extent possible under law, the implementer has waived all copyright 12 | and related or neighboring rights to the source code in this file. 13 | http://creativecommons.org/publicdomain/zero/1.0/ 14 | */ 15 | 16 | #ifndef _KeccakSponge_h_ 17 | #define _KeccakSponge_h_ 18 | 19 | #include "SnP-interface.h" 20 | #include 21 | 22 | // on Mac OS-X and possibly others, ALIGN(x) is defined in param.h, and -Werror chokes on the redef. 23 | #ifdef ALIGN 24 | #undef ALIGN 25 | #endif 26 | 27 | #if defined(__GNUC__) 28 | #define ALIGN __attribute__ ((aligned(32))) 29 | #elif defined(_MSC_VER) 30 | #define ALIGN __declspec(align(32)) 31 | #else 32 | #define ALIGN 33 | #endif 34 | 35 | /** 36 | * Structure that contains the sponge instance attributes for use with the 37 | * Keccak_Sponge* functions. 38 | * It gathers the state processed by the permutation as well as the rate, 39 | * the position of input/output bytes in the state and the phase 40 | * (absorbing or squeezing). 41 | */ 42 | ALIGN typedef struct Keccak_SpongeInstanceStruct { 43 | /** The state processed by the permutation. */ 44 | ALIGN unsigned char state[SnP_stateSizeInBytes]; 45 | /** The value of the rate in bits.*/ 46 | unsigned int rate; 47 | /** The position in the state of the next byte to be input (when absorbing) or output (when squeezing). */ 48 | unsigned int byteIOIndex; 49 | /** If set to 0, in the absorbing phase; otherwise, in the squeezing phase. */ 50 | int squeezing; 51 | } Keccak_SpongeInstance; 52 | 53 | /** 54 | * Function to initialize the state of the Keccak[r, c] sponge function. 55 | * The phase of the sponge function is set to absorbing. 56 | * @param spongeInstance Pointer to the sponge instance to be initialized. 57 | * @param rate The value of the rate r. 58 | * @param capacity The value of the capacity c. 59 | * @pre One must have r+c equal to the supported width of this implementation 60 | * and the rate a multiple of 8 bits (one byte) in this implementation. 61 | * @return Zero if successful, 1 otherwise. 62 | */ 63 | int Keccak_SpongeInitialize(Keccak_SpongeInstance *spongeInstance, unsigned int rate, unsigned int capacity); 64 | 65 | /** 66 | * Function to give input data bytes for the sponge function to absorb. 67 | * @param spongeInstance Pointer to the sponge instance initialized by Keccak_SpongeInitialize(). 68 | * @param data Pointer to the input data. 69 | * @param dataByteLen The number of input bytes provided in the input data. 70 | * @pre The sponge function must be in the absorbing phase, 71 | * i.e., Keccak_SpongeSqueeze() or Keccak_SpongeAbsorbLastFewBits() 72 | * must not have been called before. 73 | * @return Zero if successful, 1 otherwise. 74 | */ 75 | int Keccak_SpongeAbsorb(Keccak_SpongeInstance *spongeInstance, const unsigned char *data, size_t dataByteLen); 76 | 77 | /** 78 | * Function to give input data bits for the sponge function to absorb 79 | * and then to switch to the squeezing phase. 80 | * @param spongeInstance Pointer to the sponge instance initialized by Keccak_SpongeInitialize(). 81 | * @param delimitedData Byte containing from 0 to 7 trailing bits 82 | * that must be absorbed. 83 | * These n bits must be in the least significant bit positions. 84 | * These bits must be delimited with a bit 1 at position n 85 | * (counting from 0=LSB to 7=MSB) and followed by bits 0 86 | * from position n+1 to position 7. 87 | * Some examples: 88 | * - If no bits are to be absorbed, then @a delimitedData must be 0x01. 89 | * - If the 2-bit sequence 0,0 is to be absorbed, @a delimitedData must be 0x04. 90 | * - If the 5-bit sequence 0,1,0,0,1 is to be absorbed, @a delimitedData must be 0x32. 91 | * - If the 7-bit sequence 1,1,0,1,0,0,0 is to be absorbed, @a delimitedData must be 0x8B. 92 | * . 93 | * @pre The sponge function must be in the absorbing phase, 94 | * i.e., Keccak_SpongeSqueeze() or Keccak_SpongeAbsorbLastFewBits() 95 | * must not have been called before. 96 | * @pre @a delimitedData ≠ 0x00 97 | * @return Zero if successful, 1 otherwise. 98 | */ 99 | int Keccak_SpongeAbsorbLastFewBits(Keccak_SpongeInstance *spongeInstance, unsigned char delimitedData); 100 | 101 | /** 102 | * Function to squeeze output data from the sponge function. 103 | * If the sponge function was in the absorbing phase, this function 104 | * switches it to the squeezing phase 105 | * as if Keccak_SpongeAbsorbLastFewBits(spongeInstance, 0x01) was called. 106 | * @param spongeInstance Pointer to the sponge instance initialized by Keccak_SpongeInitialize(). 107 | * @param data Pointer to the buffer where to store the output data. 108 | * @param dataByteLen The number of output bytes desired. 109 | * @return Zero if successful, 1 otherwise. 110 | */ 111 | int Keccak_SpongeSqueeze(Keccak_SpongeInstance *spongeInstance, unsigned char *data, size_t dataByteLen); 112 | 113 | #endif 114 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2012-present strawbrary 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /SnP-FBWL-default.c: -------------------------------------------------------------------------------- 1 | /* 2 | Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, 3 | Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby 4 | denoted as "the implementer". 5 | 6 | For more information, feedback or questions, please refer to our websites: 7 | http://keccak.noekeon.org/ 8 | http://keyak.noekeon.org/ 9 | http://ketje.noekeon.org/ 10 | 11 | To the extent possible under law, the implementer has waived all copyright 12 | and related or neighboring rights to the source code in this file. 13 | http://creativecommons.org/publicdomain/zero/1.0/ 14 | */ 15 | 16 | #include 17 | #include "SnP-interface.h" 18 | #ifdef KeccakReference 19 | #include "displayIntermediateValues.h" 20 | #endif 21 | 22 | size_t SnP_FBWL_Absorb_Default(void *state, unsigned int laneCount, const unsigned char *data, size_t dataByteLen, unsigned char trailingBits) 23 | { 24 | size_t processed = 0; 25 | 26 | while(dataByteLen >= laneCount*SnP_laneLengthInBytes) { 27 | #ifdef KeccakReference 28 | if (trailingBits == 0) 29 | displayBytes(1, "Block to be absorbed", data, laneCount*SnP_laneLengthInBytes); 30 | else { 31 | displayBytes(1, "Block to be absorbed (part)", data, laneCount*SnP_laneLengthInBytes); 32 | displayBytes(1, "Block to be absorbed (trailing bits)", &trailingBits, 1); 33 | } 34 | #endif 35 | SnP_XORBytes(state, data, 0, laneCount*SnP_laneLengthInBytes); 36 | SnP_XORBytes(state, &trailingBits, laneCount*SnP_laneLengthInBytes, 1); 37 | SnP_Permute(state); 38 | data += laneCount*SnP_laneLengthInBytes; 39 | dataByteLen -= laneCount*SnP_laneLengthInBytes; 40 | processed += laneCount*SnP_laneLengthInBytes; 41 | } 42 | return processed; 43 | } 44 | 45 | size_t SnP_FBWL_Squeeze_Default(void *state, unsigned int laneCount, unsigned char *data, size_t dataByteLen) 46 | { 47 | size_t processed = 0; 48 | 49 | while(dataByteLen >= laneCount*SnP_laneLengthInBytes) { 50 | SnP_Permute(state); 51 | SnP_ExtractBytes(state, data, 0, laneCount*SnP_laneLengthInBytes); 52 | #ifdef KeccakReference 53 | displayBytes(1, "Squeezed block", data, laneCount*SnP_laneLengthInBytes); 54 | #endif 55 | data += laneCount*SnP_laneLengthInBytes; 56 | dataByteLen -= laneCount*SnP_laneLengthInBytes; 57 | processed += laneCount*SnP_laneLengthInBytes; 58 | } 59 | return processed; 60 | } 61 | 62 | size_t SnP_FBWL_Wrap_Default(void *state, unsigned int laneCount, const unsigned char *dataIn, unsigned char *dataOut, size_t dataByteLen, unsigned char trailingBits) 63 | { 64 | size_t processed = 0; 65 | 66 | while(dataByteLen >= laneCount*SnP_laneLengthInBytes) { 67 | SnP_XORBytes(state, dataIn, 0, laneCount*SnP_laneLengthInBytes); 68 | SnP_ExtractBytes(state, dataOut, 0, laneCount*SnP_laneLengthInBytes); 69 | SnP_XORBytes(state, &trailingBits, laneCount*SnP_laneLengthInBytes, 1); 70 | SnP_Permute(state); 71 | dataIn += laneCount*SnP_laneLengthInBytes; 72 | dataOut += laneCount*SnP_laneLengthInBytes; 73 | dataByteLen -= laneCount*SnP_laneLengthInBytes; 74 | processed += laneCount*SnP_laneLengthInBytes; 75 | } 76 | return processed; 77 | } 78 | 79 | size_t SnP_FBWL_Unwrap_Default(void *state, unsigned int laneCount, const unsigned char *dataIn, unsigned char *dataOut, size_t dataByteLen, unsigned char trailingBits) 80 | { 81 | size_t processed = 0; 82 | 83 | if (dataIn != dataOut) 84 | memcpy(dataOut, dataIn, dataByteLen); 85 | while(dataByteLen >= laneCount*SnP_laneLengthInBytes) { 86 | SnP_ExtractAndXORBytes(state, dataOut, 0, laneCount*SnP_laneLengthInBytes); 87 | SnP_XORBytes(state, dataOut, 0, laneCount*SnP_laneLengthInBytes); 88 | SnP_XORBytes(state, &trailingBits, laneCount*SnP_laneLengthInBytes, 1); 89 | SnP_Permute(state); 90 | dataIn += laneCount*SnP_laneLengthInBytes; 91 | dataOut += laneCount*SnP_laneLengthInBytes; 92 | dataByteLen -= laneCount*SnP_laneLengthInBytes; 93 | processed += laneCount*SnP_laneLengthInBytes; 94 | } 95 | return processed; 96 | } 97 | -------------------------------------------------------------------------------- /SnP-FBWL-default.h: -------------------------------------------------------------------------------- 1 | /* 2 | Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, 3 | Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby 4 | denoted as "the implementer". 5 | 6 | For more information, feedback or questions, please refer to our websites: 7 | http://keccak.noekeon.org/ 8 | http://keyak.noekeon.org/ 9 | http://ketje.noekeon.org/ 10 | 11 | To the extent possible under law, the implementer has waived all copyright 12 | and related or neighboring rights to the source code in this file. 13 | http://creativecommons.org/publicdomain/zero/1.0/ 14 | */ 15 | 16 | #ifndef _SnP_FBWL_Default_h_ 17 | #define _SnP_FBWL_Default_h_ 18 | 19 | #include 20 | 21 | size_t SnP_FBWL_Absorb_Default(void *state, unsigned int laneCount, const unsigned char *data, size_t dataByteLen, unsigned char trailingBits); 22 | size_t SnP_FBWL_Squeeze_Default(void *state, unsigned int laneCount, unsigned char *data, size_t dataByteLen); 23 | size_t SnP_FBWL_Wrap_Default(void *state, unsigned int laneCount, const unsigned char *dataIn, unsigned char *dataOut, size_t dataByteLen, unsigned char trailingBits); 24 | size_t SnP_FBWL_Unwrap_Default(void *state, unsigned int laneCount, const unsigned char *dataIn, unsigned char *dataOut, size_t dataByteLen, unsigned char trailingBits); 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /SnP-interface.h: -------------------------------------------------------------------------------- 1 | /* 2 | Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, 3 | Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby 4 | denoted as "the implementer". 5 | 6 | For more information, feedback or questions, please refer to our websites: 7 | http://keccak.noekeon.org/ 8 | http://keyak.noekeon.org/ 9 | http://ketje.noekeon.org/ 10 | 11 | To the extent possible under law, the implementer has waived all copyright 12 | and related or neighboring rights to the source code in this file. 13 | http://creativecommons.org/publicdomain/zero/1.0/ 14 | */ 15 | 16 | #ifndef _SnP_Interface_h_ 17 | #define _SnP_Interface_h_ 18 | 19 | #include "KeccakF-1600-interface.h" 20 | #include "SnP-FBWL-default.h" 21 | 22 | #define SnP_width KeccakF_width 23 | #define SnP_stateSizeInBytes KeccakF_stateSizeInBytes 24 | #define SnP_laneLengthInBytes KeccakF_laneInBytes 25 | #define SnP_laneCount 25 26 | 27 | #define SnP_StaticInitialize KeccakF1600_Initialize 28 | #define SnP_Initialize KeccakF1600_StateInitialize 29 | #define SnP_XORBytes KeccakF1600_StateXORBytes 30 | #define SnP_OverwriteBytes KeccakF1600_StateOverwriteBytes 31 | #define SnP_OverwriteWithZeroes KeccakF1600_StateOverwriteWithZeroes 32 | #define SnP_ComplementBit KeccakF1600_StateComplementBit 33 | #define SnP_Permute KeccakF1600_StatePermute 34 | #define SnP_ExtractBytes KeccakF1600_StateExtractBytes 35 | #define SnP_ExtractAndXORBytes KeccakF1600_StateExtractAndXORBytes 36 | 37 | #define SnP_FBWL_Absorb SnP_FBWL_Absorb_Default 38 | #define SnP_FBWL_Squeeze SnP_FBWL_Squeeze_Default 39 | #define SnP_FBWL_Wrap SnP_FBWL_Wrap_Default 40 | #define SnP_FBWL_Unwrap SnP_FBWL_Unwrap_Default 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /brg_endian.h: -------------------------------------------------------------------------------- 1 | /* 2 | --------------------------------------------------------------------------- 3 | Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved. 4 | 5 | LICENSE TERMS 6 | 7 | The redistribution and use of this software (with or without changes) 8 | is allowed without the payment of fees or royalties provided that: 9 | 10 | 1. source code distributions include the above copyright notice, this 11 | list of conditions and the following disclaimer; 12 | 13 | 2. binary distributions include the above copyright notice, this list 14 | of conditions and the following disclaimer in their documentation; 15 | 16 | 3. the name of the copyright holder is not used to endorse products 17 | built using this software without specific written permission. 18 | 19 | DISCLAIMER 20 | 21 | This software is provided 'as is' with no explicit or implied warranties 22 | in respect of its properties, including, but not limited to, correctness 23 | and/or fitness for purpose. 24 | --------------------------------------------------------------------------- 25 | Issue Date: 20/12/2007 26 | Changes for ARM 9/9/2010 27 | */ 28 | 29 | #ifndef _BRG_ENDIAN_H 30 | #define _BRG_ENDIAN_H 31 | 32 | #define IS_BIG_ENDIAN 4321 /* byte 0 is most significant (mc68k) */ 33 | #define IS_LITTLE_ENDIAN 1234 /* byte 0 is least significant (i386) */ 34 | 35 | #if 0 36 | /* Include files where endian defines and byteswap functions may reside */ 37 | #if defined( __sun ) 38 | # include 39 | #elif defined( __FreeBSD__ ) || defined( __OpenBSD__ ) || defined( __NetBSD__ ) 40 | # include 41 | #elif defined( BSD ) && ( BSD >= 199103 ) || defined( __APPLE__ ) || \ 42 | defined( __CYGWIN32__ ) || defined( __DJGPP__ ) || defined( __osf__ ) 43 | # include 44 | #elif defined( __linux__ ) || defined( __GNUC__ ) || defined( __GNU_LIBRARY__ ) 45 | # if !defined( __MINGW32__ ) && !defined( _AIX ) 46 | # include 47 | # if !defined( __BEOS__ ) 48 | # include 49 | # endif 50 | # endif 51 | #endif 52 | #endif 53 | 54 | /* Now attempt to set the define for platform byte order using any */ 55 | /* of the four forms SYMBOL, _SYMBOL, __SYMBOL & __SYMBOL__, which */ 56 | /* seem to encompass most endian symbol definitions */ 57 | 58 | #if defined( BIG_ENDIAN ) && defined( LITTLE_ENDIAN ) 59 | # if defined( BYTE_ORDER ) && BYTE_ORDER == BIG_ENDIAN 60 | # define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN 61 | # elif defined( BYTE_ORDER ) && BYTE_ORDER == LITTLE_ENDIAN 62 | # define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN 63 | # endif 64 | #elif defined( BIG_ENDIAN ) 65 | # define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN 66 | #elif defined( LITTLE_ENDIAN ) 67 | # define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN 68 | #endif 69 | 70 | #if defined( _BIG_ENDIAN ) && defined( _LITTLE_ENDIAN ) 71 | # if defined( _BYTE_ORDER ) && _BYTE_ORDER == _BIG_ENDIAN 72 | # define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN 73 | # elif defined( _BYTE_ORDER ) && _BYTE_ORDER == _LITTLE_ENDIAN 74 | # define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN 75 | # endif 76 | #elif defined( _BIG_ENDIAN ) 77 | # define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN 78 | #elif defined( _LITTLE_ENDIAN ) 79 | # define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN 80 | #endif 81 | 82 | #if defined( __BIG_ENDIAN ) && defined( __LITTLE_ENDIAN ) 83 | # if defined( __BYTE_ORDER ) && __BYTE_ORDER == __BIG_ENDIAN 84 | # define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN 85 | # elif defined( __BYTE_ORDER ) && __BYTE_ORDER == __LITTLE_ENDIAN 86 | # define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN 87 | # endif 88 | #elif defined( __BIG_ENDIAN ) 89 | # define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN 90 | #elif defined( __LITTLE_ENDIAN ) 91 | # define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN 92 | #endif 93 | 94 | #if defined( __BIG_ENDIAN__ ) && defined( __LITTLE_ENDIAN__ ) 95 | # if defined( __BYTE_ORDER__ ) && __BYTE_ORDER__ == __BIG_ENDIAN__ 96 | # define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN 97 | # elif defined( __BYTE_ORDER__ ) && __BYTE_ORDER__ == __LITTLE_ENDIAN__ 98 | # define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN 99 | # endif 100 | #elif defined( __BIG_ENDIAN__ ) 101 | # define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN 102 | #elif defined( __LITTLE_ENDIAN__ ) 103 | # define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN 104 | #endif 105 | 106 | /* if the platform byte order could not be determined, then try to */ 107 | /* set this define using common machine defines */ 108 | #if !defined(PLATFORM_BYTE_ORDER) 109 | 110 | #if defined( __alpha__ ) || defined( __alpha ) || defined( i386 ) || \ 111 | defined( __i386__ ) || defined( _M_I86 ) || defined( _M_IX86 ) || \ 112 | defined( __OS2__ ) || defined( sun386 ) || defined( __TURBOC__ ) || \ 113 | defined( vax ) || defined( vms ) || defined( VMS ) || \ 114 | defined( __VMS ) || defined( _M_X64 ) 115 | # define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN 116 | 117 | #elif defined( AMIGA ) || defined( applec ) || defined( __AS400__ ) || \ 118 | defined( _CRAY ) || defined( __hppa ) || defined( __hp9000 ) || \ 119 | defined( ibm370 ) || defined( mc68000 ) || defined( m68k ) || \ 120 | defined( __MRC__ ) || defined( __MVS__ ) || defined( __MWERKS__ ) || \ 121 | defined( sparc ) || defined( __sparc) || defined( SYMANTEC_C ) || \ 122 | defined( __VOS__ ) || defined( __TIGCC__ ) || defined( __TANDEM ) || \ 123 | defined( THINK_C ) || defined( __VMCMS__ ) || defined( _AIX ) 124 | # define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN 125 | 126 | #elif defined(__arm__) 127 | # ifdef __BIG_ENDIAN 128 | # define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN 129 | # else 130 | # define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN 131 | # endif 132 | #elif 1 /* **** EDIT HERE IF NECESSARY **** */ 133 | # define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN 134 | #elif 0 /* **** EDIT HERE IF NECESSARY **** */ 135 | # define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN 136 | #else 137 | # error Please edit lines 132 or 134 in brg_endian.h to set the platform byte order 138 | #endif 139 | 140 | #endif 141 | 142 | #endif 143 | -------------------------------------------------------------------------------- /config.m4: -------------------------------------------------------------------------------- 1 | PHP_ARG_ENABLE(sha3, 2 | [Whether to enable SHA3 support], 3 | [--enable-sha3 Enable SHA3 support]) 4 | 5 | if test "$PHP_SHA3" != "no"; then 6 | PHP_NEW_EXTENSION(sha3, php_sha3.c KeccakHash.c KeccakSponge.c KeccakF-1600-reference.c SnP-FBWL-default.c displayIntermediateValues.c, $ext_shared) 7 | fi -------------------------------------------------------------------------------- /config.w32: -------------------------------------------------------------------------------- 1 | ARG_ENABLE("enable-sha3", "Enable SHA3 support", "no"); 2 | 3 | if (PHP_SHA3 != "no") { 4 | EXTENSION("sha3", "php_sha3.c"); 5 | ADD_SOURCE("KeccakHash.c"); 6 | ADD_SOURCE("KeccakSponge.c"); 7 | ADD_SOURCE("KeccakF-1600-reference.c"); 8 | ADD_SOURCE("SnP-FBWL-default.c"); 9 | ADD_SOURCE("displayIntermediateValues.c"); 10 | } 11 | 12 | -------------------------------------------------------------------------------- /displayIntermediateValues.c: -------------------------------------------------------------------------------- 1 | /* 2 | Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, 3 | Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby 4 | denoted as "the implementer". 5 | 6 | For more information, feedback or questions, please refer to our websites: 7 | http://keccak.noekeon.org/ 8 | http://keyak.noekeon.org/ 9 | http://ketje.noekeon.org/ 10 | 11 | To the extent possible under law, the implementer has waived all copyright 12 | and related or neighboring rights to the source code in this file. 13 | http://creativecommons.org/publicdomain/zero/1.0/ 14 | */ 15 | 16 | #include 17 | #include "displayIntermediateValues.h" 18 | #include "SnP-interface.h" 19 | 20 | FILE *intermediateValueFile = 0; 21 | int displayLevel = 0; 22 | 23 | void displaySetIntermediateValueFile(FILE *f) 24 | { 25 | intermediateValueFile = f; 26 | } 27 | 28 | void displaySetLevel(int level) 29 | { 30 | displayLevel = level; 31 | } 32 | 33 | void displayBytes(int level, const char *text, const unsigned char *bytes, unsigned int size) 34 | { 35 | unsigned int i; 36 | 37 | if ((intermediateValueFile) && (level <= displayLevel)) { 38 | fprintf(intermediateValueFile, "%s:\n", text); 39 | for(i=0; i> iBit) & 0x01) != 0); 59 | } 60 | fprintf(intermediateValueFile, "\n"); 61 | fprintf(intermediateValueFile, "\n"); 62 | } 63 | } 64 | 65 | void displayStateAsBytes(int level, const char *text, const unsigned char *state) 66 | { 67 | displayBytes(level, text, state, SnP_width/8); 68 | } 69 | 70 | #if (SnP_laneLengthInBytes == 8) 71 | void displayStateAs32bitWords(int level, const char *text, const unsigned int *state) 72 | { 73 | unsigned int i; 74 | 75 | if ((intermediateValueFile) && (level <= displayLevel)) { 76 | fprintf(intermediateValueFile, "%s:\n", text); 77 | for(i=0; i> 32)); 109 | fprintf(intermediateValueFile, "%08X", (unsigned int)(state[i] & 0xFFFFFFFFULL)); 110 | if ((i%5) == 4) 111 | fprintf(intermediateValueFile, "\n"); 112 | else 113 | fprintf(intermediateValueFile, " "); 114 | } 115 | #endif 116 | #if (SnP_laneLengthInBytes == 4) 117 | for(i=0; i<25; i++) { 118 | fprintf(intermediateValueFile, "%08X", state[i]); 119 | if ((i%5) == 4) 120 | fprintf(intermediateValueFile, "\n"); 121 | else 122 | fprintf(intermediateValueFile, " "); 123 | } 124 | #endif 125 | #if (SnP_laneLengthInBytes == 2) 126 | for(i=0; i<25; i++) { 127 | fprintf(intermediateValueFile, "%04X ", state[i]); 128 | if ((i%5) == 4) 129 | fprintf(intermediateValueFile, "\n"); 130 | } 131 | #endif 132 | #if (SnP_laneLengthInBytes == 1) 133 | for(i=0; i<25; i++) { 134 | fprintf(intermediateValueFile, "%02X ", state[i]); 135 | if ((i%5) == 4) 136 | fprintf(intermediateValueFile, "\n"); 137 | } 138 | #endif 139 | } 140 | } 141 | 142 | void displayRoundNumber(int level, unsigned int i) 143 | { 144 | if ((intermediateValueFile) && (level <= displayLevel)) { 145 | fprintf(intermediateValueFile, "\n"); 146 | fprintf(intermediateValueFile, "--- Round %d ---\n", i); 147 | fprintf(intermediateValueFile, "\n"); 148 | } 149 | } 150 | 151 | void displayText(int level, const char *text) 152 | { 153 | if ((intermediateValueFile) && (level <= displayLevel)) { 154 | fprintf(intermediateValueFile, "%s", text); 155 | fprintf(intermediateValueFile, "\n"); 156 | fprintf(intermediateValueFile, "\n"); 157 | } 158 | } 159 | -------------------------------------------------------------------------------- /displayIntermediateValues.h: -------------------------------------------------------------------------------- 1 | /* 2 | Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, 3 | Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby 4 | denoted as "the implementer". 5 | 6 | For more information, feedback or questions, please refer to our websites: 7 | http://keccak.noekeon.org/ 8 | http://keyak.noekeon.org/ 9 | http://ketje.noekeon.org/ 10 | 11 | To the extent possible under law, the implementer has waived all copyright 12 | and related or neighboring rights to the source code in this file. 13 | http://creativecommons.org/publicdomain/zero/1.0/ 14 | */ 15 | 16 | #ifndef _displayIntermediateValues_h_ 17 | #define _displayIntermediateValues_h_ 18 | 19 | #include 20 | #include "SnP-interface.h" 21 | 22 | void displaySetIntermediateValueFile(FILE *f); 23 | void displaySetLevel(int level); 24 | void displayBytes(int level, const char *text, const unsigned char *bytes, unsigned int size); 25 | void displayBits(int level, const char *text, const unsigned char *data, unsigned int size, int MSBfirst); 26 | void displayStateAsBytes(int level, const char *text, const unsigned char *state); 27 | #if (SnP_laneLengthInBytes == 8) 28 | void displayStateAs32bitWords(int level, const char *text, const unsigned int *state); 29 | #endif 30 | void displayStateAsLanes(int level, const char *text, void *statePointer); 31 | void displayRoundNumber(int level, unsigned int i); 32 | void displayText(int level, const char *text); 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /php_sha3.c: -------------------------------------------------------------------------------- 1 | #ifdef HAVE_CONFIG_H 2 | #include "config.h" 3 | #endif 4 | 5 | #include "php.h" 6 | #include "ext/standard/info.h" 7 | #include "ext/hash/php_hash.h" 8 | #include "KeccakHash.h" 9 | #include "php_sha3.h" 10 | 11 | #define PHP_SHA3_NAME "sha3" 12 | #define PHP_SHA3_VERSION "0.2.0" 13 | #define PHP_SHA3_STANDARD_VERSION "FIPS 202" 14 | 15 | zend_function_entry sha3_functions[] = { 16 | PHP_FE(sha3, NULL) 17 | PHP_FE_END 18 | }; 19 | 20 | PHP_MINFO_FUNCTION(sha3) 21 | { 22 | php_info_print_table_start(); 23 | php_info_print_table_row(2, "sha3 support", "enabled"); 24 | php_info_print_table_row(2, "extension version", PHP_SHA3_VERSION); 25 | php_info_print_table_row(2, "standard version", PHP_SHA3_STANDARD_VERSION); 26 | php_info_print_table_end(); 27 | } 28 | 29 | zend_module_entry sha3_module_entry = { 30 | #if ZEND_MODULE_API_NO >= 20010901 31 | STANDARD_MODULE_HEADER, 32 | #endif 33 | PHP_SHA3_NAME, 34 | sha3_functions, 35 | NULL, 36 | NULL, 37 | NULL, 38 | NULL, 39 | PHP_MINFO(sha3), 40 | #if ZEND_MODULE_API_NO >= 20010901 41 | PHP_SHA3_VERSION, 42 | #endif 43 | STANDARD_MODULE_PROPERTIES 44 | }; 45 | 46 | #ifdef COMPILE_DL_SHA3 47 | ZEND_GET_MODULE(sha3) 48 | #endif 49 | 50 | PHP_FUNCTION(sha3) 51 | { 52 | #if ZEND_MODULE_API_NO >= 20151012 53 | zend_long hashBitLength = 512; 54 | zend_long hashByteLength; 55 | size_t dataByteLength; 56 | #else 57 | long hashBitLength = 512; 58 | long hashByteLength; 59 | int dataByteLength; 60 | #endif 61 | char *data; 62 | zend_bool rawOutput = 0; 63 | 64 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lb", &data, &dataByteLength, &hashBitLength, &rawOutput) == FAILURE) { 65 | return; 66 | } 67 | 68 | unsigned int capacity = hashBitLength * 2; 69 | unsigned int rate = SnP_width - capacity; 70 | 71 | hashByteLength = hashBitLength / 8; 72 | BitSequence hashVal[hashByteLength]; 73 | 74 | Keccak_HashInstance hashInstance; 75 | HashReturn ret = Keccak_HashInitialize(&hashInstance, rate, capacity, hashBitLength, 0x06); 76 | 77 | if (ret != SHA3_SUCCESS) { 78 | zend_error(E_WARNING, "Unsupported sha3() output length"); 79 | RETURN_FALSE; 80 | } 81 | 82 | Keccak_HashUpdate(&hashInstance, (unsigned char *) data, dataByteLength * 8); 83 | Keccak_HashFinal(&hashInstance, hashVal); 84 | 85 | if (rawOutput) { 86 | #if ZEND_MODULE_API_NO >= 20151012 87 | RETVAL_STRINGL((char *)hashVal, hashByteLength); 88 | #else 89 | RETURN_STRINGL((char *)hashVal, hashByteLength, 1); 90 | #endif 91 | } else { 92 | char *hexDigest = safe_emalloc(hashByteLength, 2, 1); 93 | 94 | php_hash_bin2hex(hexDigest, hashVal, hashByteLength); 95 | hexDigest[2 * hashByteLength] = 0; 96 | #if ZEND_MODULE_API_NO >= 20151012 97 | RETVAL_STRINGL(hexDigest, hashByteLength * 2); 98 | #else 99 | RETURN_STRINGL(hexDigest, hashByteLength * 2, 1); 100 | #endif 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /php_sha3.h: -------------------------------------------------------------------------------- 1 | #ifndef PHP_SHA3_H 2 | #define PHP_SHA3_H 3 | 4 | PHP_FUNCTION(sha3); 5 | 6 | extern zend_module_entry sha3_module_entry; 7 | #define phpext_sha3_ptr &sha3_module_entry 8 | 9 | #endif 10 | 11 | /* https://github.com/strawbrary/php-sha3 */ -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | PHP SHA-3 (Keccak) Extension 2 | ============================ 3 | 4 | [![Build Status](https://travis-ci.org/strawbrary/php-sha3.svg?branch=master)](https://travis-ci.org/strawbrary/php-sha3) 5 | 6 | This PHP extension is a wrapper for the reference implementation of the SHA-3 (Keccak) hash function. SHA-3 is intended to replace older general use hash functions such as SHA-2 and MD5. The algorithm was designed by Guido Bertoni, Joan Daemen, Michaël Peeters and Gilles Van Assche. 7 | 8 | This extension uses the final FIPS 202 standard published on August 5, 2015. 9 | 10 | Installation 11 | ------------ 12 | 1. git clone https://github.com/strawbrary/php-sha3 13 | 1. cd php-sha3 14 | 1. phpize 15 | 1. ./configure --enable-sha3 16 | 1. make && make install 17 | 1. Add the following line to your php.ini file 18 | 19 | ``` 20 | extension=sha3.so 21 | ``` 22 | 23 | You may need to restart your httpd/FPM to load the extension. You can verify it is loaded by looking for sha3 in your phpinfo. 24 | 25 | Usage 26 | ---- 27 | ```php 28 | string sha3 ( string $str [, int $outputSize = 512, bool $rawOutput = false ] ) 29 | ``` 30 | 31 | * $str: The string to hash 32 | * $outputSize: The bit length of the output hash 33 | * $rawOutput: If set to true, then the hash is returned in raw binary format 34 | 35 | * Return value: A hex string containing the sha3 hash of the input string 36 | 37 | Examples 38 | -------- 39 | ```php 40 | echo sha3(''); 41 | ``` 42 | 43 | a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26 44 | 45 | ```php 46 | echo sha3('', 256); 47 | ``` 48 | 49 | a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a 50 | 51 | ```php 52 | echo sha3('foobar', 384); 53 | ``` 54 | 55 | 0fa8abfbdaf924ad307b74dd2ed183b9a4a398891a2f6bac8fd2db7041b77f068580f9c6c66f699b496c2da1cbcc7ed8 56 | 57 | 58 | License 59 | -------- 60 | [MIT](LICENSE) 61 | -------------------------------------------------------------------------------- /tests/sha3_224.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Verify sha3 224 bit output 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | 10 | --EXPECT-- 11 | 6b4e03423667dbb73b6e15454f0eb1abd4597f9a1b078e3f5b5a6bc7 12 | e642824c3f8cf24ad09234ee7d3c766fc9a3a5168d0c94ad73b46fdf 13 | d15dadceaa4d5d7bb3b48f446421d542e08ad8887305e28d58335795 14 | a67c289b8250a6f437a20137985d605589a8c163d45261b15419556e -------------------------------------------------------------------------------- /tests/sha3_256.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Verify sha3 256 bit output 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | 10 | --EXPECT-- 11 | a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a 12 | 3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532 13 | 69070dda01975c8c120c3aada1b282394e7f032fa9cf32f4cb2259a0897dfc04 14 | a79d6a9da47f04a3b9a9323ec9991f2105d4c78a7bc7beeb103855a7a11dfb9f -------------------------------------------------------------------------------- /tests/sha3_384.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Verify sha3 384 bit output 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | 10 | --EXPECT-- 11 | 0c63a75b845e4f7d01107d852e4c2485c51a50aaaa94fc61995e71bbee983a2ac3713831264adb47fb6bd1e058d5f004 12 | ec01498288516fc926459f58e2c6ad8df9b473cb0fc08c2596da7cf0e49be4b298d88cea927ac7f539f1edf228376d25 13 | 7063465e08a93bce31cd89d2e3ca8f602498696e253592ed26f07bf7e703cf328581e1471a7ba7ab119b1a9ebdf8be41 14 | d5b972302f5080d0830e0de7b6b2cf383665a008f4c4f386a61112652c742d20cb45aa51bd4f542fc733e2719e999291 -------------------------------------------------------------------------------- /tests/sha3_512.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Verify sha3 512 bit output 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | 12 | --EXPECT-- 13 | a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26 14 | b751850b1a57168a5693cd924b6b096e08f621827444f70d884f5d0240d2712e10e116e9192af3c91a7ec57647e3934057340b4cf408d5a56592f8274eec53f0 15 | 01dedd5de4ef14642445ba5f5b97c15e47b9ad931326e4b0727cd94cefc44fff23f07bf543139939b49128caf436dc1bdee54fcb24023a08d9403f9b4bf0d450 16 | d1db17b4745b255e5eb159f66593cc9c143850979fc7a3951796aba80165aab536b46174ce19e3f707f0e5c6487f5f03084bc0ec9461691ef20113e42ad28163 17 | 18 | a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26 19 | b751850b1a57168a5693cd924b6b096e08f621827444f70d884f5d0240d2712e10e116e9192af3c91a7ec57647e3934057340b4cf408d5a56592f8274eec53f0 20 | 01dedd5de4ef14642445ba5f5b97c15e47b9ad931326e4b0727cd94cefc44fff23f07bf543139939b49128caf436dc1bdee54fcb24023a08d9403f9b4bf0d450 21 | d1db17b4745b255e5eb159f66593cc9c143850979fc7a3951796aba80165aab536b46174ce19e3f707f0e5c6487f5f03084bc0ec9461691ef20113e42ad28163 -------------------------------------------------------------------------------- /tests/test_helper.php: -------------------------------------------------------------------------------- 1 |