Home | History | Annotate | Download | only in kcp
      1 /*
      2 Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni,
      3 Joan Daemen, Michal 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 <string.h>
     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 FAIL;
     27     result = (HashReturn)KeccakWidth1600_SpongeInitialize(&instance->sponge, rate, capacity);
     28     if (result != SUCCESS)
     29         return result;
     30     instance->fixedOutputLength = hashbitlen;
     31     instance->delimitedSuffix = delimitedSuffix;
     32     return 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)KeccakWidth1600_SpongeAbsorb(&instance->sponge, data, databitlen/8);
     41     else {
     42         HashReturn ret = (HashReturn)KeccakWidth1600_SpongeAbsorb(&instance->sponge, data, databitlen/8);
     43         if (ret == SUCCESS) {
     44             /* The last partial byte is assumed to be aligned on the least significant bits */
     45 
     46             unsigned char lastByte = data[databitlen/8];
     47             /* Concatenate the last few bits provided here with those of the suffix */
     48 
     49             unsigned short delimitedLastBytes = (unsigned short)((unsigned short)lastByte | ((unsigned short)instance->delimitedSuffix << (databitlen % 8)));
     50             if ((delimitedLastBytes & 0xFF00) == 0x0000) {
     51                 instance->delimitedSuffix = delimitedLastBytes & 0xFF;
     52             }
     53             else {
     54                 unsigned char oneByte[1];
     55                 oneByte[0] = delimitedLastBytes & 0xFF;
     56                 ret = (HashReturn)KeccakWidth1600_SpongeAbsorb(&instance->sponge, oneByte, 1);
     57                 instance->delimitedSuffix = (delimitedLastBytes >> 8) & 0xFF;
     58             }
     59         }
     60         return ret;
     61     }
     62 }
     63 
     64 /* ---------------------------------------------------------------- */
     65 
     66 HashReturn Keccak_HashFinal(Keccak_HashInstance *instance, BitSequence *hashval)
     67 {
     68     HashReturn ret = (HashReturn)KeccakWidth1600_SpongeAbsorbLastFewBits(&instance->sponge, instance->delimitedSuffix);
     69     if (ret == SUCCESS)
     70         return (HashReturn)KeccakWidth1600_SpongeSqueeze(&instance->sponge, hashval, instance->fixedOutputLength/8);
     71     else
     72         return ret;
     73 }
     74 
     75 /* ---------------------------------------------------------------- */
     76 
     77 HashReturn Keccak_HashSqueeze(Keccak_HashInstance *instance, BitSequence *data, DataLength databitlen)
     78 {
     79     if ((databitlen % 8) != 0)
     80         return FAIL;
     81     return (HashReturn)KeccakWidth1600_SpongeSqueeze(&instance->sponge, data, databitlen/8);
     82 }
     83