keccak.c revision 1.1 1 1.1 riastrad /* $NetBSD: keccak.c,v 1.1 2017/11/30 05:47:24 riastradh Exp $ */
2 1.1 riastrad
3 1.1 riastrad /*-
4 1.1 riastrad * Copyright (c) 2015 Taylor R. Campbell
5 1.1 riastrad * All rights reserved.
6 1.1 riastrad *
7 1.1 riastrad * Redistribution and use in source and binary forms, with or without
8 1.1 riastrad * modification, are permitted provided that the following conditions
9 1.1 riastrad * are met:
10 1.1 riastrad * 1. Redistributions of source code must retain the above copyright
11 1.1 riastrad * notice, this list of conditions and the following disclaimer.
12 1.1 riastrad * 2. Redistributions in binary form must reproduce the above copyright
13 1.1 riastrad * notice, this list of conditions and the following disclaimer in the
14 1.1 riastrad * documentation and/or other materials provided with the distribution.
15 1.1 riastrad *
16 1.1 riastrad * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 1.1 riastrad * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 1.1 riastrad * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 1.1 riastrad * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 1.1 riastrad * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 1.1 riastrad * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 1.1 riastrad * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 1.1 riastrad * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 1.1 riastrad * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 1.1 riastrad * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 1.1 riastrad * SUCH DAMAGE.
27 1.1 riastrad */
28 1.1 riastrad
29 1.1 riastrad #include <sys/cdefs.h>
30 1.1 riastrad
31 1.1 riastrad #if defined(_KERNEL) || defined(_STANDALONE)
32 1.1 riastrad __KERNEL_RCSID(0, "$NetBSD: keccak.c,v 1.1 2017/11/30 05:47:24 riastradh Exp $");
33 1.1 riastrad
34 1.1 riastrad #include <sys/types.h>
35 1.1 riastrad #else
36 1.1 riastrad __RCSID("$NetBSD: keccak.c,v 1.1 2017/11/30 05:47:24 riastradh Exp $");
37 1.1 riastrad
38 1.1 riastrad #include <stdint.h>
39 1.1 riastrad #endif
40 1.1 riastrad
41 1.1 riastrad #include "keccak.h"
42 1.1 riastrad
43 1.1 riastrad #define secret /* can't use in variable-time operations, should zero */
44 1.1 riastrad
45 1.1 riastrad #define FOR5(X, STMT) do \
46 1.1 riastrad { \
47 1.1 riastrad (X) = 0; STMT; \
48 1.1 riastrad (X) = 1; STMT; \
49 1.1 riastrad (X) = 2; STMT; \
50 1.1 riastrad (X) = 3; STMT; \
51 1.1 riastrad (X) = 4; STMT; \
52 1.1 riastrad } while (0)
53 1.1 riastrad
54 1.1 riastrad static inline secret uint64_t
55 1.1 riastrad rol64(secret uint64_t v, unsigned c)
56 1.1 riastrad {
57 1.1 riastrad
58 1.1 riastrad return ((v << c) | (v >> (64 - c)));
59 1.1 riastrad }
60 1.1 riastrad
61 1.1 riastrad static inline void
62 1.1 riastrad keccakf1600_theta(secret uint64_t A[25])
63 1.1 riastrad {
64 1.1 riastrad secret uint64_t C0, C1, C2, C3, C4;
65 1.1 riastrad unsigned y;
66 1.1 riastrad
67 1.1 riastrad C0 = C1 = C2 = C3 = C4 = 0;
68 1.1 riastrad FOR5(y, {
69 1.1 riastrad C0 ^= A[0 + 5*y];
70 1.1 riastrad C1 ^= A[1 + 5*y];
71 1.1 riastrad C2 ^= A[2 + 5*y];
72 1.1 riastrad C3 ^= A[3 + 5*y];
73 1.1 riastrad C4 ^= A[4 + 5*y];
74 1.1 riastrad });
75 1.1 riastrad FOR5(y, {
76 1.1 riastrad A[0 + 5*y] ^= C4 ^ rol64(C1, 1);
77 1.1 riastrad A[1 + 5*y] ^= C0 ^ rol64(C2, 1);
78 1.1 riastrad A[2 + 5*y] ^= C1 ^ rol64(C3, 1);
79 1.1 riastrad A[3 + 5*y] ^= C2 ^ rol64(C4, 1);
80 1.1 riastrad A[4 + 5*y] ^= C3 ^ rol64(C0, 1);
81 1.1 riastrad });
82 1.1 riastrad }
83 1.1 riastrad
84 1.1 riastrad static inline void
85 1.1 riastrad keccakf1600_rho_pi(secret uint64_t A[25])
86 1.1 riastrad {
87 1.1 riastrad secret uint64_t T, U;
88 1.1 riastrad
89 1.1 riastrad /*
90 1.1 riastrad * Permute by (x,y) |---> (y, 2x + 3y mod 5) starting at (1,0),
91 1.1 riastrad * rotate the ith element by (i + 1)(i + 2)/2 mod 64.
92 1.1 riastrad */
93 1.1 riastrad U = A[ 1]; T = U;
94 1.1 riastrad U = A[10]; A[10] = rol64(T, 1); T = U;
95 1.1 riastrad U = A[ 7]; A[ 7] = rol64(T, 3); T = U;
96 1.1 riastrad U = A[11]; A[11] = rol64(T, 6); T = U;
97 1.1 riastrad U = A[17]; A[17] = rol64(T, 10); T = U;
98 1.1 riastrad U = A[18]; A[18] = rol64(T, 15); T = U;
99 1.1 riastrad U = A[ 3]; A[ 3] = rol64(T, 21); T = U;
100 1.1 riastrad U = A[ 5]; A[ 5] = rol64(T, 28); T = U;
101 1.1 riastrad U = A[16]; A[16] = rol64(T, 36); T = U;
102 1.1 riastrad U = A[ 8]; A[ 8] = rol64(T, 45); T = U;
103 1.1 riastrad U = A[21]; A[21] = rol64(T, 55); T = U;
104 1.1 riastrad U = A[24]; A[24] = rol64(T, 2); T = U;
105 1.1 riastrad U = A[ 4]; A[ 4] = rol64(T, 14); T = U;
106 1.1 riastrad U = A[15]; A[15] = rol64(T, 27); T = U;
107 1.1 riastrad U = A[23]; A[23] = rol64(T, 41); T = U;
108 1.1 riastrad U = A[19]; A[19] = rol64(T, 56); T = U;
109 1.1 riastrad U = A[13]; A[13] = rol64(T, 8); T = U;
110 1.1 riastrad U = A[12]; A[12] = rol64(T, 25); T = U;
111 1.1 riastrad U = A[ 2]; A[ 2] = rol64(T, 43); T = U;
112 1.1 riastrad U = A[20]; A[20] = rol64(T, 62); T = U;
113 1.1 riastrad U = A[14]; A[14] = rol64(T, 18); T = U;
114 1.1 riastrad U = A[22]; A[22] = rol64(T, 39); T = U;
115 1.1 riastrad U = A[ 9]; A[ 9] = rol64(T, 61); T = U;
116 1.1 riastrad U = A[ 6]; A[ 6] = rol64(T, 20); T = U;
117 1.1 riastrad A[ 1] = rol64(T, 44);
118 1.1 riastrad }
119 1.1 riastrad
120 1.1 riastrad static inline void
121 1.1 riastrad keccakf1600_chi(secret uint64_t A[25])
122 1.1 riastrad {
123 1.1 riastrad secret uint64_t B0, B1, B2, B3, B4;
124 1.1 riastrad unsigned y;
125 1.1 riastrad
126 1.1 riastrad FOR5(y, {
127 1.1 riastrad B0 = A[0 + 5*y];
128 1.1 riastrad B1 = A[1 + 5*y];
129 1.1 riastrad B2 = A[2 + 5*y];
130 1.1 riastrad B3 = A[3 + 5*y];
131 1.1 riastrad B4 = A[4 + 5*y];
132 1.1 riastrad A[0 + 5*y] ^= ~B1 & B2;
133 1.1 riastrad A[1 + 5*y] ^= ~B2 & B3;
134 1.1 riastrad A[2 + 5*y] ^= ~B3 & B4;
135 1.1 riastrad A[3 + 5*y] ^= ~B4 & B0;
136 1.1 riastrad A[4 + 5*y] ^= ~B0 & B1;
137 1.1 riastrad });
138 1.1 riastrad }
139 1.1 riastrad
140 1.1 riastrad static void
141 1.1 riastrad keccakf1600_round(secret uint64_t A[25])
142 1.1 riastrad {
143 1.1 riastrad
144 1.1 riastrad keccakf1600_theta(A);
145 1.1 riastrad keccakf1600_rho_pi(A);
146 1.1 riastrad keccakf1600_chi(A);
147 1.1 riastrad }
148 1.1 riastrad
149 1.1 riastrad void
150 1.1 riastrad keccakf1600(secret uint64_t A[25])
151 1.1 riastrad {
152 1.1 riastrad /*
153 1.1 riastrad * RC[i] = \sum_{j = 0,...,6} rc(j + 7i) 2^(2^j - 1),
154 1.1 riastrad * rc(t) = (x^t mod x^8 + x^6 + x^5 + x^4 + 1) mod x in GF(2)[x]
155 1.1 riastrad */
156 1.1 riastrad static const uint64_t RC[24] = {
157 1.1 riastrad 0x0000000000000001ULL,
158 1.1 riastrad 0x0000000000008082ULL,
159 1.1 riastrad 0x800000000000808aULL,
160 1.1 riastrad 0x8000000080008000ULL,
161 1.1 riastrad 0x000000000000808bULL,
162 1.1 riastrad 0x0000000080000001ULL,
163 1.1 riastrad 0x8000000080008081ULL,
164 1.1 riastrad 0x8000000000008009ULL,
165 1.1 riastrad 0x000000000000008aULL,
166 1.1 riastrad 0x0000000000000088ULL,
167 1.1 riastrad 0x0000000080008009ULL,
168 1.1 riastrad 0x000000008000000aULL,
169 1.1 riastrad 0x000000008000808bULL,
170 1.1 riastrad 0x800000000000008bULL,
171 1.1 riastrad 0x8000000000008089ULL,
172 1.1 riastrad 0x8000000000008003ULL,
173 1.1 riastrad 0x8000000000008002ULL,
174 1.1 riastrad 0x8000000000000080ULL,
175 1.1 riastrad 0x000000000000800aULL,
176 1.1 riastrad 0x800000008000000aULL,
177 1.1 riastrad 0x8000000080008081ULL,
178 1.1 riastrad 0x8000000000008080ULL,
179 1.1 riastrad 0x0000000080000001ULL,
180 1.1 riastrad 0x8000000080008008ULL,
181 1.1 riastrad };
182 1.1 riastrad unsigned i;
183 1.1 riastrad
184 1.1 riastrad for (i = 0; i < 24; i++) {
185 1.1 riastrad keccakf1600_round(A);
186 1.1 riastrad A[0] ^= RC[i];
187 1.1 riastrad }
188 1.1 riastrad }
189