Home | History | Annotate | Line # | Download | only in sha3
      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