-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathKeccakNISTInterface.c
96 lines (74 loc) · 2.28 KB
/
KeccakNISTInterface.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
/*
* Copyright 2016 Nathaniel Graff
*/
#include <stdint.h>
#include <string.h>
#include "KeccakNISTInterface.h"
#include "KeccakSponge.h"
HashReturn Init(HashState * state, uint32_t hashBitLen)
{
HashReturn returnVal;
switch(hashBitLen) {
case 0: // Default parameters, arbitrary length output
returnVal = InitSponge(state, 1024, 576);
break;
case 224:
returnVal = InitSponge(state, 1152, 448);
break;
case 256:
returnVal = InitSponge(state, 1088, 512);
break;
case 384:
returnVal = InitSponge(state, 832, 768);
break;
case 512:
returnVal = InitSponge(state, 576, 1024);
break;
default:
returnVal = BAD_HASHLEN;
}
state->fixedOutputLength = hashBitLen;
return returnVal;
}
HashReturn Update(HashState * state, const BitSequence * data, DataLength dataBitLen)
{
if ((dataBitLen % 8) == 0) {
return Absorb(state, data, dataBitLen);
}
else {
HashReturn returnVal = Absorb(state, data, dataBitLen - (dataBitLen % 8));
if (returnVal == SUCCESS) {
// Align the last partial byte to the least significant bits
uint8_t lastByte = data[dataBitLen / 8] >> (8 - (dataBitLen % 8));
returnVal = Absorb(state, &lastByte, dataBitLen % 8);
memset(&lastByte, 0, sizeof(lastByte)); // Clear memory of secret data
return returnVal;
}
else {
return returnVal;
}
}
}
HashReturn Final(HashState * state, BitSequence * hashVal)
{
return Squeeze(state, hashVal, state->fixedOutputLength);
}
HashReturn Hash(uint32_t hashBitLen, const BitSequence * data, DataLength databitlen, BitSequence * hashVal)
{
HashState state;
HashReturn returnVal;
if (hashBitLen == 0) {
return BAD_HASHLEN; // Only the four fixed output lengths available through this API
}
returnVal = Init(&state, hashBitLen);
if (returnVal != SUCCESS) {
return returnVal;
}
returnVal = Update(&state, data, databitlen);
if (returnVal != SUCCESS) {
return returnVal;
}
returnVal = Final(&state, hashVal);
EraseState(&state);
return returnVal;
}