| 1 | /* | 
| 2 | The Keccak sponge function, designed by Guido Bertoni, Joan Daemen, | 
| 3 | Michaƫl Peeters and Gilles Van Assche. For more information, feedback or | 
| 4 | questions, please refer to our website: http://keccak.noekeon.org/ | 
| 5 |  | 
| 6 | Implementation by the designers, | 
| 7 | hereby denoted as "the implementer". | 
| 8 |  | 
| 9 | To the extent possible under law, the implementer has waived all copyright | 
| 10 | and related or neighboring rights to the source code in this file. | 
| 11 | http://creativecommons.org/publicdomain/zero/1.0/ | 
| 12 | */ | 
| 13 |  | 
| 14 | #include <string.h> | 
| 15 | //#include "KeccakNISTInterface.h" | 
| 16 | #include "KeccakF-1600-interface.h" | 
| 17 |  | 
| 18 | static HashReturn Init(hashState *state, int hashbitlen) | 
| 19 | { | 
| 20 |     switch(hashbitlen) { | 
| 21 |         case 0: // Default parameters, arbitrary length output | 
| 22 |             InitSponge(state: (spongeState*)state, rate: 1024, capacity: 576); | 
| 23 |             break; | 
| 24 |         case 224: | 
| 25 |             InitSponge(state: (spongeState*)state, rate: 1152, capacity: 448); | 
| 26 |             break; | 
| 27 |         case 256: | 
| 28 |             InitSponge(state: (spongeState*)state, rate: 1088, capacity: 512); | 
| 29 |             break; | 
| 30 |         case 384: | 
| 31 |             InitSponge(state: (spongeState*)state, rate: 832, capacity: 768); | 
| 32 |             break; | 
| 33 |         case 512: | 
| 34 |             InitSponge(state: (spongeState*)state, rate: 576, capacity: 1024); | 
| 35 |             break; | 
| 36 |         default: | 
| 37 |             return BAD_HASHLEN; | 
| 38 |     } | 
| 39 |     state->fixedOutputLength = hashbitlen; | 
| 40 |     return SUCCESS; | 
| 41 | } | 
| 42 |  | 
| 43 | static HashReturn Update(hashState *state, const BitSequence *data, DataLength databitlen) | 
| 44 | { | 
| 45 |     if ((databitlen % 8) == 0) | 
| 46 |         return (HashReturn) Absorb(state: (spongeState*)state, data, databitlen); | 
| 47 |     else { | 
| 48 |         HashReturn ret = (HashReturn) Absorb(state: (spongeState*)state, data, databitlen: databitlen - (databitlen % 8)); | 
| 49 |         if (ret == SUCCESS) { | 
| 50 |             unsigned char lastByte;  | 
| 51 |             // Align the last partial byte to the least significant bits | 
| 52 |             lastByte = data[databitlen/8] >> (8 - (databitlen % 8)); | 
| 53 |             return (HashReturn) Absorb(state: (spongeState*)state, data: &lastByte, databitlen: databitlen % 8); | 
| 54 |         } | 
| 55 |         else | 
| 56 |             return ret; | 
| 57 |     } | 
| 58 | } | 
| 59 |  | 
| 60 | static HashReturn Final(hashState *state, BitSequence *hashval) | 
| 61 | { | 
| 62 |     return (HashReturn) Squeeze(state, output: hashval, outputLength: state->fixedOutputLength); | 
| 63 | } | 
| 64 |  | 
| 65 | #ifndef QT_BUILDING_QT | 
| 66 | static HashReturn Hash(int hashbitlen, const BitSequence *data, DataLength databitlen, BitSequence *hashval) | 
| 67 | { | 
| 68 |     hashState state; | 
| 69 |     HashReturn result; | 
| 70 |  | 
| 71 |     if ((hashbitlen != 224) && (hashbitlen != 256) && (hashbitlen != 384) && (hashbitlen != 512)) | 
| 72 |         return BAD_HASHLEN; // Only the four fixed output lengths available through this API | 
| 73 |     result = Init(&state, hashbitlen); | 
| 74 |     if (result != SUCCESS) | 
| 75 |         return result; | 
| 76 |     result = Update(&state, data, databitlen); | 
| 77 |     if (result != SUCCESS) | 
| 78 |         return result; | 
| 79 |     result = Final(&state, hashval); | 
| 80 |     return result; | 
| 81 | } | 
| 82 | #endif | 
| 83 |  |