1*cf5a6c84SAndroid Build Coastguard Worker /* sha3sum.c - Keccak-f[1600] permutation, sponge construction
2*cf5a6c84SAndroid Build Coastguard Worker *
3*cf5a6c84SAndroid Build Coastguard Worker * Copyright 2014 David Leon Gil <[email protected]>
4*cf5a6c84SAndroid Build Coastguard Worker *
5*cf5a6c84SAndroid Build Coastguard Worker * https://keccak.team/files/Keccak-reference-3.0.pdf
6*cf5a6c84SAndroid Build Coastguard Worker * https://csrc.nist.gov/publications/detail/fips/202/final
7*cf5a6c84SAndroid Build Coastguard Worker * https://nvlpubs.nist.gov/nistpubs/specialpublications/nist.sp.800-185.pdf
8*cf5a6c84SAndroid Build Coastguard Worker
9*cf5a6c84SAndroid Build Coastguard Worker USE_SHA3SUM(NEWTOY(sha3sum, "bSa#<128>512=224", TOYFLAG_USR|TOYFLAG_BIN))
10*cf5a6c84SAndroid Build Coastguard Worker
11*cf5a6c84SAndroid Build Coastguard Worker config SHA3SUM
12*cf5a6c84SAndroid Build Coastguard Worker bool "sha3sum"
13*cf5a6c84SAndroid Build Coastguard Worker default y
14*cf5a6c84SAndroid Build Coastguard Worker help
15*cf5a6c84SAndroid Build Coastguard Worker usage: sha3sum [-bS] [-a BITS] [FILE...]
16*cf5a6c84SAndroid Build Coastguard Worker
17*cf5a6c84SAndroid Build Coastguard Worker Hash function du jour.
18*cf5a6c84SAndroid Build Coastguard Worker
19*cf5a6c84SAndroid Build Coastguard Worker -a Produce a hash BITS long (default 224)
20*cf5a6c84SAndroid Build Coastguard Worker -b Brief (hash only, no filename)
21*cf5a6c84SAndroid Build Coastguard Worker -S Use SHAKE termination byte instead of SHA3 (ask FIPS why)
22*cf5a6c84SAndroid Build Coastguard Worker */
23*cf5a6c84SAndroid Build Coastguard Worker
24*cf5a6c84SAndroid Build Coastguard Worker #define FOR_sha3sum
25*cf5a6c84SAndroid Build Coastguard Worker #include "toys.h"
26*cf5a6c84SAndroid Build Coastguard Worker
27*cf5a6c84SAndroid Build Coastguard Worker GLOBALS(
28*cf5a6c84SAndroid Build Coastguard Worker long a;
29*cf5a6c84SAndroid Build Coastguard Worker unsigned long long rc[24];
30*cf5a6c84SAndroid Build Coastguard Worker )
31*cf5a6c84SAndroid Build Coastguard Worker
32*cf5a6c84SAndroid Build Coastguard Worker static const char rho[] =
33*cf5a6c84SAndroid Build Coastguard Worker {1,3,6,10,15,21,28,36,45,55,2,14,27,41,56,8,25,43,62,18,39,61,20,44};
34*cf5a6c84SAndroid Build Coastguard Worker static const char pi[] =
35*cf5a6c84SAndroid Build Coastguard Worker {10,7,11,17,18,3,5,16,8,21,24,4,15,23,19,13,12,2,20,14,22,9,6,1};
36*cf5a6c84SAndroid Build Coastguard Worker static const char rcpack[] =
37*cf5a6c84SAndroid Build Coastguard Worker {0x33,0x07,0xdd,0x16,0x38,0x1b,0x7b,0x2b,0xad,0x6a,0xce,0x4c,0x29,0xfe,0x31,
38*cf5a6c84SAndroid Build Coastguard Worker 0x68,0x9d,0xb0,0x8f,0x2f,0x0a};
39*cf5a6c84SAndroid Build Coastguard Worker
keccak(unsigned long long * a)40*cf5a6c84SAndroid Build Coastguard Worker static void keccak(unsigned long long *a)
41*cf5a6c84SAndroid Build Coastguard Worker {
42*cf5a6c84SAndroid Build Coastguard Worker unsigned long long b[5] = {0}, t;
43*cf5a6c84SAndroid Build Coastguard Worker int i, x, y;
44*cf5a6c84SAndroid Build Coastguard Worker
45*cf5a6c84SAndroid Build Coastguard Worker for (i = 0; i < 24; i++) {
46*cf5a6c84SAndroid Build Coastguard Worker for (x = 0; x<5; x++) for (b[x] = 0, y = 0; y<25; y += 5) b[x] ^= a[x+y];
47*cf5a6c84SAndroid Build Coastguard Worker for (x = 0; x<5; x++) for (y = 0; y<25; y += 5) {
48*cf5a6c84SAndroid Build Coastguard Worker t = b[(x+1)%5];
49*cf5a6c84SAndroid Build Coastguard Worker a[y+x] ^= b[(x+4)%5]^(t<<1|t>>63);
50*cf5a6c84SAndroid Build Coastguard Worker }
51*cf5a6c84SAndroid Build Coastguard Worker for (t = a[1], x = 0; x<24; x++) {
52*cf5a6c84SAndroid Build Coastguard Worker *b = a[pi[x]];
53*cf5a6c84SAndroid Build Coastguard Worker a[pi[x]] = (t<<rho[x])|(t>>(64-rho[x]));
54*cf5a6c84SAndroid Build Coastguard Worker t = *b;
55*cf5a6c84SAndroid Build Coastguard Worker }
56*cf5a6c84SAndroid Build Coastguard Worker for (y = 0; y<25; y += 5) {
57*cf5a6c84SAndroid Build Coastguard Worker for (x = 0; x<5; x++) b[x] = a[y + x];
58*cf5a6c84SAndroid Build Coastguard Worker for (x = 0; x<5; x++) a[y + x] = b[x]^((~b[(x+1)%5])&b[(x+2)%5]);
59*cf5a6c84SAndroid Build Coastguard Worker }
60*cf5a6c84SAndroid Build Coastguard Worker *a ^= TT.rc[i];
61*cf5a6c84SAndroid Build Coastguard Worker }
62*cf5a6c84SAndroid Build Coastguard Worker }
63*cf5a6c84SAndroid Build Coastguard Worker
do_sha3sum(int fd,char * name)64*cf5a6c84SAndroid Build Coastguard Worker static void do_sha3sum(int fd, char *name)
65*cf5a6c84SAndroid Build Coastguard Worker {
66*cf5a6c84SAndroid Build Coastguard Worker int span, ii, len, rate = 200-TT.a/4;
67*cf5a6c84SAndroid Build Coastguard Worker char *ss = toybuf, buf[200];
68*cf5a6c84SAndroid Build Coastguard Worker
69*cf5a6c84SAndroid Build Coastguard Worker memset(buf, 0, sizeof(buf));
70*cf5a6c84SAndroid Build Coastguard Worker for (len = 0;; ss += rate) {
71*cf5a6c84SAndroid Build Coastguard Worker if ((span = len-(ss-toybuf))<rate) {
72*cf5a6c84SAndroid Build Coastguard Worker memcpy(toybuf, ss, span);
73*cf5a6c84SAndroid Build Coastguard Worker len = span += readall(fd, (ss = toybuf)+span, sizeof(toybuf)-span);
74*cf5a6c84SAndroid Build Coastguard Worker }
75*cf5a6c84SAndroid Build Coastguard Worker if (span>rate) span = rate;
76*cf5a6c84SAndroid Build Coastguard Worker for (ii = 0; ii<span; ii++) buf[ii] ^= ss[ii];
77*cf5a6c84SAndroid Build Coastguard Worker if (rate!=span) {
78*cf5a6c84SAndroid Build Coastguard Worker buf[span] ^= FLAG(S) ? 0x1f : 0x06;
79*cf5a6c84SAndroid Build Coastguard Worker buf[rate-1] ^= 0x80;
80*cf5a6c84SAndroid Build Coastguard Worker }
81*cf5a6c84SAndroid Build Coastguard Worker keccak((void *)buf);
82*cf5a6c84SAndroid Build Coastguard Worker if (span<rate) break;
83*cf5a6c84SAndroid Build Coastguard Worker }
84*cf5a6c84SAndroid Build Coastguard Worker
85*cf5a6c84SAndroid Build Coastguard Worker for (ii = 0; ii<TT.a/8; ) {
86*cf5a6c84SAndroid Build Coastguard Worker printf("%02x", buf[ii%rate]);
87*cf5a6c84SAndroid Build Coastguard Worker if (!(++ii%rate)) keccak((void *)buf);
88*cf5a6c84SAndroid Build Coastguard Worker }
89*cf5a6c84SAndroid Build Coastguard Worker memset(buf, 0, sizeof(buf));
90*cf5a6c84SAndroid Build Coastguard Worker
91*cf5a6c84SAndroid Build Coastguard Worker xprintf(" %s\n"+(FLAG(b)<<2), name);
92*cf5a6c84SAndroid Build Coastguard Worker }
93*cf5a6c84SAndroid Build Coastguard Worker
94*cf5a6c84SAndroid Build Coastguard Worker // TODO test 224 256 384 512, and shake 128 256
sha3sum_main(void)95*cf5a6c84SAndroid Build Coastguard Worker void sha3sum_main(void)
96*cf5a6c84SAndroid Build Coastguard Worker {
97*cf5a6c84SAndroid Build Coastguard Worker int i, j, k;
98*cf5a6c84SAndroid Build Coastguard Worker char *s;
99*cf5a6c84SAndroid Build Coastguard Worker
100*cf5a6c84SAndroid Build Coastguard Worker // Decompress RC table
101*cf5a6c84SAndroid Build Coastguard Worker for (s = (void *)rcpack, i = 127; i; s += 3) for (i>>=1,k = j = 0; k<24; k++)
102*cf5a6c84SAndroid Build Coastguard Worker if (1&(s[k>>3]>>(7-(k&7)))) TT.rc[k] |= 1ULL<<i;
103*cf5a6c84SAndroid Build Coastguard Worker
104*cf5a6c84SAndroid Build Coastguard Worker loopfiles(toys.optargs, do_sha3sum);
105*cf5a6c84SAndroid Build Coastguard Worker }
106