Skip to content

Commit 5ce6530

Browse files
committed
Example: custom_backend, add tiny_sha3 as custom FIPS202 backend
Signed-off-by: willieyz <[email protected]>
1 parent f5b0907 commit 5ce6530

File tree

3 files changed

+279
-0
lines changed

3 files changed

+279
-0
lines changed
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/*
2+
* Copyright (c) The mldsa-native project authors
3+
* SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT
4+
*/
5+
6+
#if !defined(MLD_FIPS202_CUSTOM_TINY_SHA3_H)
7+
#define MLD_FIPS202_CUSTOM_TINY_SHA3_H
8+
9+
#if !defined(__ASSEMBLER__)
10+
#include "../api.h"
11+
#include "src/sha3.h"
12+
/* Replace (single) Keccak-F1600 by tiny-SHA3's */
13+
#define MLD_USE_FIPS202_X1_NATIVE
14+
static MLD_INLINE int mld_keccak_f1600_x1_native(uint64_t *state)
15+
{
16+
sha3_keccakf(state);
17+
// TODO: use 0 instead of MLD_NATIVE_FUNC_SUCCESS, wait for merged PR #607
18+
return 0;
19+
}
20+
#endif /* !__ASSEMBLER__ */
21+
22+
#endif /* !MLD_FIPS202_CUSTOM_TINY_SHA3_H */
Lines changed: 207 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
/* SPDX-License-Identifier: MIT
2+
*
3+
* sha3.c
4+
* 19-Nov-11 Markku-Juhani O. Saarinen <[email protected]> */
5+
6+
/* Revised 07-Aug-15 to match with official release of FIPS PUB 202 "SHA3" */
7+
/* Revised 03-Sep-15 for portability + OpenSSL - style API */
8+
9+
#include "sha3.h"
10+
11+
/* update the state with given number of rounds */
12+
13+
void sha3_keccakf(uint64_t st[25])
14+
{
15+
/* constants */
16+
const uint64_t keccakf_rndc[24] = {
17+
0x0000000000000001, 0x0000000000008082, 0x800000000000808a,
18+
0x8000000080008000, 0x000000000000808b, 0x0000000080000001,
19+
0x8000000080008081, 0x8000000000008009, 0x000000000000008a,
20+
0x0000000000000088, 0x0000000080008009, 0x000000008000000a,
21+
0x000000008000808b, 0x800000000000008b, 0x8000000000008089,
22+
0x8000000000008003, 0x8000000000008002, 0x8000000000000080,
23+
0x000000000000800a, 0x800000008000000a, 0x8000000080008081,
24+
0x8000000000008080, 0x0000000080000001, 0x8000000080008008};
25+
const int keccakf_rotc[24] = {1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14,
26+
27, 41, 56, 8, 25, 43, 62, 18, 39, 61, 20, 44};
27+
const int keccakf_piln[24] = {10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4,
28+
15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1};
29+
30+
/* variables */
31+
int i, j, r;
32+
uint64_t t, bc[5];
33+
34+
#if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__
35+
uint8_t *v;
36+
37+
/* endianness conversion. this is redundant on little-endian targets */
38+
for (i = 0; i < 25; i++)
39+
{
40+
v = (uint8_t *)&st[i];
41+
st[i] = ((uint64_t)v[0]) | (((uint64_t)v[1]) << 8) |
42+
(((uint64_t)v[2]) << 16) | (((uint64_t)v[3]) << 24) |
43+
(((uint64_t)v[4]) << 32) | (((uint64_t)v[5]) << 40) |
44+
(((uint64_t)v[6]) << 48) | (((uint64_t)v[7]) << 56);
45+
}
46+
#endif /* __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__ */
47+
48+
/* actual iteration */
49+
for (r = 0; r < KECCAKF_ROUNDS; r++)
50+
{
51+
/* Theta */
52+
for (i = 0; i < 5; i++)
53+
{
54+
bc[i] = st[i] ^ st[i + 5] ^ st[i + 10] ^ st[i + 15] ^ st[i + 20];
55+
}
56+
57+
for (i = 0; i < 5; i++)
58+
{
59+
t = bc[(i + 4) % 5] ^ ROTL64(bc[(i + 1) % 5], 1);
60+
for (j = 0; j < 25; j += 5)
61+
{
62+
st[j + i] ^= t;
63+
}
64+
}
65+
66+
/* Rho Pi */
67+
t = st[1];
68+
for (i = 0; i < 24; i++)
69+
{
70+
j = keccakf_piln[i];
71+
bc[0] = st[j];
72+
st[j] = ROTL64(t, keccakf_rotc[i]);
73+
t = bc[0];
74+
}
75+
76+
/* Chi */
77+
for (j = 0; j < 25; j += 5)
78+
{
79+
for (i = 0; i < 5; i++)
80+
{
81+
bc[i] = st[j + i];
82+
}
83+
for (i = 0; i < 5; i++)
84+
{
85+
st[j + i] ^= (~bc[(i + 1) % 5]) & bc[(i + 2) % 5];
86+
}
87+
}
88+
89+
/* Iota */
90+
st[0] ^= keccakf_rndc[r];
91+
}
92+
93+
#if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__
94+
/* endianness conversion. this is redundant on little-endian targets */
95+
for (i = 0; i < 25; i++)
96+
{
97+
v = (uint8_t *)&st[i];
98+
t = st[i];
99+
v[0] = (uint8_t)(t & 0xFF);
100+
v[1] = (uint8_t)((t >> 8) & 0xFF);
101+
v[2] = (uint8_t)((t >> 16) & 0xFF);
102+
v[3] = (uint8_t)((t >> 24) & 0xFF);
103+
v[4] = (uint8_t)((t >> 32) & 0xFF);
104+
v[5] = (uint8_t)((t >> 40) & 0xFF);
105+
v[6] = (uint8_t)((t >> 48) & 0xFF);
106+
v[7] = (uint8_t)((t >> 56) & 0xFF);
107+
}
108+
#endif /* __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__ */
109+
}
110+
111+
/* Initialize the context for SHA3 */
112+
113+
int sha3_init(sha3_ctx_t *c, int mdlen)
114+
{
115+
int i;
116+
117+
for (i = 0; i < 25; i++)
118+
{
119+
c->st.q[i] = 0;
120+
}
121+
c->mdlen = mdlen;
122+
c->rsiz = 200 - 2 * mdlen;
123+
c->pt = 0;
124+
125+
return 1;
126+
}
127+
128+
/* update state with more data */
129+
130+
int sha3_update(sha3_ctx_t *c, const void *data, size_t len)
131+
{
132+
size_t i;
133+
int j;
134+
135+
j = c->pt;
136+
for (i = 0; i < len; i++)
137+
{
138+
c->st.b[j++] ^= ((const uint8_t *)data)[i];
139+
if (j >= c->rsiz)
140+
{
141+
sha3_keccakf(c->st.q);
142+
j = 0;
143+
}
144+
}
145+
c->pt = j;
146+
147+
return 1;
148+
}
149+
150+
/* finalize and output a hash */
151+
152+
int sha3_final(void *md, sha3_ctx_t *c)
153+
{
154+
int i;
155+
156+
c->st.b[c->pt] ^= 0x06;
157+
c->st.b[c->rsiz - 1] ^= 0x80;
158+
sha3_keccakf(c->st.q);
159+
160+
for (i = 0; i < c->mdlen; i++)
161+
{
162+
((uint8_t *)md)[i] = c->st.b[i];
163+
}
164+
165+
return 1;
166+
}
167+
168+
/* compute a SHA-3 hash (md) of given byte length from "in" */
169+
170+
void *sha3(const void *in, size_t inlen, void *md, int mdlen)
171+
{
172+
sha3_ctx_t sha3;
173+
174+
sha3_init(&sha3, mdlen);
175+
sha3_update(&sha3, in, inlen);
176+
sha3_final(md, &sha3);
177+
178+
return md;
179+
}
180+
181+
/* SHAKE128 and SHAKE256 extensible-output functionality */
182+
183+
void shake_xof(sha3_ctx_t *c)
184+
{
185+
c->st.b[c->pt] ^= 0x1F;
186+
c->st.b[c->rsiz - 1] ^= 0x80;
187+
sha3_keccakf(c->st.q);
188+
c->pt = 0;
189+
}
190+
191+
void shake_out(sha3_ctx_t *c, void *out, size_t len)
192+
{
193+
size_t i;
194+
int j;
195+
196+
j = c->pt;
197+
for (i = 0; i < len; i++)
198+
{
199+
if (j >= c->rsiz)
200+
{
201+
sha3_keccakf(c->st.q);
202+
j = 0;
203+
}
204+
((uint8_t *)out)[i] = c->st.b[j++];
205+
}
206+
c->pt = j;
207+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/* SPDX-License-Identifier: MIT
2+
*
3+
* sha3.h
4+
* 19-Nov-11 Markku-Juhani O. Saarinen <[email protected]> */
5+
6+
#ifndef SHA3_H
7+
#define SHA3_H
8+
9+
#include <stddef.h>
10+
#include <stdint.h>
11+
12+
#ifndef KECCAKF_ROUNDS
13+
#define KECCAKF_ROUNDS 24
14+
#endif
15+
16+
#ifndef ROTL64
17+
#define ROTL64(x, y) (((x) << (y)) | ((x) >> (64 - (y))))
18+
#endif
19+
20+
/* state context */
21+
typedef struct
22+
{
23+
union
24+
{ /* state: */
25+
uint8_t b[200]; /* 8-bit bytes */
26+
uint64_t q[25]; /* 64-bit words */
27+
} st;
28+
int pt, rsiz, mdlen; /* these don't overflow */
29+
} sha3_ctx_t;
30+
31+
/* Compression function. */
32+
void sha3_keccakf(uint64_t st[25]);
33+
34+
/* OpenSSL - like interfece */
35+
int sha3_init(sha3_ctx_t *c, int mdlen); /* mdlen = hash output in bytes */
36+
int sha3_update(sha3_ctx_t *c, const void *data, size_t len);
37+
int sha3_final(void *md, sha3_ctx_t *c); /* digest goes to md */
38+
39+
/* compute a sha3 hash (md) of given byte length from "in" */
40+
void *sha3(const void *in, size_t inlen, void *md, int mdlen);
41+
42+
/* SHAKE128 and SHAKE256 extensible-output functions */
43+
#define shake128_init(c) sha3_init(c, 16)
44+
#define shake256_init(c) sha3_init(c, 32)
45+
#define shake_update sha3_update
46+
47+
void shake_xof(sha3_ctx_t *c);
48+
void shake_out(sha3_ctx_t *c, void *out, size_t len);
49+
50+
#endif /* !SHA3_H */

0 commit comments

Comments
 (0)