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