• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
10 USE_SHA3SUM(NEWTOY(sha3sum, "bSa#<128>512=224", TOYFLAG_USR|TOYFLAG_BIN))
11 
12 config 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 
28 GLOBALS(
29   long a;
30   unsigned long long rc[24];
31 )
32 
33 static 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};
35 static 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};
37 static 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 
keccak(unsigned long long * a)41 static 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 
do_sha3sum(int fd,char * name)65 static 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
sha3sum_main(void)97 void 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