-
Notifications
You must be signed in to change notification settings - Fork 42
/
Copy pathKeccak-compact-versal.cpp
executable file
·116 lines (98 loc) · 3.68 KB
/
Keccak-compact-versal.cpp
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
/*
The Keccak sponge function, designed by Guido Bertoni, Joan Daemen,
Michaël Peeters and Gilles Van Assche. For more information, feedback or
questions, please refer to our website: http://keccak.noekeon.org/
Implementation by Ronny Van Keer,
hereby denoted as "the implementer".
To the extent possible under law, the implementer has waived all copyright
and related or neighboring rights to the source code in this file.
http://creativecommons.org/publicdomain/zero/1.0/
*/
#include <string.h>
#include "Keccak-compact-settings.h"
#include "Keccak-compact-versal.h"
#define cKeccakR_SizeInBytes (cKeccakR / 8)
//#include "crypto_hash.h"
#ifndef crypto_hash_BYTES
#ifdef cKeccakFixedOutputLengthInBytes
#define crypto_hash_BYTES cKeccakFixedOutputLengthInBytes
#else
#define crypto_hash_BYTES cKeccakR_SizeInBytes
#endif
#endif
#if (crypto_hash_BYTES > cKeccakR_SizeInBytes)
#error "Full squeezing not yet implemented"
#endif
#define IS_BIG_ENDIAN 4321 /* byte 0 is most significant (mc68k) */
#define IS_LITTLE_ENDIAN 1234 /* byte 0 is least significant (i386) */
#define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN /* WARNING: This implementation works on little-endian platform. Support for big-endinanness is implemented, but not tested. */
#if (cKeccakB == 1600)
typedef unsigned long long UINT64;
typedef UINT64 tKeccakLane;
#define cKeccakNumberOfRounds 24
#elif (cKeccakB == 800)
typedef unsigned int UINT32;
// WARNING: on 8-bit and 16-bit platforms, this should be replaced by:
//typedef unsigned long UINT32;
typedef UINT32 tKeccakLane;
#define cKeccakNumberOfRounds 22
#elif (cKeccakB == 400)
typedef unsigned short UINT16;
typedef UINT16 tKeccakLane;
#define cKeccakNumberOfRounds 20
#elif (cKeccakB == 200)
typedef unsigned char UINT8;
typedef UINT8 tKeccakLane;
#define cKeccakNumberOfRounds 18
#else
#error "Unsupported Keccak-f width"
#endif
typedef unsigned int tSmallUInt; /*INFO It could be more optimized to use "unsigned char" on an 8-bit CPU */
#define cKeccakLaneSizeInBits (sizeof(tKeccakLane) * 8)
#define ROL(a, offset) (tKeccakLane)((((tKeccakLane)a) << ((offset) % cKeccakLaneSizeInBits)) ^ (((tKeccakLane)a) >> (cKeccakLaneSizeInBits-((offset) % cKeccakLaneSizeInBits))))
void KeccakF(tKeccakLane * state, const tKeccakLane *in, int laneCount);
int Versalcrypto_hash(unsigned char *out, const unsigned char *in, unsigned long long inlen, bool padding)
{
tKeccakLane state[5 * 5];
#if (crypto_hash_BYTES >= cKeccakR_SizeInBytes)
#define temp out
#else
unsigned char temp[cKeccakR_SizeInBytes];
#endif
memset(state, 0, sizeof(state));
for ( /* empty */; inlen >= cKeccakR_SizeInBytes; inlen -= cKeccakR_SizeInBytes, in += cKeccakR_SizeInBytes)
{
KeccakF(state, (const tKeccakLane*)in, cKeccakR_SizeInBytes / sizeof(tKeccakLane));
}
if (padding)
{
/*Last data and padding*/
memcpy(temp, in, (size_t)inlen);
temp[inlen++] = 6;
if (inlen < cKeccakR_SizeInBytes)
{
memset(temp + inlen, 0, cKeccakR_SizeInBytes - (size_t)inlen);
}
temp[cKeccakR_SizeInBytes - 1] |= 0x80;
KeccakF(state, (const tKeccakLane*)temp, cKeccakR_SizeInBytes / sizeof(tKeccakLane));
}
#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) || (cKeccakB == 200)
memcpy(out, state, crypto_hash_BYTES);
#else
for (i = 0; i < (crypto_hash_BYTES / sizeof(tKeccakLane)); ++i)
{
tSmallUInt j;
tKeccakLane t;
t = state[i];
for (j = 0; j < sizeof(tKeccakLane); ++j)
{
*(out++) = (unsigned char)t;
t >>= 8;
}
}
#endif
#if (crypto_hash_BYTES >= cKeccakR_SizeInBytes)
#undef temp
#endif
return (0);
}