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