XRootD
Loading...
Searching...
No Matches
XrdOucSHA3.cc
Go to the documentation of this file.
1/******************************************************************************/
2/* */
3/* X r d O u c S H A 3 . c c */
4/* */
5/* The MIT License (MIT) */
6/* */
7/* Copyright (c) 2015 Markku-Juhani O. Saarinen */
8/* Contact: 19-Nov-11 Markku-Juhani O. Saarinen <mjos@iki.fi> */
9/* Reprository: https://github.com/mjosaarinen/tiny_sha3.git */
10/* Original: tiny_sha3/sha3.c */
11/* */
12/* Revised 07-Aug-15 to match with official release of FIPS PUB 202 "SHA3" */
13/* Revised 03-Sep-15 for portability + OpenSSL - style API */
14/* */
15/* Permission is hereby granted, free of charge, to any person obtaining a */
16/* copy of this software and associated documentation files (the "Software"), */
17/* to deal in the Software without restriction, including without limitation */
18/* the rights to use, copy, modify, merge, publish, distribute, sublicense, */
19/* and/or sell copies of the Software, and to permit persons to whom the */
20/* Software is furnished to do so, subject to the following conditions: */
21/* */
22/* The above copyright notice and this permission notice shall be included */
23/* in all copies or substantial portions of the Software. */
24/* */
25/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR */
26/* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, */
27/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL */
28/* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER */
29/* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */
30/* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER */
31/* DEALINGS IN THE SOFTWARE. */
32/******************************************************************************/
33
34#include "XrdOuc/XrdOucSHA3.hh"
35
36/******************************************************************************/
37/* S H A 3 D e f i n e s */
38/******************************************************************************/
39
40#ifndef KECCAKF_ROUNDS
41#define KECCAKF_ROUNDS 24
42#endif
43
44#ifndef ROTL64
45#define ROTL64(x, y) (((x) << (y)) | ((x) >> (64 - (y))))
46#endif
47
48/******************************************************************************/
49/* Private: s h a 3 _ k e c c a k f */
50/******************************************************************************/
51
52// update the state with given number of rounds
53
54void XrdOucSHA3::sha3_keccakf(uint64_t st[25])
55{
56 // constants
57 const uint64_t keccakf_rndc[24] = {
58 0x0000000000000001, 0x0000000000008082, 0x800000000000808a,
59 0x8000000080008000, 0x000000000000808b, 0x0000000080000001,
60 0x8000000080008081, 0x8000000000008009, 0x000000000000008a,
61 0x0000000000000088, 0x0000000080008009, 0x000000008000000a,
62 0x000000008000808b, 0x800000000000008b, 0x8000000000008089,
63 0x8000000000008003, 0x8000000000008002, 0x8000000000000080,
64 0x000000000000800a, 0x800000008000000a, 0x8000000080008081,
65 0x8000000000008080, 0x0000000080000001, 0x8000000080008008
66 };
67 const int keccakf_rotc[24] = {
68 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14,
69 27, 41, 56, 8, 25, 43, 62, 18, 39, 61, 20, 44
70 };
71 const int keccakf_piln[24] = {
72 10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4,
73 15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1
74 };
75
76 // variables
77 int i, j, r;
78 uint64_t t, bc[5];
79
80#if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__
81 uint8_t *v;
82
83 // endianess conversion. this is redundant on little-endian targets
84 for (i = 0; i < 25; i++) {
85 v = (uint8_t *) &st[i];
86 st[i] = ((uint64_t) v[0]) | (((uint64_t) v[1]) << 8) |
87 (((uint64_t) v[2]) << 16) | (((uint64_t) v[3]) << 24) |
88 (((uint64_t) v[4]) << 32) | (((uint64_t) v[5]) << 40) |
89 (((uint64_t) v[6]) << 48) | (((uint64_t) v[7]) << 56);
90 }
91#endif
92
93 // actual iteration
94 for (r = 0; r < KECCAKF_ROUNDS; r++) {
95
96 // Theta
97 for (i = 0; i < 5; i++)
98 bc[i] = st[i] ^ st[i + 5] ^ st[i + 10] ^ st[i + 15] ^ st[i + 20];
99
100 for (i = 0; i < 5; i++) {
101 t = bc[(i + 4) % 5] ^ ROTL64(bc[(i + 1) % 5], 1);
102 for (j = 0; j < 25; j += 5)
103 st[j + i] ^= t;
104 }
105
106 // Rho Pi
107 t = st[1];
108 for (i = 0; i < 24; i++) {
109 j = keccakf_piln[i];
110 bc[0] = st[j];
111 st[j] = ROTL64(t, keccakf_rotc[i]);
112 t = bc[0];
113 }
114
115 // Chi
116 for (j = 0; j < 25; j += 5) {
117 for (i = 0; i < 5; i++)
118 bc[i] = st[j + i];
119 for (i = 0; i < 5; i++)
120 st[j + i] ^= (~bc[(i + 1) % 5]) & bc[(i + 2) % 5];
121 }
122
123 // Iota
124 st[0] ^= keccakf_rndc[r];
125 }
126
127#if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__
128 // endianess conversion. this is redundant on little-endian targets
129 for (i = 0; i < 25; i++) {
130 v = (uint8_t *) &st[i];
131 t = st[i];
132 v[0] = t & 0xFF;
133 v[1] = (t >> 8) & 0xFF;
134 v[2] = (t >> 16) & 0xFF;
135 v[3] = (t >> 24) & 0xFF;
136 v[4] = (t >> 32) & 0xFF;
137 v[5] = (t >> 40) & 0xFF;
138 v[6] = (t >> 48) & 0xFF;
139 v[7] = (t >> 56) & 0xFF;
140 }
141#endif
142}
143
144/******************************************************************************/
145/* C a l c */
146/******************************************************************************/
147
148// compute a SHA-3 hash (md) of given byte length from "in"
149
150void *XrdOucSHA3::Calc(const void *in, size_t inlen, void *md,
151 XrdOucSHA3::MDLen mdlen)
152{
153 sha3_ctx_t sha3;
154
155 Init(&sha3, mdlen);
156 Update(&sha3, in, inlen);
157 Final(&sha3, md);
158
159 return md;
160}
161
162/******************************************************************************/
163/* I n i t */
164/******************************************************************************/
165
166// Initialize the context for SHA3
167
169{
170 int i;
171
172 for (i = 0; i < 25; i++)
173 c->st.q[i] = 0;
174 c->mdlen = (int)mdlen;
175 c->rsiz = 200 - 2 * (int)mdlen;
176 c->pt = 0;
177 c->xof= 1;
178}
179
180/******************************************************************************/
181/* U p d a t e */
182/******************************************************************************/
183
184// update state with more data
185
186void XrdOucSHA3::Update(XrdOucSHA3::sha3_ctx_t *c, const void *data, size_t len)
187{
188 size_t i;
189 int j;
190
191 j = c->pt;
192 for (i = 0; i < len; i++) {
193 c->st.b[j++] ^= ((const uint8_t *) data)[i];
194 if (j >= c->rsiz) {
195 sha3_keccakf(c->st.q);
196 j = 0;
197 }
198 }
199 c->pt = j;
200}
201
202/******************************************************************************/
203/* F i n a l */
204/******************************************************************************/
205
206// finalize and output a hash
207
209{
210 int i;
211
212 c->st.b[c->pt] ^= 0x06;
213 c->st.b[c->rsiz - 1] ^= 0x80;
214 sha3_keccakf(c->st.q);
215
216 for (i = 0; i < c->mdlen; i++) {
217 ((uint8_t *) md)[i] = c->st.b[i];
218 }
219}
220
221/******************************************************************************/
222/* Private: s h a k e _ x o f */
223/******************************************************************************/
224
225// SHAKE128 and SHAKE256 extensible-output functionality
226
227void XrdOucSHA3::shake_xof(XrdOucSHA3::sha3_ctx_t *c)
228{
229 c->st.b[c->pt] ^= 0x1F;
230 c->st.b[c->rsiz - 1] ^= 0x80;
231 sha3_keccakf(c->st.q);
232 c->pt = 0;
233}
234
235/******************************************************************************/
236/* S H A K E _ O u t */
237/******************************************************************************/
238
239void XrdOucSHA3::SHAKE_Out(XrdOucSHA3::sha3_ctx_t *c, void *out, size_t len)
240{
241 size_t i;
242 int j;
243
244 if (c->xof)
245 {shake_xof(c);
246 c->xof = 0;
247 }
248
249 j = c->pt;
250 for (i = 0; i < len; i++) {
251 if (j >= c->rsiz) {
252 sha3_keccakf(c->st.q);
253 j = 0;
254 }
255 ((uint8_t *) out)[i] = c->st.b[j++];
256 }
257 c->pt = j;
258}
#define KECCAKF_ROUNDS
Definition XrdOucSHA3.cc:41
#define ROTL64(x, y)
Definition XrdOucSHA3.cc:45
union XrdOucSHA3::sha3_ctx_t::@120 st
static void Update(sha3_ctx_t *c, const void *data, size_t len)
int xof
these don't overflow
Definition XrdOucSHA3.hh:49
MDLen
SHA3 digest lengths (bits to bytes).
Definition XrdOucSHA3.hh:56
static void * Calc(const void *in, size_t inlen, void *md, MDLen mdlen)
static void SHAKE_Out(sha3_ctx_t *c, void *out, size_t len)
static void Init(sha3_ctx_t *c, MDLen mdlen)
static void Final(sha3_ctx_t *c, void *md)
SHA3 state context used by all methods (OpenSSL - like interface)
Definition XrdOucSHA3.hh:44