3 sha3-256 hash function (once crashed compiler when targeting hc08/s08/mos6502/mos65c02).
5 Based on implementation by Eugene Chou (which in turn was based on an implementation by Dr. Markku-Juhani O. Saarinen).
13 #if !defined(__SDCC_mos6502) && !defined(__SDCC_mos65c02) // mos6052/mos65c02 can't return struct this large yet.
14 #if !defined(__SDCC_hc08) && !defined(__SDCC_s08) && !defined(__SDCC_ds390) // hc08/s08/ds390 can't return struct yet.
15 #if !defined(__SDCC_mcs51) && !defined(__SDCC_pdk14) && !defined(__SDCC_pdk15) && !( (defined (__SDCC_mos6502) || defined(__SDCC_mos65c02 )) && defined(__SDCC_STACK_AUTO) ) // Lack of memory
17 #define SHA3_256_MD_LEN 32 // 256-bit digest length in bytes.
18 #define SHA3_256_ROUNDS 24 // KECCAK rounds to perform for SHA3-256.
19 #define SHA3_256_WIDTH 200 // 1600-bit width in bytes.
20 #define SHA3_256_LANES 25 // State is an unrolled 5x5 array of 64-bit lanes.
21 #define SHA3_256_RATE 136 // 1600-bit width - 512-bit capacity in bytes.
27 uint64_t words
[SHA3_256_LANES
];
28 uint8_t bytes
[SHA3_256_WIDTH
];
32 struct Sha3_256
sha3_256_new(void);
34 void sha3_256_update(struct Sha3_256
*ctx
, uint8_t *data
, uint64_t n
);
36 void sha3_256_finalize(struct Sha3_256
*ctx
, uint8_t *digest
);
38 void sha3_256_digest(uint8_t *data
, uint64_t n
, uint8_t *digest
);
40 #define ROTL64(x, y) (((x) << (y)) | ((x) >> (64 - (y))))
42 static void theta(struct Sha3_256
*ctx
) {
43 uint64_t C
[5] = { 0 };
44 uint64_t D
[5] = { 0 };
46 for (int i
= 0; i
< 5; i
+= 1) {
47 C
[i
] = ctx
->state
.words
[i
];
48 C
[i
] ^= ctx
->state
.words
[i
+ 5];
49 C
[i
] ^= ctx
->state
.words
[i
+ 10];
50 C
[i
] ^= ctx
->state
.words
[i
+ 15];
51 C
[i
] ^= ctx
->state
.words
[i
+ 20];
54 for (int i
= 0; i
< 5; i
+= 1) {
55 D
[i
] = C
[(i
+ 4) % 5] ^ ROTL64(C
[(i
+ 1) % 5], 1);
58 for (int i
= 0; i
< 5; i
+= 1) {
59 for (int j
= 0; j
< 25; j
+= 5) {
60 ctx
->state
.words
[i
+ j
] ^= D
[i
];
65 static void rho(struct Sha3_256
*ctx
) {
66 static const int rotations
[25] = {
74 for (int i
= 0; i
< 25; i
+= 1) {
75 ctx
->state
.words
[i
] = ROTL64(ctx
->state
.words
[i
], rotations
[i
]);
79 static void pi(struct Sha3_256
*ctx
) {
80 static const int switcheroo
[25] = {
88 uint64_t temp
[25] = { 0 };
90 for (int i
= 0; i
< 25; i
+= 1) {
91 temp
[i
] = ctx
->state
.words
[i
];
94 for (int i
= 0; i
< 25; i
+= 1) {
95 ctx
->state
.words
[switcheroo
[i
]] = temp
[i
];
99 static void chi(struct Sha3_256
*ctx
) {
100 uint64_t temp
[5] = { 0 };
102 for (int j
= 0; j
< 25; j
+= 5) {
103 for (int i
= 0; i
< 5; i
+= 1) {
104 temp
[i
] = ctx
->state
.words
[i
+ j
];
107 for (int i
= 0; i
< 5; i
+= 1) {
108 ctx
->state
.words
[i
+ j
] ^= (~temp
[(i
+ 1) % 5]) & temp
[(i
+ 2) % 5];
113 static void iota(struct Sha3_256
*ctx
, uint8_t r
) {
114 static const uint64_t constants
[24] = {
115 0x0000000000000001, 0x0000000000008082, 0x800000000000808a,
116 0x8000000080008000, 0x000000000000808b, 0x0000000080000001,
117 0x8000000080008081, 0x8000000000008009, 0x000000000000008a,
118 0x0000000000000088, 0x0000000080008009, 0x000000008000000a,
119 0x000000008000808b, 0x800000000000008b, 0x8000000000008089,
120 0x8000000000008003, 0x8000000000008002, 0x8000000000000080,
121 0x000000000000800a, 0x800000008000000a, 0x8000000080008081,
122 0x8000000000008080, 0x0000000080000001, 0x8000000080008008
125 ctx
->state
.words
[0] ^= constants
[r
];
128 static void keccak(struct Sha3_256
*ctx
) {
129 for (int i
= 0; i
< SHA3_256_ROUNDS
; i
+= 1) {
138 static void absorb(struct Sha3_256
*ctx
, uint8_t *data
, uint64_t n
) {
139 for (uint64_t i
= 0; i
< n
; i
+= 1) {
140 ctx
->state
.bytes
[ctx
->absorbed
++] ^= data
[i
];
142 if (ctx
->absorbed
== SHA3_256_RATE
) {
148 ctx
->padpoint
= ctx
->absorbed
;
151 static void squeeze(struct Sha3_256
*ctx
, uint8_t *digest
) {
152 ctx
->state
.bytes
[ctx
->padpoint
] ^= 0x06;
153 ctx
->state
.bytes
[SHA3_256_RATE
- 1] ^= 0x80;
157 for (int i
= 0; i
< SHA3_256_MD_LEN
; i
+= 1) {
158 digest
[i
] = ctx
->state
.bytes
[i
];
161 ctx
->padpoint
= ctx
->absorbed
= 0;
162 memset(&ctx
->state
.words
, 0, sizeof(ctx
->state
.words
));
165 struct Sha3_256
sha3_256_new(void) {
167 memset(&ctx
, 0, sizeof(ctx
));
171 void sha3_256_update(struct Sha3_256
*ctx
, uint8_t *data
, uint64_t n
) {
172 absorb(ctx
, data
, n
);
175 void sha3_256_finalize(struct Sha3_256
*ctx
, uint8_t *digest
) {
176 squeeze(ctx
, digest
);
179 void sha3_256_digest(uint8_t *data
, uint64_t n
, uint8_t *digest
) {
181 ctx
= sha3_256_new();
182 absorb(&ctx
, data
, n
);
183 squeeze(&ctx
, digest
);
188 unsigned char* in
; /* input string */
189 unsigned char out
[32]; /* expected output */
192 /* known input/output pairs */
193 const struct pair pairs
[] = {
194 /* 0: empty string */
197 {0xa7, 0xff, 0xc6, 0xf8, 0xbf, 0x1e, 0xd7, 0x66, 0x51, 0xc1, 0x47, 0x56, 0xa0, 0x61, 0xd6, 0x62, 0xf5, 0x80, 0xff, 0x4d, 0xe4, 0x3b, 0x49, 0xfa, 0x82, 0xd8, 0x0a, 0x4b, 0x80, 0xf8, 0x43, 0x4a}
201 "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
202 {0x91, 0x6f, 0x60, 0x61, 0xfe, 0x87, 0x97, 0x41, 0xca, 0x64, 0x69, 0xb4, 0x39, 0x71, 0xdf, 0xdb, 0x28, 0xb1, 0xa3, 0x2d, 0xc3, 0x6c, 0xb3, 0x25, 0x4e, 0x81, 0x2b, 0xe2, 0x7a, 0xad, 0x1d, 0x18}
213 #if __STDC_ENDIAN_NATIVE__ // The implementation assumes little-endian
214 #if !defined(__SDCC_mos6502) && !defined(__SDCC_mos65c02) // mos6502/mos65c02 can't return struct this large yet
215 #if !defined(__SDCC_ds390) // ds390 can't return struct yet.
216 #if !__SDCC_mcs51 && !defined(__SDCC_pdk14) && !defined(__SDCC_pdk15) // Lack of memory
219 for (i
= 0; i
< sizeof(pairs
)/sizeof(pairs
[0]); i
++) {
220 unsigned char out
[32];
221 sha3_256_digest(pairs
[i
].in
, strlen(pairs
[i
].in
), out
);
222 ASSERT(!memcmp(out
, pairs
[i
].out
, sizeof(out
)));