⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 keccaksponge.c

📁 Keccak hash加密算法
💻 C
字号:
/*Algorithm Name: KeccakAuthors: Guido Bertoni, Joan Daemen, Michaël Peeters and Gilles Van AsscheDate: January 9, 2009This code, originally by Guido Bertoni, Joan Daemen, Michaël Peeters andGilles Van Assche as a part of the SHA-3 submission, is hereby put in thepublic domain. It is given as is, without any guarantee.For more information, feedback or questions, please refer to our website:http://keccak.noekeon.org/*/#include <string.h>#include "KeccakNISTInterface.h"#include "KeccakPermutationInterface.h"#ifdef KeccakReference#include "displayIntermediateValues.h"#endifHashReturn Init(hashState *state, int hashbitlen){    KeccakInitialize();    switch(hashbitlen) {        case 0: // Arbitrary length output            state->capacity = 576;            break;        case 224:            state->capacity = 576;            break;        case 256:            state->capacity = 576;            break;        case 384:            state->capacity = 1088;            break;        case 512:            state->capacity = 1088;            break;        default:            return BAD_HASHLEN;    }    state->rate = KeccakPermutationSize - state->capacity;    state->diversifier = hashbitlen/8;    state->hashbitlen = hashbitlen;    KeccakInitializeState(state->state);    memset(state->dataQueue, 0, KeccakMaximumRateInBytes);    state->bitsInQueue = 0;    state->squeezing = 0;    state->bitsAvailableForSqueezing = 0;    return SUCCESS;}void AbsorbQueue(hashState *state){    #ifdef KeccakReference    displayBytes(1, "Data to be absorbed", state->dataQueue, state->bitsInQueue/8);    #endif    // state->bitsInQueue is assumed to be equal a multiple of 8    memset(state->dataQueue+state->bitsInQueue/8, 0, state->rate/8-state->bitsInQueue/8);    if (state->rate == 1024)        KeccakAbsorb1024bits(state->state, state->dataQueue);    else        KeccakAbsorb512bits(state->state, state->dataQueue);    state->bitsInQueue = 0;}HashReturn Update(hashState *state, const BitSequence *data, DataLength databitlen){    DataLength i, j;    DataLength partialBlock, partialByte, wholeBlocks;    BitSequence lastByte;    const BitSequence *curData;    if ((state->bitsInQueue % 8) != 0)        return FAIL; // Only the last call may contain a partial byte    if (state->squeezing)        return FAIL; // Too late for additional input    i = 0;    while(i < databitlen) {        if ((state->bitsInQueue == 0) && (databitlen >= state->rate) && (i <= (databitlen-state->rate))) {            wholeBlocks = (databitlen-i)/state->rate;            curData = data+i/8;            if (state->rate == 1024) {                for(j=0; j<wholeBlocks; j++, curData+=1024/8) {                    #ifdef KeccakReference                    displayBytes(1, "Data to be absorbed", curData, state->rate/8);                    #endif                    KeccakAbsorb1024bits(state->state, curData);                }            }            else {                for(j=0; j<wholeBlocks; j++, curData+=512/8) {                    #ifdef KeccakReference                    displayBytes(1, "Data to be absorbed", curData, state->rate/8);                    #endif                    KeccakAbsorb512bits(state->state, curData);                }            }            i += wholeBlocks*state->rate;        }        else {            partialBlock = databitlen - i;            if (partialBlock+state->bitsInQueue > state->rate)                partialBlock = state->rate-state->bitsInQueue;            partialByte = partialBlock % 8;            partialBlock -= partialByte;            memcpy(state->dataQueue+state->bitsInQueue/8, data+i/8, partialBlock/8);            state->bitsInQueue += partialBlock;            i += partialBlock;            if (state->bitsInQueue == state->rate)                AbsorbQueue(state);            if (partialByte > 0) {                // Align the last partial byte to the least significant bits                lastByte = data[i/8] >> (8-partialByte);                state->dataQueue[state->bitsInQueue/8] = lastByte;                state->bitsInQueue += partialByte;                i += partialByte;            }        }    }    return SUCCESS;}void PadAndSwitchToSqueezingPhase(hashState *state){    if ((state->bitsInQueue % 8) != 0) {        // The bits are numbered from 0=LSB to 7=MSB        unsigned char padByte = 1 << (state->bitsInQueue % 8);        state->dataQueue[state->bitsInQueue/8] |= padByte;        state->bitsInQueue += 8-(state->bitsInQueue % 8);    }    else {        state->dataQueue[state->bitsInQueue/8] = 0x01;        state->bitsInQueue += 8;    }    if (state->bitsInQueue == state->rate)        AbsorbQueue(state);    state->dataQueue[state->bitsInQueue/8] = state->diversifier;    state->bitsInQueue += 8;    if (state->bitsInQueue == state->rate)        AbsorbQueue(state);    state->dataQueue[state->bitsInQueue/8] = state->rate/8;    state->bitsInQueue += 8;    if (state->bitsInQueue == state->rate)        AbsorbQueue(state);    state->dataQueue[state->bitsInQueue/8] = 0x01;    state->bitsInQueue += 8;    if (state->bitsInQueue > 0)        AbsorbQueue(state);    if ((state->rate == 1024) && ((state->hashbitlen > 512) || (state->hashbitlen == 0))) {        KeccakExtract1024bits(state->state, state->dataQueue);        state->bitsAvailableForSqueezing = 1024;    }    else {        KeccakExtract512bits(state->state, state->dataQueue);        state->bitsAvailableForSqueezing = 512;    }    state->squeezing = 1;}HashReturn Final(hashState *state, BitSequence *hashval){    if (state->squeezing)        return FAIL; // Too late, we are already squeezing    PadAndSwitchToSqueezingPhase(state);    if (state->hashbitlen > 0)        memcpy(hashval, state->dataQueue, state->hashbitlen/8);    return SUCCESS;}HashReturn Squeeze(hashState *state, BitSequence *output, DataLength outputLength){    DataLength i;    DataLength partialBlock;    if (!state->squeezing)        return FAIL; // Too early, we are still absorbing    if (state->hashbitlen != 0)        return FAIL; // Arbitrary length output is not permitted in this case    if ((outputLength % 8) != 0)        return FAIL; // Only multiple of 8 bits are allowed, truncation can be done at user level    i = 0;    while(i < outputLength) {        if (state->bitsAvailableForSqueezing == 0) {            KeccakPermutation(state->state);            if (state->rate == 1024) {                KeccakExtract1024bits(state->state, state->dataQueue);                state->bitsAvailableForSqueezing = state->rate;            }            else                return FAIL; // Inconsistent rate        }        partialBlock = outputLength - i;        if (partialBlock > state->bitsAvailableForSqueezing)            partialBlock = state->bitsAvailableForSqueezing;        memcpy(output+i/8, state->dataQueue+(state->rate-state->bitsAvailableForSqueezing)/8, partialBlock/8);        state->bitsAvailableForSqueezing -= partialBlock;        i += partialBlock;    }    return SUCCESS;}HashReturn Hash(int hashbitlen, const BitSequence *data, DataLength databitlen, BitSequence *hashval){    hashState state;    HashReturn result;    if (hashbitlen == 0)        return BAD_HASHLEN; // Arbitrary length output not available through this API    result = Init(&state, hashbitlen);    if (result != SUCCESS)        return result;    result = Update(&state, data, databitlen);    if (result != SUCCESS)        return result;    result = Final(&state, hashval);    return result;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -