aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--.gitignore22
-rw-r--r--Makefile90
-rw-r--r--README.md90
-rw-r--r--c/sha3.c905
-rw-r--r--c/sha3.h137
-rw-r--r--c/sha3sum.c760
-rw-r--r--java-c-jni/SHA3.c871
-rw-r--r--java-c-jni/SHA3.java384
-rw-r--r--java-c-jni/sha3sum.java485
-rw-r--r--java/ConcurrentSHA3.java963
-rw-r--r--java/SHA3.java969
-rw-r--r--java/sha3_256sum.java42
-rw-r--r--java/sha3_384sum.java42
-rw-r--r--java/sha3_512sum.java42
-rw-r--r--java/sha3sum.java485
-rw-r--r--python2/sha3.py668
-rwxr-xr-xpython2/sha3sum.py398
-rw-r--r--python3/sha3.py661
-rwxr-xr-xpython3/sha3sum.py386
-rw-r--r--src/sha3sum.c (renamed from java/sha3_224sum.java)24
-rw-r--r--test-cases1
21 files changed, 6 insertions, 8419 deletions
diff --git a/.gitignore b/.gitignore
index 2de43a4..4a1d36d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,27 +1,17 @@
_/
+obj/
bin/
-\#*\#*
+\#*\#
.*
!.git*
*~
-*.sw[op]
+*.swo
+*.swp
*.bak
-__pycache__/
-*.class
-*.jar
-*.py[co]
*.o
*.out
*.so
+*.a
+*.su
*.gch
-java-c-jni/*.h
-*.info
-*.pdf
-*.ps
-*.dvi
-*.tar
-*.tgz
-*.gz
-*.bz2
-*.xz
diff --git a/Makefile b/Makefile
index 9be3ffa..c873690 100644
--- a/Makefile
+++ b/Makefile
@@ -7,98 +7,8 @@
#
# [GNU All Permissive License]
-# NB! Do not forget to test against -O0, -O4 to -O6 (ignored in GCC) and -Ofast is not safe
-C_OPTIMISE=-Ofast
-JAVA_OPTIMISE=-O
-
-LIB_EXT=so
-
-JAVAC=javac
-JAVAH=javah
-JAR=jar
-JAVADIRS=-s "java" -d "bin/java" -cp "java"
-JAVAFLAGS=-Xlint $(JAVA_OPTIMISE)
-JAVA_FLAGS=$(JAVADIRS) $(JAVAFLAGS)
-
-WITH_WIPE=yes
-CFLAGS=-Wall -Wextra -pedantic $(C_OPTIMISE) -fPIC
-ifeq ($(WITH_C99),yes)
- CFLAGS+=-std=c99 -DWITH_C99
-endif
-ifeq ($(WITH_THREADLOCAL),yes)
- CFLAGS+=-DWITH_THREADLOCAL -DWITH_WIPE
-endif
-ifeq ($(WITH_WIPE),yes)
- CFLAGS+=-DWITH_WIPE
-endif
-SOFLAGS=-Wall -Wextra -pedantic $(C_OPTIMISE) -shared
-CPPFLAGS=
-LDFLAGS=
-C_FLAGS=$(CFLAGS) $(CPPFLAGS) $(LDFLAGS)
-SO_FLAGS=$(SOFLAGS) $(CPPFLAGS) $(LDFLAGS)
-
-JNI_C_INCLUDE=-I$${JAVA_HOME}/include
-JNI_C_FLAGS=$(JNI_INCLUDE) -fPIC -shared
-JNI_JAVADIRS=-s "java-c-jni" -d "bin/java-c-jni" -cp "java-c-jni"
-JNI_JAVAFLAGS=-Xlint $(JAVA_OPTIMISE)
-JNI_JAVA_FLAGS=$(JNI_JAVADIRS) $(JNI_JAVAFLAGS)
-
-JAVA_CLASSES = $(shell find "java" | grep '\.java$$' | sed -e 's_^_bin/_g' -e 's_java$$_class_g')
-C_OBJS = $(shell find "c" | grep '\.h$$' | sed -e 's_^_bin/_g' -e 's_h$$_o_g')
-C_BINS = bin/c/sha3sum
-JNI_CLASSES = $(shell find "java-c-jni" | grep '\.java$$' | sed -e 's_^_bin/_g' -e 's_java$$_class_g')
-
-
-
-.PHONY: all
-all: java c java-c-jni
-
-
-.PHONY: java java-bin java-jar
-java: java-bin java-jar
-java-bin: $(JAVA_CLASSES)
-bin/java/%.class: java/%.java
- mkdir -p "bin/java"
- $(JAVAC) $(JAVA_FLAGS) "java/$*.java"
-java-jar: bin/java/sha3.jar
-bin/java/sha3.jar: bin/java/SHA3.class bin/java/ConcurrentSHA3.class
- cd bin/java; $(JAR) cf sha3.jar SHA3.class ConcurrentSHA3.class
-
-
-.PHONY: c c-bin c-so
-c: c-bin c-so
-c-bin: $(C_OBJS) $(C_BINS)
-bin/c/%.o: c/%.h c/%.c
- mkdir -p "bin/c"
- $(CC) $(C_FLAGS) -c "c/$*".{c,h}
- mv "$*.o" "bin/c/$*.o"
-bin/c/%: c/%.c
- $(CC) $(C_FLAGS) -o "$@" "c/$*".c "bin/c/"*.o
-c-so: bin/c/sha3.$(LIB_EXT)
-bin/c/sha3.$(LIB_EXT): bin/c/sha3.o
- $(CC) $(SO_FLAGS) $^ -o "$@"
-
-
-.PHONY: java-c-jni java-c-jni-so java-c-jni-jar
-java-c-jni: bin/java-c-jni/SHA3.$(LIB_EXT) $(JNI_CLASSES)
-bin/java-c-jni/%.class: java-c-jni/%.java
- mkdir -p "bin/java-c-jni"
- $(JAVAC) $(JNI_JAVA_FLAGS) "java-c-jni/$*.java"
-java-c-jni/%.h: bin/java-c-jni/%.class
- $(JAVAH) -classpath bin/java-c-jni -jni -d java-c-jni \
- $$(echo "$<" | sed -e 's:^bin/java-c-jni/::' -e 's:.class$$::' | sed -e 's:/:.:g')
-java-c-jni-so: bin/java-c-jni/SHA3.$(LIB_EXT)
-bin/java-c-jni/%.$(LIB_EXT): java-c-jni/%.h java-c-jni/%.c
- mkdir -p "bin/java-c-jni"
- $(CC) $(C_FLAGS) $(JNI_C_FLAGS) "java-c-jni/$*.c" -o "$@"
-java-c-jni-jar: bin/java-c-jni/sha3.jar
-bin/java-c-jni/sha3.jar: bin/java-c-jni/SHA3.class
- cd bin/java; $(JAR) cf sha3.jar SHA3.class
-
-
.PHONY: clean
clean:
- -rm java-c-jni/*.h
-rm -r bin obj
diff --git a/README.md b/README.md
deleted file mode 100644
index 2b1bec6..0000000
--- a/README.md
+++ /dev/null
@@ -1,90 +0,0 @@
-COMPLETE STATUS:
-
- Java 1.2+ :: optimised
- Python 3 :: optimised
- Python 2 :: optimised for Python 3
- C ISO C90 :: optimised
- Java/C JNI :: optimised
- NASM :: planned (maybe)
- Python 3 + C :: planned (maybe)
- Haskell :: planned (maybe)
- Perl :: planned (maybe)
- D :: planned (maybe)
- Common Lisp :: planned (perhaps)
- Scala :: planned (perhaps)
- Magic :: planned (perhaps)
- Vala :: maybe in the future
-
-
-PERFORMANCE COMPARISON:
-
- C ISO C90 :: 0,082s ~ 1
- Java/C JNI :: 0,175s ~ 2,13
- Java 1.2+ :: 0,228s ~ 2,78
- Python 3 :: 24,373s ~ 297
- Python 2 :: 34,595s ~ 422
-
- md5sum :: 0,009s ~ 0,110
- sha1sum :: 0,013s ~ 0,159
- sha384sum :: 0,015s ~ 0,183
- sha512sum :: 0,015s ~ 0,183
- sha224sum :: 0,020s ~ 0,244
- sha256sum :: 0,021s ~ 0,256
- md6sum :: 0,165s ~ 2,01
-
- Based on test against a 2,3 MB file.
-
-
-**SHA-3/Keccak checksum calculator**
-
-*USAGE:*
-
- sha3sum [option...] < FILE
- sha3sum [option...] file...
-
-*OPTIONS:*
-
- -r BITRATE
- --bitrate The bitrate to use for checksum. (default: 1024)
-
- -c CAPACITY
- --capacity The capacity to use for checksum. (default: 576)
-
- -w WORDSIZE
- --wordsize The word size to use for checksum. (default: 64)
-
- -o OUTPUTSIZE
- --outputsize The output size to use for checksum. (default: 512)
-
- -s STATESIZE
- --statesize The state size to use for checksum. (default: 1600)
-
- -i ITERATIONS
- --iterations The number of hash iterations to run. (default: 1)
-
- -j SQUEEZES
- --squeezes The number of hash squeezes to run. (default: 1)
-
- -x
- --hex Read the input in hexadecimal, rather than binary.
-
- -b
- --binary Print the checksum in binary, rather than hexadecimal.
-
- -m
- --multi Print the checksum at all iterations.
-
-
-**Pending the standardisation of SHA-3**, there is no specification of particular
-SHA-3 functions yet. Our defaults are based on Keccak[] being Keccak[r = 1024, c = 576]
-rather than the functions in Wikipedia's entires that uses [r = 576, c = 1024].
-No release will made until SHA-3 has been standardise, this is to prevent the
-program to change behaviour caused by mismatch with standardisation.
-
-
-If you want to contribute with an implementation in another
-language, please try do so in the earliest version of the
-language officially supported on GNU/Linux, unless there are
-backwards incompatibilities (as is the case with Python.)
-This helps for embedded devices.
-
diff --git a/c/sha3.c b/c/sha3.c
deleted file mode 100644
index 50ba85b..0000000
--- a/c/sha3.c
+++ /dev/null
@@ -1,905 +0,0 @@
-/**
- * sha3sum – SHA-3 (Keccak) checksum calculator
- *
- * Copyright © 2013, 2014 Mattias Andrée (maandree@member.fsf.org)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-#include "sha3.h"
-
-#include <string.h>
-
-
-#ifdef WITH_C99
- #define static_inline static inline
-#else
- #define static_inline inline
-#endif
-
-#ifdef WITH_THREADLOCAL
- #define threadlocal __thread
- /* This is compiler dependent, if your compiler does
- * not support this you need to define __thread yourself. */
-#else
- #define threadlocal /* no threading support */
-#endif
-
-#define null 0
-#define true 1
-#define false 0
-
-
-
-/**
- * Round contants
- */
-#ifdef WITH_C99
-static const llong RC[] = {
- 0x0000000000000001LL, 0x0000000000008082LL, 0x800000000000808ALL, 0x8000000080008000LL,
- 0x000000000000808BLL, 0x0000000080000001LL, 0x8000000080008081LL, 0x8000000000008009LL,
- 0x000000000000008ALL, 0x0000000000000088LL, 0x0000000080008009LL, 0x000000008000000ALL,
- 0x000000008000808BLL, 0x800000000000008BLL, 0x8000000000008089LL, 0x8000000000008003LL,
- 0x8000000000008002LL, 0x8000000000000080LL, 0x000000000000800ALL, 0x800000008000000ALL,
- 0x8000000080008081LL, 0x8000000000008080LL, 0x0000000080000001LL, 0x8000000080008008LL};
-#else
-static const llong RC[] = {
- 0x0000000000000001L, 0x0000000000008082L, 0x800000000000808AL, 0x8000000080008000L,
- 0x000000000000808BL, 0x0000000080000001L, 0x8000000080008081L, 0x8000000000008009L,
- 0x000000000000008AL, 0x0000000000000088L, 0x0000000080008009L, 0x000000008000000AL,
- 0x000000008000808BL, 0x800000000000008BL, 0x8000000000008089L, 0x8000000000008003L,
- 0x8000000000008002L, 0x8000000000000080L, 0x000000000000800AL, 0x800000008000000AL,
- 0x8000000080008081L, 0x8000000000008080L, 0x0000000080000001L, 0x8000000080008008L};
-#endif
-
-/**
- * Keccak-f round temporary
- */
-static threadlocal llong B[25];
-
-/**
- * Keccak-f round temporary
- */
-static threadlocal llong C[5];
-
-
-/**
- * The bitrate
- */
-static threadlocal long r = 0;
-
-/**
- * The capacity
- */
-static threadlocal long c = 0;
-
-/**
- * The output size
- */
-static threadlocal long n = 0;
-
-/**
- * The state size
- */
-static threadlocal long b = 0;
-
-/**
- * The word size
- */
-static threadlocal long w = 0;
-
-/**
- * The word mask
- */
-static threadlocal llong wmod = 0;
-
-/**
- * ℓ, the binary logarithm of the word size
- */
-static threadlocal long l = 0;
-
-/**
- * 12 + 2ℓ, the number of rounds
- */
-static threadlocal long nr = 0;
-
-
-/**
- * The current state
- */
-static threadlocal llong* S = null;
-
-/**
- * Left over water to fill the sponge with at next update
- */
-static threadlocal byte* M = null;
-
-/**
- * Pointer for {@link #M}
- */
-static threadlocal long mptr = 0;
-
-/**
- * Size of {@link #M}
- */
-static threadlocal long mlen = 0;
-
-
-
-/**
- * Gets the smallest, in value, of the arguments
- *
- * @param X The first candidate
- * @param Y The second candidate
- * @return The lowest candidate
- */
-#define min(X, Y) ((X) < (Y) ? (X) : (Y))
-
-
-
-/**
- * Copy an array segment into an array in start to end order
- *
- * @param src The source array
- * @param soff The source array offset
- * @param dest The destination array
- * @param doff The destination array offset
- * @param length The number of elements to copy
- */
-static_inline void sha3_arraycopy(byte* src, long soff, byte* dest, long doff, long length)
-{
- long i;
- src += soff;
- dest += doff;
-
- #define __(X) dest[X] = src[X]
- #define __0 *dest = *src
- #define __1 __(0x01)
- #define __2 __(0x02); __(0x03)
- #define __3 __(0x04); __(0x05); __(0x06); __(0x07)
- #define __4 __(0x08); __(0x09); __(0x0A); __(0x0B); __(0x0C); __(0x0D); __(0x0E); __(0x0F)
- #define __5 __(0x10); __(0x11); __(0x12); __(0x13); __(0x14); __(0x15); __(0x16); __(0x17); __(0x18); __(0x19); __(0x1A); __(0x1B); __(0x1C); __(0x1D); __(0x1E); __(0x1F)
- #define __6 __(0x20); __(0x21); __(0x22); __(0x23); __(0x24); __(0x25); __(0x26); __(0x27); __(0x28); __(0x29); __(0x2A); __(0x2B); __(0x2C); __(0x2D); __(0x2E); __(0x2F); \
- __(0x30); __(0x31); __(0x32); __(0x33); __(0x34); __(0x35); __(0x36); __(0x37); __(0x38); __(0x39); __(0x3A); __(0x3B); __(0x3C); __(0x3D); __(0x3E); __(0x3F)
- #define __7 __(0x40); __(0x41); __(0x42); __(0x43); __(0x44); __(0x45); __(0x46); __(0x47); __(0x48); __(0x49); __(0x4A); __(0x4B); __(0x4C); __(0x4D); __(0x4E); __(0x4F); \
- __(0x50); __(0x51); __(0x52); __(0x53); __(0x54); __(0x55); __(0x56); __(0x57); __(0x58); __(0x59); __(0x5A); __(0x5B); __(0x5C); __(0x5D); __(0x5E); __(0x5F); \
- __(0x60); __(0x61); __(0x62); __(0x63); __(0x64); __(0x65); __(0x66); __(0x67); __(0x68); __(0x69); __(0x6A); __(0x6B); __(0x6C); __(0x6D); __(0x6E); __(0x6F); \
- __(0x70); __(0x71); __(0x72); __(0x73); __(0x74); __(0x75); __(0x76); __(0x77); __(0x78); __(0x79); __(0x7A); __(0x7B); __(0x7C); __(0x7D); __(0x7E); __(0x7F)
- #define __8 __(0x80); __(0x81); __(0x82); __(0x83); __(0x84); __(0x85); __(0x86); __(0x87); __(0x88); __(0x89); __(0x8A); __(0x8B); __(0x8C); __(0x8D); __(0x8E); __(0x8F); \
- __(0x90); __(0x91); __(0x92); __(0x93); __(0x94); __(0x95); __(0x96); __(0x97); __(0x98); __(0x99); __(0x9A); __(0x9B); __(0x9C); __(0x9D); __(0x9E); __(0x9F); \
- __(0xA0); __(0xA1); __(0xA2); __(0xA3); __(0xA4); __(0xA5); __(0xA6); __(0xA7); __(0xA8); __(0xA9); __(0xAA); __(0xAB); __(0xAC); __(0xAD); __(0xAE); __(0xAF); \
- __(0xB0); __(0xB1); __(0xB2); __(0xB3); __(0xB4); __(0xB5); __(0xB6); __(0xB7); __(0xB8); __(0xB9); __(0xBA); __(0xBB); __(0xBC); __(0xBD); __(0xBE); __(0xBF); \
- __(0xC0); __(0xC1); __(0xC2); __(0xC3); __(0xC4); __(0xC5); __(0xC6); __(0xC7); __(0xC8); __(0xC9); __(0xCA); __(0xCB); __(0xCC); __(0xCD); __(0xCE); __(0xCF); \
- __(0xD0); __(0xD1); __(0xD2); __(0xD3); __(0xD4); __(0xD5); __(0xD6); __(0xD7); __(0xD8); __(0xD9); __(0xDA); __(0xDB); __(0xDC); __(0xDD); __(0xDE); __(0xDF); \
- __(0xE0); __(0xE1); __(0xE2); __(0xE3); __(0xE4); __(0xE5); __(0xE6); __(0xE7); __(0xE8); __(0xE9); __(0xEA); __(0xEB); __(0xEC); __(0xED); __(0xEE); __(0xEF); \
- __(0xF0); __(0xF1); __(0xF2); __(0xF3); __(0xF4); __(0xF5); __(0xF6); __(0xF7); __(0xF8); __(0xF9); __(0xFA); __(0xFB); __(0xFC); __(0xFD); __(0xFE); __(0xFF)
-
- if ((length & 15))
- {
- if ((length & 1)) { __0; src += 1; dest += 1; }
- if ((length & 2)) { __0; __1; src += 2; dest += 2; }
- if ((length & 4)) { __0; __1; __2; src += 4; dest += 4; }
- if ((length & 8)) { __0; __1; __2; __3; src += 8; dest += 8; }
- }
- if ((length & 240))
- {
- if ((length & 16)) { __0; __1; __2; __3; __4; src += 16; dest += 16; }
- if ((length & 32)) { __0; __1; __2; __3; __4; __5; src += 32; dest += 32; }
- if ((length & 64)) { __0; __1; __2; __3; __4; __5; __6; src += 64; dest += 64; }
- if ((length & 128)) { __0; __1; __2; __3; __4; __5; __6; __7; src += 128; dest += 128; }
- }
- length &= ~255;
- for (i = 0; i < length; i += 256)
- {
- __0; __1; __2; __3; __4; __5; __6; __7; __8; src += 256; dest += 256;
- }
-
- #undef __8
- #undef __7
- #undef __6
- #undef __5
- #undef __4
- #undef __3
- #undef __2
- #undef __1
- #undef __0
- #undef __
-}
-
-
-/**
- * Copy an array segment into an array in end to start order
- *
- * @param src The source array
- * @param soff The source array offset
- * @param dest The destination array
- * @param doff The destination array offset
- * @param length The number of elements to copy
- */
-static_inline void sha3_revarraycopy(byte* src, long soff, byte* dest, long doff, long length)
-{
- long copyi;
- for (copyi = length - 1; copyi >= 0; copyi--)
- dest[copyi + doff] = src[copyi + soff];
-}
-
-
-/**
- * Rotate a word
- *
- * @param X:llong The value to rotate
- * @param N:long Rotation steps, may not be 0
- * @return :llong The value rotated
- */
-#define rotate(X, N) ((((X) >> (w - ((N) % w))) + ((X) << ((N) % w))) & wmod)
-
-
-/**
- * Rotate a 64-bit word
- *
- * @param X:llong The value to rotate
- * @param N:long Rotation steps, may not be 0
- * @return :llong The value rotated
- */
-#define rotate64(X, N) ((llong)((ullong)(X) >> (64 - (N))) + ((X) << (N)))
-
-
-/**
- * Binary logarithm
- *
- * @param x The value of which to calculate the binary logarithm
- * @return The binary logarithm
- */
-static_inline long sha3_lb(long x)
-{
- long rc = 0;
- if ((x & 0xFF00) != 0) { rc += 8; x >>= 8; }
- if ((x & 0x00F0) != 0) { rc += 4; x >>= 4; }
- if ((x & 0x000C) != 0) { rc += 2; x >>= 2; }
- if ((x & 0x0002) != 0) rc += 1;
- return rc;
-}
-
-
-/**
- * Perform one round of computation
- *
- * @param A The current state
- * @param rc Round constant
- */
-static void sha3_keccakFRound(llong* restrict_ A, llong rc)
-{
- llong da, db, dc, dd, de;
-
- /* θ step (step 1 and 2 of 3) */
- #define __C(I, J0, J1, J2, J3, J4) C[I] = (A[J0] ^ A[J1]) ^ (A[J2] ^ A[J3]) ^ A[J4]
- __C(0, 0, 1, 2, 3, 4);
- __C(1, 5, 6, 7, 8, 9);
- __C(2, 10, 11, 12, 13, 14);
- __C(3, 15, 16, 17, 18, 19);
- __C(4, 20, 21, 22, 23, 24);
- #undef __C
-
- if (w == 64)
- {
- da = C[4] ^ rotate64(C[1], 1);
- dd = C[2] ^ rotate64(C[4], 1);
- db = C[0] ^ rotate64(C[2], 1);
- de = C[3] ^ rotate64(C[0], 1);
- dc = C[1] ^ rotate64(C[3], 1);
-
- /* ρ and π steps, with last two part of θ */
- #define __B(Bi, Ai, Dv, R) B[Bi] = rotate64(A[Ai] ^ Dv, R)
- B[0] = A[0] ^ da; __B( 1, 15, dd, 28); __B( 2, 5, db, 1); __B( 3, 20, de, 27); __B( 4, 10, dc, 62);
- __B( 5, 6, db, 44); __B( 6, 21, de, 20); __B( 7, 11, dc, 6); __B( 8, 1, da, 36); __B( 9, 16, dd, 55);
- __B(10, 12, dc, 43); __B(11, 2, da, 3); __B(12, 17, dd, 25); __B(13, 7, db, 10); __B(14, 22, de, 39);
- __B(15, 18, dd, 21); __B(16, 8, db, 45); __B(17, 23, de, 8); __B(18, 13, dc, 15); __B(19, 3, da, 41);
- __B(20, 24, de, 14); __B(21, 14, dc, 61); __B(22, 4, da, 18); __B(23, 19, dd, 56); __B(24, 9, db, 2);
- #undef __B
- }
- else
- {
- da = C[4] ^ rotate(C[1], 1);
- dd = C[2] ^ rotate(C[4], 1);
- db = C[0] ^ rotate(C[2], 1);
- de = C[3] ^ rotate(C[0], 1);
- dc = C[1] ^ rotate(C[3], 1);
-
- /* ρ and π steps, with last two part of θ */
- #define __B(Bi, Ai, Dv, R) B[Bi] = rotate(A[Ai] ^ Dv, R)
- B[0] = A[0] ^ da; __B( 1, 15, dd, 28); __B( 2, 5, db, 1); __B( 3, 20, de, 27); __B( 4, 10, dc, 62);
- __B( 5, 6, db, 44); __B( 6, 21, de, 20); __B( 7, 11, dc, 6); __B( 8, 1, da, 36); __B( 9, 16, dd, 55);
- __B(10, 12, dc, 43); __B(11, 2, da, 3); __B(12, 17, dd, 25); __B(13, 7, db, 10); __B(14, 22, de, 39);
- __B(15, 18, dd, 21); __B(16, 8, db, 45); __B(17, 23, de, 8); __B(18, 13, dc, 15); __B(19, 3, da, 41);
- __B(20, 24, de, 14); __B(21, 14, dc, 61); __B(22, 4, da, 18); __B(23, 19, dd, 56); __B(24, 9, db, 2);
- #undef __B
- }
-
- /* ξ step */
- #define __A(X, X5, X10) A[X] = B[X] ^ ((~(B[X5])) & B[X10])
- __A( 0, 5, 10); __A( 1, 6, 11); __A( 2, 7, 12); __A( 3, 8, 13); __A( 4, 9, 14);
- __A( 5, 10, 15); __A( 6, 11, 16); __A( 7, 12, 17); __A( 8, 13, 18); __A( 9, 14, 19);
- __A(10, 15, 20); __A(11, 16, 21); __A(12, 17, 22); __A(13, 18, 23); __A(14, 19, 24);
- __A(15, 20, 0); __A(16, 21, 1); __A(17, 22, 2); __A(18, 23, 3); __A(19, 24, 4);
- __A(20, 0, 5); __A(21, 1, 6); __A(22, 2, 7); __A(23, 3, 8); __A(24, 4, 9);
- #undef __A
-
- /* ι step */
- A[0] ^= rc;
-}
-
-
-/**
- * Perform Keccak-f function
- *
- * @param A The current state
- */
-static void sha3_keccakF(llong* restrict_ A)
-{
- long i;
- if (nr == 24)
- {
- sha3_keccakFRound(A, 0x0000000000000001);
- sha3_keccakFRound(A, 0x0000000000008082);
- sha3_keccakFRound(A, 0x800000000000808A);
- sha3_keccakFRound(A, 0x8000000080008000);
- sha3_keccakFRound(A, 0x000000000000808B);
- sha3_keccakFRound(A, 0x0000000080000001);
- sha3_keccakFRound(A, 0x8000000080008081);
- sha3_keccakFRound(A, 0x8000000000008009);
- sha3_keccakFRound(A, 0x000000000000008A);
- sha3_keccakFRound(A, 0x0000000000000088);
- sha3_keccakFRound(A, 0x0000000080008009);
- sha3_keccakFRound(A, 0x000000008000000A);
- sha3_keccakFRound(A, 0x000000008000808B);
- sha3_keccakFRound(A, 0x800000000000008B);
- sha3_keccakFRound(A, 0x8000000000008089);
- sha3_keccakFRound(A, 0x8000000000008003);
- sha3_keccakFRound(A, 0x8000000000008002);
- sha3_keccakFRound(A, 0x8000000000000080);
- sha3_keccakFRound(A, 0x000000000000800A);
- sha3_keccakFRound(A, 0x800000008000000A);
- sha3_keccakFRound(A, 0x8000000080008081);
- sha3_keccakFRound(A, 0x8000000000008080);
- sha3_keccakFRound(A, 0x0000000080000001);
- sha3_keccakFRound(A, 0x8000000080008008);
- }
- else
- for (i = 0; i < nr; i++)
- sha3_keccakFRound(A, RC[i] & wmod);
-}
-
-
-/**
- * Convert a chunk of byte:s to a word
- *
- * @param message The message
- * @param msglen The length of the message
- * @param rr Bitrate in bytes
- * @param ww Word size in bytes
- * @param off The offset in the message
- * @return Lane
- */
-static_inline llong sha3_toLane(byte* restrict_ message, long msglen, long rr, long ww, long off)
-{
- llong rc = 0;
- long n = min(msglen, rr), i;
- for (i = off + ww - 1; i >= off; i--)
- rc = (rc << 8) | ((i < n) ? (llong)(message[i] & 255) : 0L);
- return rc;
-}
-
-
-/**
- * Convert a chunk of byte:s to a 64-bit word
- *
- * @param message The message
- * @param msglen The length of the message
- * @param rr Bitrate in bytes
- * @param off The offset in the message
- * @return Lane
- */
-static_inline llong sha3_toLane64(byte* restrict_ message, long msglen, long rr, long off)
-{
- long n = min(msglen, rr);
- return ((off + 7 < n) ? ((llong)(message[off + 7] & 255) << 56) : 0L) |
- ((off + 6 < n) ? ((llong)(message[off + 6] & 255) << 48) : 0L) |
- ((off + 5 < n) ? ((llong)(message[off + 5] & 255) << 40) : 0L) |
- ((off + 4 < n) ? ((llong)(message[off + 4] & 255) << 32) : 0L) |
- ((off + 3 < n) ? ((llong)(message[off + 3] & 255) << 24) : 0L) |
- ((off + 2 < n) ? ((llong)(message[off + 2] & 255) << 16) : 0L) |
- ((off + 1 < n) ? ((llong)(message[off + 1] & 255) << 8) : 0L) |
- ((off < n) ? ((llong)(message[off ] & 255) ) : 0L);
-}
-
-
-/**
- * pad 10*1
- *
- * @param msg The message to pad
- * @param len The length of the message
- * @param r The bitrate
- * @param bits The number of bits in the end of the message that does not make a whole byte
- * @param outlen The length of the padded message (out parameter)
- * @return The message padded
- */
-static_inline byte* sha3_pad10star1(byte* restrict_ msg, long len, long r, long bits, long* restrict_ outlen)
-{
- byte* message;
- byte b;
- long i, ll, nbrf, nrf;
-
- len = ((len - (bits + 7) / 8) << 3) + bits;
- nrf = len >> 3;
- nbrf = len & 7;
- ll = len % r;
-
- b = (byte)(nbrf == 0 ? 1 : (msg[nrf] | (1 << nbrf)));
-
- if ((r - 8 <= ll) && (ll <= r - 2))
- {
- message = (byte*)malloc((len = nrf + 1) * sizeof(byte));
- message[nrf] = (byte)(b ^ 128);
- }
- else
- {
- byte* M;
- long N;
- len = (nrf + 1) << 3;
- len = ((len - (len % r) + (r - 8)) >> 3) + 1;
- message = (byte*)malloc(len * sizeof(byte));
- message[nrf] = b;
- N = len - nrf - 1;
- M = message + nrf + 1;
-
- #define __(X) M[X] = 0
- #define __0 *M = 0
- #define __1 __(0x01)
- #define __2 __(0x02); __(0x03)
- #define __3 __(0x04); __(0x05); __(0x06); __(0x07)
- #define __4 __(0x08); __(0x09); __(0x0A); __(0x0B); __(0x0C); __(0x0D); __(0x0E); __(0x0F)
- #define __5 __(0x10); __(0x11); __(0x12); __(0x13); __(0x14); __(0x15); __(0x16); __(0x17); __(0x18); __(0x19); __(0x1A); __(0x1B); __(0x1C); __(0x1D); __(0x1E); __(0x1F)
- #define __6 __(0x20); __(0x21); __(0x22); __(0x23); __(0x24); __(0x25); __(0x26); __(0x27); __(0x28); __(0x29); __(0x2A); __(0x2B); __(0x2C); __(0x2D); __(0x2E); __(0x2F); \
- __(0x30); __(0x31); __(0x32); __(0x33); __(0x34); __(0x35); __(0x36); __(0x37); __(0x38); __(0x39); __(0x3A); __(0x3B); __(0x3C); __(0x3D); __(0x3E); __(0x3F)
- #define __7 __(0x40); __(0x41); __(0x42); __(0x43); __(0x44); __(0x45); __(0x46); __(0x47); __(0x48); __(0x49); __(0x4A); __(0x4B); __(0x4C); __(0x4D); __(0x4E); __(0x4F); \
- __(0x50); __(0x51); __(0x52); __(0x53); __(0x54); __(0x55); __(0x56); __(0x57); __(0x58); __(0x59); __(0x5A); __(0x5B); __(0x5C); __(0x5D); __(0x5E); __(0x5F); \
- __(0x60); __(0x61); __(0x62); __(0x63); __(0x64); __(0x65); __(0x66); __(0x67); __(0x68); __(0x69); __(0x6A); __(0x6B); __(0x6C); __(0x6D); __(0x6E); __(0x6F); \
- __(0x70); __(0x71); __(0x72); __(0x73); __(0x74); __(0x75); __(0x76); __(0x77); __(0x78); __(0x79); __(0x7A); __(0x7B); __(0x7C); __(0x7D); __(0x7E); __(0x7F)
- #define __8 __(0x80); __(0x81); __(0x82); __(0x83); __(0x84); __(0x85); __(0x86); __(0x87); __(0x88); __(0x89); __(0x8A); __(0x8B); __(0x8C); __(0x8D); __(0x8E); __(0x8F); \
- __(0x90); __(0x91); __(0x92); __(0x93); __(0x94); __(0x95); __(0x96); __(0x97); __(0x98); __(0x99); __(0x9A); __(0x9B); __(0x9C); __(0x9D); __(0x9E); __(0x9F); \
- __(0xA0); __(0xA1); __(0xA2); __(0xA3); __(0xA4); __(0xA5); __(0xA6); __(0xA7); __(0xA8); __(0xA9); __(0xAA); __(0xAB); __(0xAC); __(0xAD); __(0xAE); __(0xAF); \
- __(0xB0); __(0xB1); __(0xB2); __(0xB3); __(0xB4); __(0xB5); __(0xB6); __(0xB7); __(0xB8); __(0xB9); __(0xBA); __(0xBB); __(0xBC); __(0xBD); __(0xBE); __(0xBF); \
- __(0xC0); __(0xC1); __(0xC2); __(0xC3); __(0xC4); __(0xC5); __(0xC6); __(0xC7); __(0xC8); __(0xC9); __(0xCA); __(0xCB); __(0xCC); __(0xCD); __(0xCE); __(0xCF); \
- __(0xD0); __(0xD1); __(0xD2); __(0xD3); __(0xD4); __(0xD5); __(0xD6); __(0xD7); __(0xD8); __(0xD9); __(0xDA); __(0xDB); __(0xDC); __(0xDD); __(0xDE); __(0xDF); \
- __(0xE0); __(0xE1); __(0xE2); __(0xE3); __(0xE4); __(0xE5); __(0xE6); __(0xE7); __(0xE8); __(0xE9); __(0xEA); __(0xEB); __(0xEC); __(0xED); __(0xEE); __(0xEF); \
- __(0xF0); __(0xF1); __(0xF2); __(0xF3); __(0xF4); __(0xF5); __(0xF6); __(0xF7); __(0xF8); __(0xF9); __(0xFA); __(0xFB); __(0xFC); __(0xFD); __(0xFE); __(0xFF)
-
- if ((N & 15))
- {
- if ((N & 1)) { __0; M += 1; }
- if ((N & 2)) { __0; __1; M += 2; }
- if ((N & 4)) { __0; __1; __2; M += 4; }
- if ((N & 8)) { __0; __1; __2; __3; M += 8; }
- }
- if ((N & 240))
- {
- if ((N & 16)) { __0; __1; __2; __3; __4; M += 16; }
- if ((N & 32)) { __0; __1; __2; __3; __4; __5; M += 32; }
- if ((N & 64)) { __0; __1; __2; __3; __4; __5; __6; M += 64; }
- if ((N & 128)) { __0; __1; __2; __3; __4; __5; __6; __7; M += 128; }
- }
- N &= ~255;
- for (i = 0; i < N; i += 256)
- {
- __0; __1; __2; __3; __4; __5; __6; __7; __8; M += 256;
- }
-
- #undef __8
- #undef __7
- #undef __6
- #undef __5
- #undef __4
- #undef __3
- #undef __2
- #undef __1
- #undef __0
- #undef __
-
- message[len - 1] = -128;
- }
- sha3_arraycopy(msg, 0, message, 0, nrf);
-
- *outlen = len;
- return message;
-}
-
-
-/**
- * Initialise Keccak sponge
- *
- * @param bitrate The bitrate
- * @param capacity The capacity
- * @param output The output size
- */
-void sha3_initialise(long bitrate, long capacity, long output)
-{
- long i;
-
- r = bitrate;
- n = output;
- c = capacity;
- b = r + c;
- w = b / 25;
- l = sha3_lb(w);
- nr = 12 + (l << 1);
- if (w == 64)
- wmod = -1;
- else
- {
- wmod = 1;
- wmod <<= w;
- wmod--;
- }
- S = (llong*)malloc(25 * sizeof(llong));
- M = (byte*)malloc((mlen = (r * b) >> 2) * sizeof(byte));
- mptr = 0;
-
- for (i = 0; i < 25; i++)
- *(S + i) = 0;
-}
-
-/**
- * Dispose of the Keccak sponge
- */
-void sha3_dispose()
-{
- #ifdef WITH_WIPE
- long i;
- #endif
- if (S != null)
- {
- #ifdef WITH_WIPE
- for (i = 0; i < 25; i++)
- *(S + i) = 0;
- #endif
- free(S);
- S = null;
- }
- if (M != null)
- {
- #ifdef WITH_WIPE
- for (i = 0; i < mlen; i++)
- *(M + i) = 0;
- #endif
- free(M);
- M = null;
- }
-}
-
-/**
- * Absorb the more of the message to the Keccak sponge
- *
- * @param msg The partial message
- * @param msglen The length of the partial message
- */
-void sha3_update(byte* restrict_ msg, long msglen)
-{
- long rr = r >> 3;
- long ww = w >> 3;
- long i, len;
- byte* message;
- byte* _msg;
- long nnn;
-
- if (mptr + msglen > mlen)
- #ifndef WITH_WIPE
- M = (byte*)realloc(M, mlen = (mlen + msglen) << 1);
- #else
- {
- long mlen_ = mlen;
- char* M_ = (byte*)malloc(mlen = (mlen + msglen) << 1);
- sha3_arraycopy(M, 0, M_, 0, mlen_);
- for (i = 0; i < mlen_; i++)
- *(M + i) = 0;
- free(M);
- M = M_;
- }
- #endif
- sha3_arraycopy(msg, 0, M, mptr, msglen);
- len = mptr += msglen;
- len -= len % ((r * b) >> 3);
- message = (byte*)malloc(len * sizeof(byte));
- sha3_arraycopy(M, 0, message, 0, len);
- mptr -= len;
- sha3_revarraycopy(M, nnn = len, M, 0, mptr);
- _msg = message;
-
- /* Absorbing phase */
- if (ww == 8)
- for (i = 0; i < nnn; i += rr)
- {
- #define __S(Si, OFF) S[Si] ^= sha3_toLane64(message, len, rr, OFF)
- __S( 0, 0); __S( 5, 8); __S(10, 16); __S(15, 24); __S(20, 32);
- __S( 1, 40); __S( 6, 48); __S(11, 56); __S(16, 64); __S(21, 72);
- __S( 2, 80); __S( 7, 88); __S(12, 96); __S(17, 104); __S(22, 112);
- __S( 3, 120); __S( 8, 128); __S(13, 136); __S(18, 144); __S(23, 152);
- __S( 4, 160); __S( 9, 168); __S(14, 176); __S(19, 184); __S(24, 192);
- #undef __S
- sha3_keccakF(S);
- message += rr;
- len -= rr;
- }
- else
- for (i = 0; i < nnn; i += rr)
- {
- #define __S(Si, OFF) S[Si] ^= sha3_toLane(message, len, rr, ww, OFF * ww)
- __S( 0, 0); __S( 5, 1); __S(10, 2); __S(15, 3); __S(20, 4);
- __S( 1, 5); __S( 6, 6); __S(11, 7); __S(16, 8); __S(21, 9);
- __S( 2, 10); __S( 7, 11); __S(12, 12); __S(17, 13); __S(22, 14);
- __S( 3, 15); __S( 8, 16); __S(13, 17); __S(18, 18); __S(23, 19);
- __S( 4, 20); __S( 9, 21); __S(14, 22); __S(19, 23); __S(24, 24);
- #undef __S
- sha3_keccakF(S);
- message += rr;
- len -= rr;
- }
-
- #ifdef WITH_WIPE
- for (i = 0; i < nnn; i++)
- *(_msg + i) = 0;
- #endif
- free(_msg);
-}
-
-
-/**
- * Absorb the last part of the message and squeeze the Keccak sponge
- *
- * @param msg The rest of the message, may be {@code null}
- * @param msglen The length of the partial message
- * @param bits The number of bits at the end of the message not covered by `msglen`
- * @param suffix The suffix concatenate to the message
- * @param withReturn Whether to return the hash instead of just do a quick squeeze phrase and return {@code null}
- * @return The hash sum, or {@code null} if <tt>withReturn</tt> is {@code false}
- */
-byte* sha3_digest(byte* restrict_ msg, long msglen, long bits, char* restrict_ suffix, boolean withReturn)
-{
- byte* message;
- byte* _msg;
- byte* rc;
- long rr = r >> 3, len;
- long nn = (n + 7) >> 3, olen;
- long ww = w >> 3, ni;
- long i, j = 0, ptr = 0, _;
- long nnn;
- long suffix_len = strlen(suffix);
-
- if (msg == null)
- msglen = bits = 0;
-
- msglen += bits >> 3;
- if ((bits &= 7))
- msg[msglen] &= (1 << bits) - 1;
- if (suffix_len)
- {
- #ifndef WITH_WIPE
- msg = (byte*)realloc(msg, msglen + ((suffix_len + bits + 7) >> 3));
- #else
- {
- char* old_msg = msg;
- msg = (byte*)malloc(msglen + ((suffix_len + bits + 7) >> 3));
- memcpy(msg, old_msg, msglen + !!bits);
- for (i = 0; i < msglen + !!bits; i++)
- *(old_msg + i) = 0;
- free(old_msg);
- }
- #endif
- if (!bits)
- msg[msglen] = 0;
- for (i = 0; i < suffix_len; i++)
- {
- msg[msglen] |= (suffix[i] - '0') << bits++;
- if (bits == 8)
- {
- bits = 0;
- msglen++;
- msg[msglen] = 0;
- }
- }
- }
- if (bits)
- msglen++;
-
- if (mptr + msglen > mlen)
- #ifndef WITH_WIPE
- M = (byte*)realloc(M, mlen += msglen);
- #else
- {
- long mlen_ = mlen;
- char* M_ = (byte*)malloc(mlen += msglen);
- sha3_arraycopy(M, 0, M_, 0, mlen_);
- for (i = 0; i < mlen_; i++)
- *(M + i) = 0;
- free(M);
- M = M_;
- }
- #endif
- sha3_arraycopy(msg, 0, M, mptr, msglen);
- message = sha3_pad10star1(M, mptr + msglen, r, bits, &len);
-
- #ifdef WITH_WIPE
- for (i = 0; i < mlen; i++)
- *(M + i) = 0;
- #endif
- free(M);
- M = null;
- rc = withReturn ? (byte*)malloc(((n + 7) >> 3) * sizeof(byte)) : null;
- _msg = message;
- nnn = len;
-
- /* Absorbing phase */
- if (ww == 8)
- for (i = 0; i < nnn; i += rr)
- {
- #define __S(Si, OFF) S[Si] ^= sha3_toLane64(message, len, rr, OFF)
- __S( 0, 0); __S( 5, 8); __S(10, 16); __S(15, 24); __S(20, 32);
- __S( 1, 40); __S( 6, 48); __S(11, 56); __S(16, 64); __S(21, 72);
- __S( 2, 80); __S( 7, 88); __S(12, 96); __S(17, 104); __S(22, 112);
- __S( 3, 120); __S( 8, 128); __S(13, 136); __S(18, 144); __S(23, 152);
- __S( 4, 160); __S( 9, 168); __S(14, 176); __S(19, 184); __S(24, 192);
- #undef __S
- sha3_keccakF(S);
- message += rr;
- len -= rr;
- }
- else
- for (i = 0; i < nnn; i += rr)
- {
- #define __S(Si, OFF) S[Si] ^= sha3_toLane(message, len, rr, ww, OFF * ww)
- __S( 0, 0); __S( 5, 1); __S(10, 2); __S(15, 3); __S(20, 4);
- __S( 1, 5); __S( 6, 6); __S(11, 7); __S(16, 8); __S(21, 9);
- __S( 2, 10); __S( 7, 11); __S(12, 12); __S(17, 13); __S(22, 14);
- __S( 3, 15); __S( 8, 16); __S(13, 17); __S(18, 18); __S(23, 19);
- __S( 4, 20); __S( 9, 21); __S(14, 22); __S(19, 23); __S(24, 24);
- #undef __S
- sha3_keccakF(S);
- message += rr;
- len -= rr;
- }
-
- #ifdef WITH_WIPE
- for (i = 0; i < nnn; i++)
- *(_msg + i) = 0;
- #endif
- free(_msg);
-
- /* Squeezing phase */
- olen = n;
- if (withReturn)
- {
- ni = rr / ww;
- while (olen > 0)
- {
- i = 0;
- while ((i < ni) && (j < nn))
- {
- llong v = S[(i % 5) * 5 + i / 5];
- for (_ = 0; _ < ww; _++)
- {
- if (j < nn)
- rc[ptr++] = (byte)v;
- v >>= 8;
- j += 1;
- }
- i += 1;
- }
- olen -= r;
- if (olen > 0)
- sha3_keccakF(S);
- }
- if ((n & 7))
- rc[n >> 3] &= (1 << (n & 7)) - 1;
-
- return rc;
- }
- while ((olen -= r) > 0)
- sha3_keccakF(S);
- return null;
-}
-
-
-/**
- * Force some rounds of Keccak-f
- *
- * @param times The number of rounds
- */
-void sha3_simpleSqueeze(long times)
-{
- long i;
- for (i = 0; i < times; i++)
- sha3_keccakF(S);
-}
-
-
-/**
- * Squeeze as much as is needed to get a digest a number of times
- *
- * @param times The number of digests
- */
-void sha3_fastSqueeze(long times)
-{
- long i, olen;
- for (i = 0; i < times; i++)
- {
- sha3_keccakF(S); /* Last squeeze did not do a ending squeeze */
- olen = n;
- while ((olen -= r) > 0)
- sha3_keccakF(S);
- }
-}
-
-
-/**
- * Squeeze out another digest
- *
- * @return The hash sum
- */
-byte* sha3_squeeze(void)
-{
- long nn, ww, olen, i, j, _, ptr, ni;
- byte* rc;
-
- sha3_keccakF(S); /* Last squeeze did not do a ending squeeze */
-
- ww = w >> 3;
- rc = (byte*)malloc((nn = (n + 7) >> 3) * sizeof(byte));
- olen = n;
- j = ptr = 0;
- ni = (r >> 3) / ww;
-
- while (olen > 0)
- {
- i = 0;
- while ((i < ni) && (j < nn))
- {
- llong v = S[(i % 5) * 5 + i / 5];
- for (_ = 0; _ < ww; _++)
- {
- if (j < nn)
- *(rc + ptr++) = (byte)v;
- v >>= 8;
- j += 1;
- }
- i += 1;
- }
- olen -= r;
- if (olen > 0)
- sha3_keccakF(S);
- }
- if (n & 7)
- rc[nn - 1] &= (1 << (n & 7)) - 1;
-
- return rc;
-}
-
-
-/**
- * Retrieve the state of the Keccak sponge
- *
- * @return A 25-element array with the state, changes will be applied to the sponge
- */
-llong* sha3_state(void)
-{
- return S;
-}
-
diff --git a/c/sha3.h b/c/sha3.h
deleted file mode 100644
index a66d937..0000000
--- a/c/sha3.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/**
- * sha3sum – SHA-3 (Keccak) checksum calculator
- *
- * Copyright © 2013, 2014 Mattias Andrée (maandree@member.fsf.org)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-#ifndef __SHA3_H__
-#define __SHA3_H__
-
-#include <stdlib.h>
-
-
-#ifdef WITH_C99
- #include <inttypes.h>
- #define restrict_ restrict
- #define byte int_fast8_t
- #define boolean int_fast8_t
- #define llong int_fast64_t
- #define ullong uint_fast64_t
-#else
- #define restrict_ /* introduced in C99 */
- #define byte char
- #define boolean char
- #if __x86_64__ || __ppc64__
- #define llong long int
- #else
- #define llong long long int
- #endif
- #define ullong unsigned llong
-#endif
-
-
-/**
- * Suffix the message when calculating the Keccak hash sum
- */
-#define KECCAK_SUFFIX ""
-
-/**
- * Suffix the message when calculating the SHA-3 hash sum
- */
-#define SHA3_SUFFIX "01"
-
-/**
- * Suffix the message when calculating the RawSHAKE hash sum
- */
-#define RawSHAKE_SUFFIX "11"
-
-/**
- * Suffix the message when calculating the SHAKE hash sum
- */
-#define SHAKE_SUFFIX "1111"
-
-
-/**
- * Initialise Keccak sponge
- *
- * @param bitrate The bitrate
- * @param capacity The capacity
- * @param output The output size
- */
-void sha3_initialise(long bitrate, long capacity, long output);
-
-
-/**
- * Dispose of the Keccak sponge
- */
-void sha3_dispose(void);
-
-
-/**
- * Absorb the more of the message to the Keccak sponge
- *
- * @param msg The partial message
- * @param msglen The length of the partial message
- */
-void sha3_update(byte* restrict_ msg, long msglen);
-
-
-/**
- * Absorb the last part of the message and squeeze the Keccak sponge
- *
- * @param msg The rest of the message, may be {@code null}
- * @param msglen The length of the partial message
- * @param bits The number of bits at the end of the message not covered by `msglen`
- * @param suffix The suffix concatenate to the message
- * @param withReturn Whether to return the hash instead of just do a quick squeeze phrase and return {@code null}
- * @return The hash sum, or {@code null} if <tt>withReturn</tt> is {@code false}
- */
-byte* sha3_digest(byte* restrict_ msg, long msglen, long bits, char* restrict_ suffix, boolean withReturn);
-
-
-/**
- * Force some rounds of Keccak-f
- *
- * @param times The number of rounds
- */
-void sha3_simpleSqueeze(long times);
-
-
-/**
- * Squeeze as much as is needed to get a digest a number of times
- *
- * @param times The number of digests
- */
-void sha3_fastSqueeze(long times);
-
-
-/**
- * Squeeze out another digest
- *
- * @return The hash sum
- */
-byte* sha3_squeeze(void);
-
-
-/**
- * Retrieve the state of the Keccak sponge
- *
- * @return A 25-element array with the state, changes will be applied to the sponge
- */
-llong* sha3_state(void);
-
-
-#endif
-
diff --git a/c/sha3sum.c b/c/sha3sum.c
deleted file mode 100644
index 8b32755..0000000
--- a/c/sha3sum.c
+++ /dev/null
@@ -1,760 +0,0 @@
-/**
- * sha3sum – SHA-3 (Keccak) checksum calculator
- *
- * Copyright © 2013, 2014 Mattias Andrée (maandree@member.fsf.org)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-#include <stdio.h>
-#include <alloca.h>
-#include <sys/stat.h>
-
-#include "sha3.h"
-
-
-#define false 0
-#define true 1
-#define null 0
-
-#define SET void**
-
-#define HEXADECA "0123456789ABCDEF"
-
-
-/**
- * Prints a number of bytes to stdout
- *
- * @param BYTES:char* The bytes to print
- * @param N:long The number of bytes
- */
-#define putchars(BYTES, N) fwrite(BYTES, 1, N, stdout)
-
-
-/**
- * Creates a new set
- *
- * @return The set
- */
-SET set_new()
-{
- long i;
- void** rc = (void**)malloc(sizeof(void*) << 4);
- for (i = 0; i < 16; i++)
- *(rc + i) = 0;
- return rc;
-}
-
-
-/**
- * Frees a set
- *
- * @param set The set
- */
-void set_free(SET restrict_ set)
-{
- if (*(set + 0)) set_free((void**)*(set + 0));
- if (*(set + 1)) set_free((void**)*(set + 1));
- if (*(set + 2)) set_free((void**)*(set + 2));
- if (*(set + 3)) set_free((void**)*(set + 3));
- if (*(set + 4)) set_free((void**)*(set + 4));
- if (*(set + 5)) set_free((void**)*(set + 5));
- if (*(set + 6)) set_free((void**)*(set + 6));
- if (*(set + 7)) set_free((void**)*(set + 7));
- if (*(set + 8)) set_free((void**)*(set + 8));
- if (*(set + 9)) set_free((void**)*(set + 9));
- if (*(set + 10)) set_free((void**)*(set + 10));
- if (*(set + 11)) set_free((void**)*(set + 11));
- if (*(set + 12)) set_free((void**)*(set + 12));
- if (*(set + 13)) set_free((void**)*(set + 13));
- if (*(set + 14)) set_free((void**)*(set + 14));
- if (*(set + 15)) set_free((void**)*(set + 15));
- free(set);
-}
-
-
-/**
- * Adds an item to a set
- *
- * @param set The set
- * @param item The item
- * @param n The length of the item
- */
-void set_add(SET restrict_ set, char* restrict_ item, long n)
-{
- long i, j;
- void** at = set;
- for (i = 0; i < n; i++)
- {
- long a = (long)((*(item + i)) & 15), b = (long)((*(item + i) >> 4) & 15);
- if (*(at + a))
- at = (void**)*(at + a);
- else
- {
- at = (void**)(*(at + a) = (void*)malloc(sizeof(void*) << 4));
- for (j = 0; j < 16; j++)
- *(at + j) = 0;
- }
- if (*(at + b))
- at = (void**)*(at + b);
- else
- {
- at = (void**)(*(at + b) = (void*)malloc(sizeof(void*) << 4));
- for (j = 0; j < 16; j++)
- *(at + j) = 0;
- }
- }
-}
-
-
-/**
- * Checks if a set contains an item
- *
- * @param set The set
- * @param item The item
- * @param n The length of the item
- * @return Whether the set contains the item
- */
-long set_contains(SET restrict_ set, byte* restrict_ item, long n)
-{
- long i;
- void** at = set;
- for (i = 0; i < n; i++)
- {
- long a = (long)((*(item + i)) & 15), b = (long)((*(item + i) >> 4) & 15);
- if (*(at + a))
- at = (void**)*(at + a);
- else
- return false;
- if (*(at + b))
- at = (void**)*(at + b);
- else
- return false;
- }
- return true;
-}
-
-
-/**
- * String equality comparator
- *
- * @param a First comparand
- * @param b Second comparand
- * @return Whether the comparands are equal
- */
-long eq(char* restrict_ a, char* restrict_ b)
-{
- while (*a)
- if (*a++ != *b++)
- return false;
- return !*b;
-}
-
-
-/**
- * Convert a string to an integer
- *
- * @param str String representation
- * @return Native representation
- */
-long parseInt(char* restrict_ str)
-{
- long rc = 0;
- while (*str)
- rc = rc * 10 - (*str++ & 15);
- return -rc;
-}
-
-
-/**
- * This is the main entry point of the program
- *
- * @param argc Command line argument count
- * @param argv Command line arguments
- * @return Exit value, zero on and only on successful execution
- */
-int main(int argc, char** argv)
-{
- char* out_alloc;
- byte* stdin_alloc;
-
- long _o, o, _s, s, _r, r, _c, c, _w, w, _i, i, _j, j;
- long _O, O, _S, S, _R, R, _C, C, _W, W, _I, I, _J, J;
- long binary = false, hex = false, dashed = false;
- long multi = 0, fptr = 0, bn;
-
- char** files = (char**)alloca((argc + 2) * sizeof(char*));
- char** linger = files + argc;
- char* linger0 = (char*)alloca(sizeof(char) << 13);
-
- long a = 0, an = argc - 1;
- char** args = argv + 1;
- char* cmd = *argv;
-
-
- _O = _S = _R = _C = _W = _I = _J = false;
- O = S = R = C = W = I = J = 0;
- o = s = r = c = w = i = j = 0;
-
- *linger = 0;
-
-
- s = -1;
- for (i = 0; *(cmd + i); i++)
- if (*(cmd + i) == '/')
- s = i;
- if (s >= 0)
- cmd += s + 1;
-
- _o = 512; /* --outputsize */
- if ((cmd[0] == 's') && (cmd[1] == 'h') && (cmd[2] == 'a') && (cmd[3] == '3') && (cmd[4] == '-'))
- if ((cmd[5] != 0) && (cmd[6] != 0) && (cmd[7] != 0))
- if ((cmd[8] == 's') && (cmd[9] == 'u') && (cmd[10] == 'm') && (cmd[11] == 0))
- {
- if ((cmd[5] == '2') && (cmd[6] == '2') && (cmd[7] == '4'))
- _o = 224;
- else if ((cmd[5] == '2') && (cmd[6] == '5') && (cmd[7] == '6'))
- _o = 256;
- else if ((cmd[5] == '3') && (cmd[6] == '8') && (cmd[7] == '4'))
- _o = 384;
- else if ((cmd[5] == '5') && (cmd[6] == '1') && (cmd[7] == '2'))
- _o = 512;
- }
- _s = 1600; /* --statesize */
- _c = _s - (_o << 1); /* --capacity */
- _r = _s - _c; /* --bitrate */
- _w = _s / 25; /* --wordsize */
- _i = 1; /* --iterations */
- _j = 1; /* --squeezes */
-
-
- for (; a <= an; a++)
- {
- char* arg = a == an ? null : *(args + a);
- if (*linger)
- {
- if (eq(*linger, "-h") || eq(*linger, "--help"))
- {
- printf("\n");
- printf("SHA-3/Keccak checksum calculator\n");
- printf("\n");
- printf("USAGE: sha3sum [option...] < file\n");
- printf(" sha3sum [option...] file...\n");
- printf("\n");
- printf("\n");
- printf("OPTIONS:\n");
- printf(" -r BITRATE\n");
- printf(" --bitrate The bitrate to use for checksum. (default: %li)\n", _r);
- printf(" \n");
- printf(" -c CAPACITY\n");
- printf(" --capacity The capacity to use for checksum. (default: %li)\n", _c);
- printf(" \n");
- printf(" -w WORDSIZE\n");
- printf(" --wordsize The word size to use for checksum. (default: %li)\n", _w);
- printf(" \n");
- printf(" -o OUTPUTSIZE\n");
- printf(" --outputsize The output size to use for checksum. (default: %li)\n", _o);
- printf(" \n");
- printf(" -s STATESIZE\n");
- printf(" --statesize The state size to use for ckecksum. (default: %li)\n", _s);
- printf(" \n");
- printf(" -i ITERATIONS\n");
- printf(" --iterations The number of hash iterations to run. (default: %li)\n", _i);
- printf(" \n");
- printf(" -j SQUEEZES\n");
- printf(" --squeezes The number of hash squeezes to run. (default: %li)\n", _j);
- printf(" \n");
- printf(" -x\n");
- printf(" --hex Read the input in hexadecimal, rather than binary.\n");
- printf(" \n");
- printf(" -b\n");
- printf(" --binary Print the checksum in binary, rather than hexadecimal.\n");
- printf(" \n");
- printf(" -m\n");
- printf(" --multi Print the checksum at all iterations.\n");
- printf("\n");
- printf("\n");
- printf("COPYRIGHT:\n");
- printf("\n");
- printf("Copyright © 2013, 2014 Mattias Andrée (maandree@member.fsf.org)\n");
- printf("\n");
- printf("This program is free software: you can redistribute it and/or modify\n");
- printf("it under the terms of the GNU Affero General Public License as published by\n");
- printf("the Free Software Foundation, either version 3 of the License, or\n");
- printf("(at your option) any later version.\n");
- printf("\n");
- printf("This program is distributed in the hope that it will be useful,\n");
- printf("but WITHOUT ANY WARRANTY; without even the implied warranty of\n");
- printf("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n");
- printf("GNU Affero General Public License for more details.\n");
- printf("\n");
- printf("You should have received a copy of the GNU Affero General Public License\n");
- printf("along with this program. If not, see <http://www.gnu.org/licenses/>.\n");
- printf("\n");
- fflush(stdout);
- fflush(stderr);
- return 0;
- }
- else
- {
- if (*(linger + 1) == null)
- {
- *(linger + 1) = arg;
- arg = null;
- }
- if (eq(*linger, "-r") || eq(*linger, "--bitrate"))
- _R = 1 | (R = parseInt(linger[1]));
- else if (eq(*linger, "-c") || eq(*linger, "--capacity"))
- _C = 1 | (C = parseInt(linger[1]));
- else if (eq(*linger, "-w") || eq(*linger, "--wordsize"))
- _W = 1 | (W = parseInt(linger[1]));
- else if (eq(*linger, "-o") || eq(*linger, "--outputsize"))
- _O = 1 | (O = parseInt(linger[1]));
- else if (eq(*linger, "-s") || eq(*linger, "--statesize"))
- _S = 1 | (S = parseInt(linger[1]));
- else if (eq(*linger, "-i") || eq(*linger, "--iterations"))
- _I = 1 | (I = parseInt(linger[1]));
- else if (eq(*linger, "-j") || eq(*linger, "--squeezes"))
- _J = 1 | (J = parseInt(linger[1]));
- else
- {
- fprintf(stderr, "%s: unrecognised option: %s\n", cmd, *linger);
- fflush(stdout);
- fflush(stderr);
- return 1;
- }
- }
- *linger = null;
- if (arg == null)
- continue;
- }
- if (arg == null)
- continue;
- if (dashed)
- files[fptr++] = ((arg[0] == '-') && (arg[1] == 0)) ? null : arg;
- else if ((arg[0] == '-') && (arg[1] == '-') && (arg[2] == 0))
- dashed = true;
- else if ((arg[0] == '-') && (arg[1] == 0))
- files[fptr++] = null;
- else if ((arg[0] == '-') && (arg[1] == '-') && arg[2])
- {
- long idx = -1, j;
- for (j = 0; *(arg + j); j++)
- if (*(arg + j) == '=')
- {
- idx = j;
- break;
- }
- if (idx >= 0)
- {
- linger[0] = linger0;
- linger[1] = arg + idx + 1;
- for (j = 0; j < idx; j++)
- *(*linger + j) = *(arg + j);
- }
- else
- if (eq(arg, "--binary"))
- binary = true;
- else if (eq(arg, "--multi"))
- multi++;
- else if (eq(arg, "--hex"))
- hex = true;
- else
- {
- linger[0] = arg;
- linger[1] = null;
- }
- }
- else if ((arg[0] == '-') && arg[1])
- {
- arg++;
- if (*arg == 'b')
- {
- binary = true;
- arg++;
- }
- else if (*arg == 'm')
- {
- multi++;
- arg++;
- }
- else if (*arg == 'x')
- {
- hex = true;
- arg++;
- }
- else
- {
- {
- char* _ = linger0;
- *_++ = '-'; *_++ = *arg; *_ = 0;
- linger[0] = _ - 2;
- }
- {
- long _ = 0;
- while (*(arg + _))
- _++;
- linger[1] = _ == 1 ? null : arg + 1;
- }
- }
- }
- else
- files[fptr++] = arg;
- }
-
-
- i = _I ? I : _i;
- j = _J ? J : _j;
-
- #define ERR(text) fprintf(stderr, "%s: " text "\n", cmd); fflush(stdout); fflush(stderr)
-
- if (_S)
- {
- s = S;
- if ((s <= 0) || (s > 1600) || (s % 25))
- {
- ERR("the state size must be a positive multiple of 25 and is limited to 1600.");
- return 6;
- }
- }
-
- if (_W)
- {
- w = W;
- if ((w <= 0) || (w > 64))
- {
- ERR("the word size must be positive and is limited to 64.");
- return 6;
- }
- if (_S && (s != w * 25))
- {
- ERR("the state size must be 25 times of the word size.");
- return 6;
- }
- else if (_S == null)
- _S = 1 | (S = w * 25);
- }
-
- if (_C)
- {
- c = C;
- if ((c <= 0) || (c & 7))
- {
- ERR("the capacity must be a positive multiple of 8.");
- return 6;
- }
- }
-
- if (_R)
- {
- r = R;
- if ((r <= 0) || (r & 7))
- {
- ERR("the bitrate must be a positive multiple of 8.");
- return 6;
- }
- }
-
- if (_O)
- {
- o = O;
- if (o <= 0)
- {
- ERR("the output size must be positive.");
- return 6;
- }
- }
-
- if ((_R | _C | _O) == null) /* s? */
- {
- s = _S ? s : _s;
- c = -((r = (o = (((s << 5) / 100 + 7) >> 3) << 3) << 1) - s);
- o = o < 8 ? 8 : o;
- }
- else if ((_R | _C) == null) /* !o s? */
- {
- r = _r;
- c = _c;
- s = _S ? s : (r + c);
- }
- else if (_R == null) /* !c o? s? */
- {
- r = (s = _S ? s : _s) - c;
- o = _O ? o : (c == 8 ? 8 : (c << 1));
- }
- else if (_C == null) /* !r o? s? */
- {
- c = (s = _S ? s : _s) - r;
- o = _O ? o : (c == 8 ? 8 : (c << 1));
- }
- else /* !r !c o? s? */
- {
- s = _S ? s : (r + c);
- o = _O ? o : (c == 8 ? 8 : (c << 1));
- }
-
-
- fprintf(stderr, "Bitrate: %li\n", r);
- fprintf(stderr, "Capacity: %li\n", c);
- fprintf(stderr, "Word size: %li\n", w);
- fprintf(stderr, "State size: %li\n", s);
- fprintf(stderr, "Output Size: %li\n", o);
- fprintf(stderr, "Iterations: %li\n", i);
- fprintf(stderr, "Squeezes: %li\n", j);
-
-
- if (r > s)
- {
- ERR("the bitrate must not be higher than the state size.");
- return 6;
- }
- if (c > s)
- {
- ERR("the capacity must not be higher than the state size.");
- return 6;
- }
- if (r + c != s)
- {
- ERR("the sum of the bitrate and the capacity must equal the state size.");
- return 6;
- }
-
-
- if (fptr == 0)
- files[fptr++] = null;
- if (i < 1)
- {
- ERR("sorry, I will only do at least one hash iteration!");
- return 3;
- }
- if (j < 1)
- {
- ERR("sorry, I will only do at least one squeeze iteration!");
- return 3;
- }
-
- #undef ERR
-
- bn = (o + 7) >> 3;
- out_alloc = (char*)alloca(bn * 2 * sizeof(char) + bn * sizeof(byte));
- stdin_alloc = (byte*)(out_alloc + bn * 2);
- {
- byte* stdin;
- char* filename;
- char* fn;
- long f, fail, _;
- struct stat attr;
-
- char* out = binary ? null : out_alloc;
-
- fail = false;
- stdin = null;
-
- for (f = 0; f < fptr; f++)
- {
- FILE* file;
- long blksize;
- byte* chunk;
- byte* bs;
-
- filename = *(files + f);
- fn = filename ? filename : "/dev/stdin";
- file = fopen(fn, "r");
- if (file == null)
- {
- fprintf(stderr, "%s: cannot read file: %s\n", cmd, filename);
- fail = true;
- continue;
- }
-
- if ((filename != null) || (stdin == null))
- {
- sha3_initialise(r, c, o);
- blksize = stat(*(argv + f), &attr) ? 0 : attr.st_blksize;
- if (blksize <= 0)
- blksize = 4096;
- chunk = (byte*)alloca(blksize * sizeof(byte));
- for (;;)
- {
- long read = fread(chunk, 1, blksize, file);
- if (read <= 0)
- break;
- if (hex == false)
- sha3_update(chunk, read);
- else
- {
- int n = read >> 1;
- for (_ = 0; _ < n; _++)
- {
- byte a = *(chunk + (_ << 1)), b = *(chunk + ((_ << 1) | 1));
- a = (a & 15) + (a <= '9' ? 0 : 9);
- b = (b & 15) + (b <= '9' ? 0 : 9);
- *(chunk + _) = (a << 4) | b;
- }
- sha3_update(chunk, n);
- }
- }
- bs = sha3_digest(null, 0, 0, SHA3_SUFFIX, j == 1);
- if (j > 2)
- sha3_fastSqueeze(j - 2);
- if (j > 1)
- bs = sha3_squeeze();
- sha3_dispose();
-
- if (filename == null)
- {
- stdin = stdin_alloc;
- for (_ = 0; _ < bn; _++)
- *(stdin_alloc + _) = *(bs + _);
- }
- }
- else
- bs = stdin;
-
- if (multi == 0)
- {
- for (_ = 1; _ < i; _++)
- {
- byte* _bs = bs;
- sha3_initialise(r, c, o);
- bs = sha3_digest(bs, bn, 0, SHA3_SUFFIX, j == 1);
- if (j > 2)
- sha3_fastSqueeze(j - 2);
- if (j > 1)
- bs = sha3_squeeze();
- free(_bs);
- sha3_dispose();
- }
- if (binary)
- putchars((char*)bs, bn);
- else
- {
- long b, outptr = 0;
- for (b = 0; b < bn; b++)
- {
- byte v = bs[b];
- *(out + outptr++) = HEXADECA[(v >> 4) & 15];
- *(out + outptr++) = HEXADECA[v & 15];
- }
- out[outptr] = '\0';
- printf("%s %s\n", out, filename ? filename : "-");
- }
- }
- else if (multi == 1)
- {
- long b;
- if (binary)
- putchars((char*)bs, bn);
- else
- {
- for (b = 0; b < bn; b++)
- {
- byte v = bs[b];
- out[b * 2 ] = HEXADECA[(v >> 4) & 15];
- out[b * 2 + 1] = HEXADECA[v & 15];
- }
- out[b*2] = '\0';
- printf("%s %s\n", out, filename ? filename : "-");
- }
- for (_ = 1; _ < i; _++)
- {
- byte* _bs = bs;
- sha3_initialise(r, c, o);
- bs = sha3_digest(bs, bn, 0, SHA3_SUFFIX, j == 1);
- if (j > 2)
- sha3_fastSqueeze(j - 2);
- if (j > 1)
- bs = sha3_squeeze();
- free(_bs);
- sha3_dispose();
- if (binary)
- putchars((char*)bs, bn);
- else
- {
- for (b = 0; b < bn; b++)
- {
- byte v = bs[b];
- out[b * 2 ] = HEXADECA[(v >> 4) & 15];
- out[b * 2 + 1] = HEXADECA[v & 15];
- }
- out[b*2] = '\0';
- printf("%s\n", out);
- }
- }
- }
- else
- {
- long b;
- char loophere;
- char* loop = null;
- SET got = set_new();
- for (_ = 0; _ < i; _++)
- {
- if (_ > 0)
- {
- byte* _bs = bs;
- sha3_initialise(r, c, o);
- bs = sha3_digest(bs, bn, 0, SHA3_SUFFIX, j == 1);
- if (j > 2)
- sha3_fastSqueeze(j - 2);
- if (j > 1)
- bs = sha3_squeeze();
- free(_bs);
- sha3_dispose();
- }
- for (b = 0; b < bn; b++)
- {
- byte v = bs[b];
- out[b * 2 ] = HEXADECA[(v >> 4) & 15];
- out[b * 2 + 1] = HEXADECA[v & 15];
- }
- if (loop == null)
- {
- if (set_contains(got, bs, bn))
- {
- loop = (char*)malloc(bn * 2 * sizeof(char));
- for (b = 0; b < bn * 2; b++)
- *(loop + b) = *(out + b);
- }
- else
- set_add(got, out, bn);
- }
- loophere = loop && eq(loop, out);
- if (loophere)
- printf("\033[31m");
- putchars(out, bn * 2);
- if (loophere)
- printf("\033[00m");
- fflush(stdout);
- }
- if (loop)
- {
- fprintf(stderr, "\033[01;31mLoop found\033[00m\n");
- free(loop);
- }
- set_free(got);
- }
- if (bs != null)
- free(bs);
- fclose(file);
- }
-
- fflush(stdout);
- fflush(stderr);
- if (fail)
- return 5;
- }
-
- return 0;
-}
-
diff --git a/java-c-jni/SHA3.c b/java-c-jni/SHA3.c
deleted file mode 100644
index 76b1d61..0000000
--- a/java-c-jni/SHA3.c
+++ /dev/null
@@ -1,871 +0,0 @@
-/**
- * sha3sum – SHA-3 (Keccak) checksum calculator
- *
- * Copyright © 2013, 2014 Mattias Andrée (maandree@member.fsf.org)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-#include <stdlib.h>
-#include "SHA3.h"
-
-
-#if __x86_64__ || __ppc64__
- #define llong long int
-#else
- #define llong long long int
-#endif
-
-
-#define null 0
-#define byte char
-#define boolean long
-#define true 1
-#define false 0
-
-
-
-/**
- * Round contants
- */
-static const llong RC[] = {
- 0x0000000000000001L, 0x0000000000008082L, 0x800000000000808AL, 0x8000000080008000L,
- 0x000000000000808BL, 0x0000000080000001L, 0x8000000080008081L, 0x8000000000008009L,
- 0x000000000000008AL, 0x0000000000000088L, 0x0000000080008009L, 0x000000008000000AL,
- 0x000000008000808BL, 0x800000000000008BL, 0x8000000000008089L, 0x8000000000008003L,
- 0x8000000000008002L, 0x8000000000000080L, 0x000000000000800AL, 0x800000008000000AL,
- 0x8000000080008081L, 0x8000000000008080L, 0x0000000080000001L, 0x8000000080008008L};
-
-/**
- * Keccak-f round temporary
- */
-static llong B[25];
-
-/**
- * Keccak-f round temporary
- */
-static llong C[5];
-
-
-/**
- * The bitrate
- */
-static long r = 0;
-
-/**
- * The capacity
- */
-static long c = 0;
-
-/**
- * The output size
- */
-static long n = 0;
-
-/**
- * The state size
- */
-static long b = 0;
-
-/**
- * The word size
- */
-static long w = 0;
-
-/**
- * The word mask
- */
-static llong wmod = 0;
-
-/**
- * ℓ, the binary logarithm of the word size
- */
-static long l = 0;
-
-/**
- * 12 + 2ℓ, the number of rounds
- */
-static long nr = 0;
-
-
-/**
- * The current state
- */
-static llong* S = null;
-
-/**
- * Left over water to fill the sponge with at next update
- */
-static byte* M = null;
-
-/**
- * Pointer for {@link #M}
- */
-static long mptr = 0;
-
-/**
- * Size of {@link #M}
- */
-static long mlen = 0;
-
-
-
-/**
- * Gets the smallest, in value, of the arguments
- *
- * @param X The first candidate
- * @param Y The second candidate
- * @return The lowest candidate
- */
-#define min(X, Y) ((X) < (Y) ? (X) : (Y))
-
-
-
-/**
- * Copy an array segment into an array in start to end order
- *
- * @param src The source array
- * @param soff The source array offset
- * @param dest The destination array
- * @param doff The destination array offset
- * @param length The number of elements to copy
- */
-inline void arraycopy(byte* src, long soff, byte* dest, long doff, long length)
-{
- long i;
- src += soff;
- dest += doff;
-
- #define __(X) dest[X] = src[X]
- #define __0 *dest = *src
- #define __1 __(0x01)
- #define __2 __(0x02); __(0x03)
- #define __3 __(0x04); __(0x05); __(0x06); __(0x07)
- #define __4 __(0x08); __(0x09); __(0x0A); __(0x0B); __(0x0C); __(0x0D); __(0x0E); __(0x0F)
- #define __5 __(0x10); __(0x11); __(0x12); __(0x13); __(0x14); __(0x15); __(0x16); __(0x17); __(0x18); __(0x19); __(0x1A); __(0x1B); __(0x1C); __(0x1D); __(0x1E); __(0x1F)
- #define __6 __(0x20); __(0x21); __(0x22); __(0x23); __(0x24); __(0x25); __(0x26); __(0x27); __(0x28); __(0x29); __(0x2A); __(0x2B); __(0x2C); __(0x2D); __(0x2E); __(0x2F); \
- __(0x30); __(0x31); __(0x32); __(0x33); __(0x34); __(0x35); __(0x36); __(0x37); __(0x38); __(0x39); __(0x3A); __(0x3B); __(0x3C); __(0x3D); __(0x3E); __(0x3F)
- #define __7 __(0x40); __(0x41); __(0x42); __(0x43); __(0x44); __(0x45); __(0x46); __(0x47); __(0x48); __(0x49); __(0x4A); __(0x4B); __(0x4C); __(0x4D); __(0x4E); __(0x4F); \
- __(0x50); __(0x51); __(0x52); __(0x53); __(0x54); __(0x55); __(0x56); __(0x57); __(0x58); __(0x59); __(0x5A); __(0x5B); __(0x5C); __(0x5D); __(0x5E); __(0x5F); \
- __(0x60); __(0x61); __(0x62); __(0x63); __(0x64); __(0x65); __(0x66); __(0x67); __(0x68); __(0x69); __(0x6A); __(0x6B); __(0x6C); __(0x6D); __(0x6E); __(0x6F); \
- __(0x70); __(0x71); __(0x72); __(0x73); __(0x74); __(0x75); __(0x76); __(0x77); __(0x78); __(0x79); __(0x7A); __(0x7B); __(0x7C); __(0x7D); __(0x7E); __(0x7F)
- #define __8 __(0x80); __(0x81); __(0x82); __(0x83); __(0x84); __(0x85); __(0x86); __(0x87); __(0x88); __(0x89); __(0x8A); __(0x8B); __(0x8C); __(0x8D); __(0x8E); __(0x8F); \
- __(0x90); __(0x91); __(0x92); __(0x93); __(0x94); __(0x95); __(0x96); __(0x97); __(0x98); __(0x99); __(0x9A); __(0x9B); __(0x9C); __(0x9D); __(0x9E); __(0x9F); \
- __(0xA0); __(0xA1); __(0xA2); __(0xA3); __(0xA4); __(0xA5); __(0xA6); __(0xA7); __(0xA8); __(0xA9); __(0xAA); __(0xAB); __(0xAC); __(0xAD); __(0xAE); __(0xAF); \
- __(0xB0); __(0xB1); __(0xB2); __(0xB3); __(0xB4); __(0xB5); __(0xB6); __(0xB7); __(0xB8); __(0xB9); __(0xBA); __(0xBB); __(0xBC); __(0xBD); __(0xBE); __(0xBF); \
- __(0xC0); __(0xC1); __(0xC2); __(0xC3); __(0xC4); __(0xC5); __(0xC6); __(0xC7); __(0xC8); __(0xC9); __(0xCA); __(0xCB); __(0xCC); __(0xCD); __(0xCE); __(0xCF); \
- __(0xD0); __(0xD1); __(0xD2); __(0xD3); __(0xD4); __(0xD5); __(0xD6); __(0xD7); __(0xD8); __(0xD9); __(0xDA); __(0xDB); __(0xDC); __(0xDD); __(0xDE); __(0xDF); \
- __(0xE0); __(0xE1); __(0xE2); __(0xE3); __(0xE4); __(0xE5); __(0xE6); __(0xE7); __(0xE8); __(0xE9); __(0xEA); __(0xEB); __(0xEC); __(0xED); __(0xEE); __(0xEF); \
- __(0xF0); __(0xF1); __(0xF2); __(0xF3); __(0xF4); __(0xF5); __(0xF6); __(0xF7); __(0xF8); __(0xF9); __(0xFA); __(0xFB); __(0xFC); __(0xFD); __(0xFE); __(0xFF)
-
- if ((length & 15))
- {
- if ((length & 1)) { __0; src += 1; dest += 1; }
- if ((length & 2)) { __0; __1; src += 2; dest += 2; }
- if ((length & 4)) { __0; __1; __2; src += 4; dest += 4; }
- if ((length & 8)) { __0; __1; __2; __3; src += 8; dest += 8; }
- }
- if ((length & 240))
- {
- if ((length & 16)) { __0; __1; __2; __3; __4; src += 16; dest += 16; }
- if ((length & 32)) { __0; __1; __2; __3; __4; __5; src += 32; dest += 32; }
- if ((length & 64)) { __0; __1; __2; __3; __4; __5; __6; src += 64; dest += 64; }
- if ((length & 128)) { __0; __1; __2; __3; __4; __5; __6; __7; src += 128; dest += 128; }
- }
- length &= ~255;
- for (i = 0; i < length; i += 256)
- {
- __0; __1; __2; __3; __4; __5; __6; __7; __8; src += 256; dest += 256;
- }
-
- #undef __8
- #undef __7
- #undef __6
- #undef __5
- #undef __4
- #undef __3
- #undef __2
- #undef __1
- #undef __0
- #undef __
-}
-
-
-/**
- * Copy an array segment into an array in end to start order
- *
- * @param src The source array
- * @param soff The source array offset
- * @param dest The destination array
- * @param doff The destination array offset
- * @param length The number of elements to copy
- */
-inline void revarraycopy(byte* src, long soff, byte* dest, long doff, long length)
-{
- long copyi;
- for (copyi = length - 1; copyi >= 0; copyi--)
- dest[copyi + doff] = src[copyi + soff];
-}
-
-
-/**
- * Rotate a word
- *
- * @param X:llong The value to rotate
- * @param N:long Rotation steps, may not be 0
- * @return :llong The value rotated
- */
-#define rotate(X, N) ((((X) >> (w - ((N) % w))) + ((X) << ((N) % w))) & wmod)
-
-
-/**
- * Rotate a 64-bit word
- *
- * @param X:llong The value to rotate
- * @param N:long Rotation steps, may not be 0
- * @return :llong The value rotated
- */
-#define rotate64(X, N) ((llong)((unsigned llong)(X) >> (64 - (N))) + ((X) << (N)))
-
-
-/**
- * Binary logarithm
- *
- * @param x The value of which to calculate the binary logarithm
- * @return The binary logarithm
- */
-static long lb(long x)
-{
- long rc = 0;
- if ((x & 0xFF00) != 0) { rc += 8; x >>= 8; }
- if ((x & 0x00F0) != 0) { rc += 4; x >>= 4; }
- if ((x & 0x000C) != 0) { rc += 2; x >>= 2; }
- if ((x & 0x0002) != 0) rc += 1;
- return rc;
-}
-
-
-/**
- * Perform one round of computation
- *
- * @param A The current state
- * @param rc Round constant
- */
-static void keccakFRound(llong* A, llong rc)
-{
- llong da, db, dc, dd, de;
-
- /* θ step (step 1 and 2 of 3) */
- #define __C(I, J0, J1, J2, J3, J4) C[I] = (A[J0] ^ A[J1]) ^ (A[J2] ^ A[J3]) ^ A[J4]
- __C(0, 0, 1, 2, 3, 4);
- __C(1, 5, 6, 7, 8, 9);
- __C(2, 10, 11, 12, 13, 14);
- __C(3, 15, 16, 17, 18, 19);
- __C(4, 20, 21, 22, 23, 24);
- #undef __C
-
- if (w == 64)
- {
- da = C[4] ^ rotate64(C[1], 1);
- dd = C[2] ^ rotate64(C[4], 1);
- db = C[0] ^ rotate64(C[2], 1);
- de = C[3] ^ rotate64(C[0], 1);
- dc = C[1] ^ rotate64(C[3], 1);
-
- /* ρ and π steps, with last two part of θ */
- #define __B(Bi, Ai, Dv, R) B[Bi] = rotate64(A[Ai] ^ Dv, R)
- B[0] = A[0] ^ da; __B( 1, 15, dd, 28); __B( 2, 5, db, 1); __B( 3, 20, de, 27); __B( 4, 10, dc, 62);
- __B( 5, 6, db, 44); __B( 6, 21, de, 20); __B( 7, 11, dc, 6); __B( 8, 1, da, 36); __B( 9, 16, dd, 55);
- __B(10, 12, dc, 43); __B(11, 2, da, 3); __B(12, 17, dd, 25); __B(13, 7, db, 10); __B(14, 22, de, 39);
- __B(15, 18, dd, 21); __B(16, 8, db, 45); __B(17, 23, de, 8); __B(18, 13, dc, 15); __B(19, 3, da, 41);
- __B(20, 24, de, 14); __B(21, 14, dc, 61); __B(22, 4, da, 18); __B(23, 19, dd, 56); __B(24, 9, db, 2);
- #undef __B
- }
- else
- {
- da = C[4] ^ rotate(C[1], 1);
- dd = C[2] ^ rotate(C[4], 1);
- db = C[0] ^ rotate(C[2], 1);
- de = C[3] ^ rotate(C[0], 1);
- dc = C[1] ^ rotate(C[3], 1);
-
- /* ρ and π steps, with last two part of θ */
- #define __B(Bi, Ai, Dv, R) B[Bi] = rotate(A[Ai] ^ Dv, R)
- B[0] = A[0] ^ da; __B( 1, 15, dd, 28); __B( 2, 5, db, 1); __B( 3, 20, de, 27); __B( 4, 10, dc, 62);
- __B( 5, 6, db, 44); __B( 6, 21, de, 20); __B( 7, 11, dc, 6); __B( 8, 1, da, 36); __B( 9, 16, dd, 55);
- __B(10, 12, dc, 43); __B(11, 2, da, 3); __B(12, 17, dd, 25); __B(13, 7, db, 10); __B(14, 22, de, 39);
- __B(15, 18, dd, 21); __B(16, 8, db, 45); __B(17, 23, de, 8); __B(18, 13, dc, 15); __B(19, 3, da, 41);
- __B(20, 24, de, 14); __B(21, 14, dc, 61); __B(22, 4, da, 18); __B(23, 19, dd, 56); __B(24, 9, db, 2);
- #undef __B
- }
-
- /* ξ step */
- #define __A(X, X5, X10) A[X] = B[X] ^ ((~(B[X5])) & B[X10])
- __A( 0, 5, 10); __A( 1, 6, 11); __A( 2, 7, 12); __A( 3, 8, 13); __A( 4, 9, 14);
- __A( 5, 10, 15); __A( 6, 11, 16); __A( 7, 12, 17); __A( 8, 13, 18); __A( 9, 14, 19);
- __A(10, 15, 20); __A(11, 16, 21); __A(12, 17, 22); __A(13, 18, 23); __A(14, 19, 24);
- __A(15, 20, 0); __A(16, 21, 1); __A(17, 22, 2); __A(18, 23, 3); __A(19, 24, 4);
- __A(20, 0, 5); __A(21, 1, 6); __A(22, 2, 7); __A(23, 3, 8); __A(24, 4, 9);
- #undef __A
-
- /* ι step */
- A[0] ^= rc;
-}
-
-
-/**
- * Perform Keccak-f function
- *
- * @param A The current state
- */
-static void keccakF(llong* A)
-{
- long i;
- if (nr == 24)
- {
- keccakFRound(A, 0x0000000000000001);
- keccakFRound(A, 0x0000000000008082);
- keccakFRound(A, 0x800000000000808A);
- keccakFRound(A, 0x8000000080008000);
- keccakFRound(A, 0x000000000000808B);
- keccakFRound(A, 0x0000000080000001);
- keccakFRound(A, 0x8000000080008081);
- keccakFRound(A, 0x8000000000008009);
- keccakFRound(A, 0x000000000000008A);
- keccakFRound(A, 0x0000000000000088);
- keccakFRound(A, 0x0000000080008009);
- keccakFRound(A, 0x000000008000000A);
- keccakFRound(A, 0x000000008000808B);
- keccakFRound(A, 0x800000000000008B);
- keccakFRound(A, 0x8000000000008089);
- keccakFRound(A, 0x8000000000008003);
- keccakFRound(A, 0x8000000000008002);
- keccakFRound(A, 0x8000000000000080);
- keccakFRound(A, 0x000000000000800A);
- keccakFRound(A, 0x800000008000000A);
- keccakFRound(A, 0x8000000080008081);
- keccakFRound(A, 0x8000000000008080);
- keccakFRound(A, 0x0000000080000001);
- keccakFRound(A, 0x8000000080008008);
- }
- else
- for (i = 0; i < nr; i++)
- keccakFRound(A, RC[i] & wmod);
-}
-
-
-/**
- * Convert a chunk of byte:s to a word
- *
- * @param message The message
- * @param msglen The length of the message
- * @param rr Bitrate in bytes
- * @param ww Word size in bytes
- * @param off The offset in the message
- * @return Lane
- */
-inline llong toLane(byte* message, long msglen, long rr, long ww, long off)
-{
- llong rc = 0;
- long n = min(msglen, rr), i;
- for (i = off + ww - 1; i >= off; i--)
- rc = (rc << 8) | ((i < n) ? (llong)(message[i] & 255) : 0L);
- return rc;
-}
-
-
-/**
- * Convert a chunk of byte:s to a 64-bit word
- *
- * @param message The message
- * @param msglen The length of the message
- * @param rr Bitrate in bytes
- * @param off The offset in the message
- * @return Lane
- */
-inline llong toLane64(byte* message, long msglen, long rr, long off)
-{
- long n = min(msglen, rr);
- return ((off + 7 < n) ? ((llong)(message[off + 7] & 255) << 56) : 0L) |
- ((off + 6 < n) ? ((llong)(message[off + 6] & 255) << 48) : 0L) |
- ((off + 5 < n) ? ((llong)(message[off + 5] & 255) << 40) : 0L) |
- ((off + 4 < n) ? ((llong)(message[off + 4] & 255) << 32) : 0L) |
- ((off + 3 < n) ? ((llong)(message[off + 3] & 255) << 24) : 0L) |
- ((off + 2 < n) ? ((llong)(message[off + 2] & 255) << 16) : 0L) |
- ((off + 1 < n) ? ((llong)(message[off + 1] & 255) << 8) : 0L) |
- ((off < n) ? ((llong)(message[off ] & 255) ) : 0L);
-}
-
-
-/**
- * pad 10*1
- *
- * @param msg The message to pad
- * @param len The length of the message
- * @param r The bitrate
- * @param bits The number of bits in the end of the message that does not make a whole byte
- * @param outlen The length of the padded message (out parameter)
- * @return The message padded
- */
-inline byte* pad10star1(byte* msg, long len, long r, long bits, long* outlen)
-{
- byte* message;
- byte b;
- long i, ll, nbrf, nrf;
-
- len = ((len - (bits + 7) / 8) << 3) + bits;
- nrf = len >> 3;
- nbrf = len & 7;
- ll = len % r;
-
- b = (byte)(nbrf == 0 ? 1 : (msg[nrf] | (1 << nbrf)));
-
- if ((r - 8 <= ll) && (ll <= r - 2))
- {
- message = (byte*)malloc(len = nrf + 1);
- message[nrf] = (byte)(b ^ 128);
- }
- else
- {
- byte* M;
- long N;
- len = (nrf + 1) << 3;
- len = ((len - (len % r) + (r - 8)) >> 3) + 1;
- message = (byte*)malloc(len);
- message[nrf] = b;
- N = len - nrf - 1;
- M = message + nrf + 1;
-
- #define __(X) M[X] = 0
- #define __0 *M = 0
- #define __1 __(0x01)
- #define __2 __(0x02); __(0x03)
- #define __3 __(0x04); __(0x05); __(0x06); __(0x07)
- #define __4 __(0x08); __(0x09); __(0x0A); __(0x0B); __(0x0C); __(0x0D); __(0x0E); __(0x0F)
- #define __5 __(0x10); __(0x11); __(0x12); __(0x13); __(0x14); __(0x15); __(0x16); __(0x17); __(0x18); __(0x19); __(0x1A); __(0x1B); __(0x1C); __(0x1D); __(0x1E); __(0x1F)
- #define __6 __(0x20); __(0x21); __(0x22); __(0x23); __(0x24); __(0x25); __(0x26); __(0x27); __(0x28); __(0x29); __(0x2A); __(0x2B); __(0x2C); __(0x2D); __(0x2E); __(0x2F); \
- __(0x30); __(0x31); __(0x32); __(0x33); __(0x34); __(0x35); __(0x36); __(0x37); __(0x38); __(0x39); __(0x3A); __(0x3B); __(0x3C); __(0x3D); __(0x3E); __(0x3F)
- #define __7 __(0x40); __(0x41); __(0x42); __(0x43); __(0x44); __(0x45); __(0x46); __(0x47); __(0x48); __(0x49); __(0x4A); __(0x4B); __(0x4C); __(0x4D); __(0x4E); __(0x4F); \
- __(0x50); __(0x51); __(0x52); __(0x53); __(0x54); __(0x55); __(0x56); __(0x57); __(0x58); __(0x59); __(0x5A); __(0x5B); __(0x5C); __(0x5D); __(0x5E); __(0x5F); \
- __(0x60); __(0x61); __(0x62); __(0x63); __(0x64); __(0x65); __(0x66); __(0x67); __(0x68); __(0x69); __(0x6A); __(0x6B); __(0x6C); __(0x6D); __(0x6E); __(0x6F); \
- __(0x70); __(0x71); __(0x72); __(0x73); __(0x74); __(0x75); __(0x76); __(0x77); __(0x78); __(0x79); __(0x7A); __(0x7B); __(0x7C); __(0x7D); __(0x7E); __(0x7F)
- #define __8 __(0x80); __(0x81); __(0x82); __(0x83); __(0x84); __(0x85); __(0x86); __(0x87); __(0x88); __(0x89); __(0x8A); __(0x8B); __(0x8C); __(0x8D); __(0x8E); __(0x8F); \
- __(0x90); __(0x91); __(0x92); __(0x93); __(0x94); __(0x95); __(0x96); __(0x97); __(0x98); __(0x99); __(0x9A); __(0x9B); __(0x9C); __(0x9D); __(0x9E); __(0x9F); \
- __(0xA0); __(0xA1); __(0xA2); __(0xA3); __(0xA4); __(0xA5); __(0xA6); __(0xA7); __(0xA8); __(0xA9); __(0xAA); __(0xAB); __(0xAC); __(0xAD); __(0xAE); __(0xAF); \
- __(0xB0); __(0xB1); __(0xB2); __(0xB3); __(0xB4); __(0xB5); __(0xB6); __(0xB7); __(0xB8); __(0xB9); __(0xBA); __(0xBB); __(0xBC); __(0xBD); __(0xBE); __(0xBF); \
- __(0xC0); __(0xC1); __(0xC2); __(0xC3); __(0xC4); __(0xC5); __(0xC6); __(0xC7); __(0xC8); __(0xC9); __(0xCA); __(0xCB); __(0xCC); __(0xCD); __(0xCE); __(0xCF); \
- __(0xD0); __(0xD1); __(0xD2); __(0xD3); __(0xD4); __(0xD5); __(0xD6); __(0xD7); __(0xD8); __(0xD9); __(0xDA); __(0xDB); __(0xDC); __(0xDD); __(0xDE); __(0xDF); \
- __(0xE0); __(0xE1); __(0xE2); __(0xE3); __(0xE4); __(0xE5); __(0xE6); __(0xE7); __(0xE8); __(0xE9); __(0xEA); __(0xEB); __(0xEC); __(0xED); __(0xEE); __(0xEF); \
- __(0xF0); __(0xF1); __(0xF2); __(0xF3); __(0xF4); __(0xF5); __(0xF6); __(0xF7); __(0xF8); __(0xF9); __(0xFA); __(0xFB); __(0xFC); __(0xFD); __(0xFE); __(0xFF)
-
- if ((N & 15))
- {
- if ((N & 1)) { __0; M += 1; }
- if ((N & 2)) { __0; __1; M += 2; }
- if ((N & 4)) { __0; __1; __2; M += 4; }
- if ((N & 8)) { __0; __1; __2; __3; M += 8; }
- }
- if ((N & 240))
- {
- if ((N & 16)) { __0; __1; __2; __3; __4; M += 16; }
- if ((N & 32)) { __0; __1; __2; __3; __4; __5; M += 32; }
- if ((N & 64)) { __0; __1; __2; __3; __4; __5; __6; M += 64; }
- if ((N & 128)) { __0; __1; __2; __3; __4; __5; __6; __7; M += 128; }
- }
- N &= ~255;
- for (i = 0; i < N; i += 256)
- {
- __0; __1; __2; __3; __4; __5; __6; __7; __8; M += 256;
- }
-
- #undef __8
- #undef __7
- #undef __6
- #undef __5
- #undef __4
- #undef __3
- #undef __2
- #undef __1
- #undef __0
- #undef __
-
- message[len - 1] = -128;
- }
- arraycopy(msg, 0, message, 0, nrf);
-
- *outlen = len;
- return message;
-}
-
-
-/**
- * Initialise Keccak sponge
- *
- * @param bitrate The bitrate
- * @param capacity The capacity
- * @param output The output size
- */
-void initialise(long bitrate, long capacity, long output)
-{
- long i;
-
- r = bitrate;
- n = output;
- c = capacity;
- b = r + c;
- w = b / 25;
- l = lb(w);
- nr = 12 + (l << 1);
- if (w == 64)
- wmod = -1;
- else
- {
- wmod = 1;
- wmod <<= w;
- wmod--;
- }
- S = (llong*)malloc(25 * sizeof(llong));
- M = (byte*)malloc(mlen = (r * b) >> 2);
- mptr = 0;
-
- for (i = 0; i < 25; i++)
- *(S + i) = 0;
-}
-
-/**
- * Dispose of the Keccak sponge
- */
-extern void dispose()
-{
- if (S != null)
- {
- free(S);
- S = null;
- }
- if (M != null)
- {
- free(M);
- M = null;
- }
-}
-
-/**
- * Absorb the more of the message message to the Keccak sponge
- *
- * @param msg The partial message
- * @param msglen The length of the partial message
- */
-void update(byte* msg, long msglen)
-{
- long rr = r >> 3;
- long ww = w >> 3;
- long i, len;
- byte* message;
- byte* _msg;
- long nnn;
-
- if (mptr + msglen > mlen)
- {
- byte* buf = (byte*)malloc(mlen = (mlen + msglen) << 1);
- arraycopy(M, 0, buf, 0, mptr);
- free(M);
- M = buf;
- }
- arraycopy(msg, 0, M, mptr, msglen);
- len = mptr += msglen;
- len -= len % ((r * b) >> 3);
- message = (byte*)malloc(len);
- arraycopy(M, 0, message, 0, len);
- mptr -= len;
- revarraycopy(M, nnn = len, M, 0, mptr);
- _msg = message;
-
- /* Absorbing phase */
- if (ww == 8)
- for (i = 0; i < nnn; i += rr)
- {
- #define __S(Si, OFF) S[Si] ^= toLane64(message, len, rr, OFF)
- __S( 0, 0); __S( 5, 8); __S(10, 16); __S(15, 24); __S(20, 32);
- __S( 1, 40); __S( 6, 48); __S(11, 56); __S(16, 64); __S(21, 72);
- __S( 2, 80); __S( 7, 88); __S(12, 96); __S(17, 104); __S(22, 112);
- __S( 3, 120); __S( 8, 128); __S(13, 136); __S(18, 144); __S(23, 152);
- __S( 4, 160); __S( 9, 168); __S(14, 176); __S(19, 184); __S(24, 192);
- #undef __S
- keccakF(S);
- message += rr;
- len -= rr;
- }
- else
- for (i = 0; i < nnn; i += rr)
- {
- #define __S(Si, OFF) S[Si] ^= toLane(message, len, rr, ww, OFF * ww)
- __S( 0, 0); __S( 5, 1); __S(10, 2); __S(15, 3); __S(20, 4);
- __S( 1, 5); __S( 6, 6); __S(11, 7); __S(16, 8); __S(21, 9);
- __S( 2, 10); __S( 7, 11); __S(12, 12); __S(17, 13); __S(22, 14);
- __S( 3, 15); __S( 8, 16); __S(13, 17); __S(18, 18); __S(23, 19);
- __S( 4, 20); __S( 9, 21); __S(14, 22); __S(19, 23); __S(24, 24);
- #undef __S
- keccakF(S);
- message += rr;
- len -= rr;
- }
-
- free(_msg);
-}
-
-
-/**
- * Absorb the last part of the message and squeeze the Keccak sponge
- *
- * @param msg The rest of the message, may be {@code null}
- * @param msglen The length of the partial message
- * @param bits The number of bits at the end of the message not covered by <tt>msglen</tt>
- * @param suffix The suffix concatenate to the message
- * @param suffix_len The length of the suffix
- * @param withReturn Whether to return the hash instead of just do a quick squeeze phrase and return {@code null}
- * @return The hash sum, or {@code null} if <tt>withReturn</tt> is {@code false}
- */
-byte* digest(byte* msg, long msglen, long bits, int* suffix, long suffix_len, boolean withReturn)
-{
- byte* message;
- byte* _msg;
- byte* rc;
- long rr = r >> 3, len;
- long nn = (n + 7) >> 3, olen;
- long ww = w >> 3, ni;
- long i, j = 0, ptr = 0, _;
- long nnn;
-
- if (msg == null)
- msglen = bits = 0;
-
- msglen += bits >> 3;
- if ((bits &= 7))
- msg[msglen] &= (1 << bits) - 1;
- if (suffix_len)
- {
- msg = (byte*)realloc(msg, msglen + ((suffix_len + bits + 7) >> 3));
- if (!bits)
- msg[msglen] = 0;
- for (i = 0; i < suffix_len; i++)
- {
- msg[msglen] |= suffix[i] << bits++;
- if (bits == 8)
- {
- bits = 0;
- msglen++;
- msg[msglen] = 0;
- }
- }
- }
- if (bits)
- msglen++;
-
- if (mptr + msglen > mlen)
- {
- byte* buf = (byte*)malloc(mlen += msglen);
- arraycopy(M, 0, buf, 0, mptr);
- free(M);
- M = buf;
- }
- arraycopy(msg, 0, M, mptr, msglen);
- message = pad10star1(M, mptr + msglen, r, bits, &len);
-
- free(M);
- M = null;
- rc = (byte*)malloc((n + 7) >> 3);
- _msg = message;
- nnn = len;
-
- /* Absorbing phase */
- if (ww == 8)
- for (i = 0; i < nnn; i += rr)
- {
- #define __S(Si, OFF) S[Si] ^= toLane64(message, len, rr, OFF)
- __S( 0, 0); __S( 5, 8); __S(10, 16); __S(15, 24); __S(20, 32);
- __S( 1, 40); __S( 6, 48); __S(11, 56); __S(16, 64); __S(21, 72);
- __S( 2, 80); __S( 7, 88); __S(12, 96); __S(17, 104); __S(22, 112);
- __S( 3, 120); __S( 8, 128); __S(13, 136); __S(18, 144); __S(23, 152);
- __S( 4, 160); __S( 9, 168); __S(14, 176); __S(19, 184); __S(24, 192);
- #undef __S
- keccakF(S);
- message += rr;
- len -= rr;
- }
- else
- for (i = 0; i < nnn; i += rr)
- {
- #define __S(Si, OFF) S[Si] ^= toLane(message, len, rr, ww, OFF * ww)
- __S( 0, 0); __S( 5, 1); __S(10, 2); __S(15, 3); __S(20, 4);
- __S( 1, 5); __S( 6, 6); __S(11, 7); __S(16, 8); __S(21, 9);
- __S( 2, 10); __S( 7, 11); __S(12, 12); __S(17, 13); __S(22, 14);
- __S( 3, 15); __S( 8, 16); __S(13, 17); __S(18, 18); __S(23, 19);
- __S( 4, 20); __S( 9, 21); __S(14, 22); __S(19, 23); __S(24, 24);
- #undef __S
- keccakF(S);
- message += rr;
- len -= rr;
- }
-
- free(_msg);
-
- /* Squeezing phase */
- olen = n;
- if (withReturn)
- {
- ni = rr / ww;
- while (olen > 0)
- {
- i = 0;
- while ((i < ni) && (j < nn))
- {
- llong v = S[(i % 5) * 5 + i / 5];
- for (_ = 0; _ < ww; _++)
- {
- if (j < nn)
- rc[ptr++] = (byte)v;
- v >>= 8;
- j += 1;
- }
- i += 1;
- }
- olen -= r;
- if (olen > 0)
- keccakF(S);
- }
- if ((n & 7))
- rc[n >> 3] &= (1 << (n & 7)) - 1;
-
- return rc;
- }
- while ((olen -= r) > 0)
- keccakF(S);
- return null;
-}
-
-
-/**
- * Force some rounds of Keccak-f
- *
- * @param times The number of rounds
- */
-void simpleSqueeze(long times)
-{
- long i;
- for (i = 0; i < times; i++)
- keccakF(S);
-}
-
-
-/**
- * Squeeze as much as is needed to get a digest a number of times
- *
- * @param times The number of digests
- */
-void fastSqueeze(long times)
-{
- long i, olen;
- for (i = 0; i < times; i++)
- {
- keccakF(S); /* Last squeeze did not do a ending squeeze */
- olen = n;
- while ((olen -= r) > 0)
- keccakF(S);
- }
-}
-
-
-/**
- * Squeeze out another digest
- *
- * @return The hash sum
- */
-byte* squeeze()
-{
- long nn, ww, olen, i, j, ptr, ni;
- byte* rc;
-
- keccakF(S); /* Last squeeze did not do a ending squeeze */
-
- ww = w >> 3;
- rc = (byte*)malloc(nn = (n + 7) >> 3);
- olen = n;
- j = ptr = 0;
- ni = (r >> 3) / ww;
-
- while (olen > 0)
- {
- i = 0;
- while ((i < ni) && (j < nn))
- {
- long _, v = S[(i % 5) * 5 + i / 5];
- for (_ = 0; _ < ww; _++)
- {
- if (j < nn)
- *(rc + ptr++) = (byte)v;
- v >>= 8;
- j += 1;
- }
- i += 1;
- }
- olen -= r;
- if (olen > 0)
- keccakF(S);
- }
- if (n & 7)
- rc[nn - 1] &= (1 << (n & 7)) - 1;
-
- return rc;
-}
-
-
-
-JNIEXPORT void JNICALL Java_SHA3_initialise(JNIEnv* env, jclass class, jint bitrate, jint capacity, jint output)
-{
- (void) env;
- (void) class;
-
- initialise(bitrate, capacity, output);
-}
-
-
-JNIEXPORT void JNICALL Java_SHA3_update(JNIEnv* env, jclass class, jbyteArray msg, jint msglen)
-{
- (void) class;
- if ((msg != null) && (msglen != 0))
- update((byte*)((*env)->GetByteArrayElements(env, msg, 0)), msglen);
-}
-
-
-JNIEXPORT jbyteArray JNICALL Java_SHA3_digest(JNIEnv* env, jclass class, jbyteArray msg, jint msglen, jint bits, jintArray suffix, jboolean withReturn)
-{
- jbyte* rcn;
- jbyteArray rcj = null;
- int* suffix_elems = (int*)((*env)->GetIntArrayElements(env, suffix, 0));
- long suffix_len = (long)((*env)->GetArrayLength(env, suffix));
-
- (void) class;
-
- if ((msg != null) && (msglen != 0))
- rcn = (jbyte*)digest((byte*)((*env)->GetByteArrayElements(env, msg, 0)), msglen,
- bits, suffix_elems, suffix_len, withReturn);
- else
- rcn = (jbyte*)digest(null, 0, 0, suffix_elems, suffix_len, withReturn);
- if (withReturn)
- {
- rcj = (*env)->NewByteArray(env, (n + 7) >> 3);
- (*env)->SetByteArrayRegion(env, rcj, 0, (n + 7) >> 3, rcn);
- }
- return rcj;
-}
-
diff --git a/java-c-jni/SHA3.java b/java-c-jni/SHA3.java
deleted file mode 100644
index 4be013e..0000000
--- a/java-c-jni/SHA3.java
+++ /dev/null
@@ -1,384 +0,0 @@
-/**
- * sha3sum – SHA-3 (Keccak) checksum calculator
- *
- * Copyright © 2013, 2014 Mattias Andrée (maandree@member.fsf.org)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-import java.io.*;
-import java.util.*;
-
-
-/**
- * SHA-3/Keccak hash algorithm implementation
- *
- * @author Mattias Andrée <a href="mailto:maandree@member.fsf.org">maandree@member.fsf.org</a>
- */
-public class SHA3
-{
- /**
- * Suffix the message when calculating the Keccak hash sum
- */
- public static final String KECCAK_SUFFIX = "";
-
- /**
- * Suffix the message when calculating the SHA-3 hash sum
- */
- public static final String SHA3_SUFFIX = "01";
-
- /**
- * Suffix the message when calculating the RawSHAKE hash sum
- */
- public static final String RawSHAKE_SUFFIX = "11";
-
- /**
- * Suffix the message when calculating the SHAKE hash sum
- */
- public static final String SHAKE_SUFFIX = "1111";
-
-
-
- /**
- * Hidden constructor
- */
- private SHA3()
- {
- // Inhibit instansiation
- }
-
-
-
- /**
- * Class initialiser
- */
- static
- {
- try
- {
- System.load((new File("./SHA3.so")).getCanonicalPath());
- }
- catch (IOException err)
- {
- throw new Error("SHA3 library cannot be found");
- }
- }
-
-
-
- /**
- * Initialise Keccak sponge
- *
- * @param r The bitrate
- * @param c The capacity
- * @param n The output size
- */
- public static native void initialise(int r, int c, int n);
-
-
- /**
- * Absorb the more of the message message to the Keccak sponge
- *
- * @param msg The partial message
- */
- public static void update(byte[] msg)
- {
- update(msg, msg.length);
- }
-
-
- /**
- * Absorb the more of the message message to the Keccak sponge
- *
- * @param msg The partial message
- * @param msglen The length of the partial message
- */
- public static native void update(byte[] msg, int msglen);
-
-
- /**
- * Squeeze the Keccak sponge
- *
- * @return The hash sum
- */
- public static byte[] digest()
- {
- return digest(null, 0, 0, SHA3.SHA3_SUFFIX, true);
- }
-
-
- /**
- * Squeeze the Keccak sponge
- *
- * @param suffix The suffix concatenate to the message
- * @return The hash sum
- */
- public static byte[] digest(String suffix)
- {
- return digest(null, 0, 0, suffix, true);
- }
-
-
- /**
- * Squeeze the Keccak sponge
- *
- * @param withReturn Whether to return the hash instead of just do a quick squeeze phrase and return {@code null}
- * @return The hash sum, or {@code null} if <tt>withReturn</tt> is {@code false}
- */
- public static byte[] digest(boolean withReturn)
- {
- return digest(null, 0, 0, SHA3.SHA3_SUFFIX, withReturn);
- }
-
-
- /**
- * Squeeze the Keccak sponge
- *
- * @param suffix The suffix concatenate to the message
- * @param withReturn Whether to return the hash instead of just do a quick squeeze phrase and return {@code null}
- * @return The hash sum, or {@code null} if <tt>withReturn</tt> is {@code false}
- */
- public static byte[] digest(String suffix, boolean withReturn)
- {
- return digest(null, 0, 0, suffix, withReturn);
- }
-
-
- /**
- * Absorb the last part of the message and squeeze the Keccak sponge
- *
- * @param msg The rest of the message
- * @return The hash sum
- */
- public static byte[] digest(byte[] msg)
- {
- return digest(msg, msg == null ? 0 : msg.length, 0, SHA3.SHA3_SUFFIX, true);
- }
-
-
- /**
- * Absorb the last part of the message and squeeze the Keccak sponge
- *
- * @param msg The rest of the message
- * @param suffix The suffix concatenate to the message
- * @return The hash sum
- */
- public static byte[] digest(byte[] msg, String suffix)
- {
- return digest(msg, msg == null ? 0 : msg.length, 0, suffix, true);
- }
-
-
- /**
- * Absorb the last part of the message and squeeze the Keccak sponge
- *
- * @param msg The rest of the message
- * @param withReturn Whether to return the hash instead of just do a quick squeeze phrase and return {@code null}
- * @return The hash sum, or {@code null} if <tt>withReturn</tt> is {@code false}
- */
- public static byte[] digest(byte[] msg, boolean withReturn)
- {
- return digest(msg, msg == null ? 0 : msg.length, 0, SHA3.SHA3_SUFFIX, withReturn);
- }
-
-
- /**
- * Absorb the last part of the message and squeeze the Keccak sponge
- *
- * @param msg The rest of the message
- * @param suffix The suffix concatenate to the message
- * @param withReturn Whether to return the hash instead of just do a quick squeeze phrase and return {@code null}
- * @return The hash sum, or {@code null} if <tt>withReturn</tt> is {@code false}
- */
- public static byte[] digest(byte[] msg, String suffix, boolean withReturn)
- {
- return digest(msg, msg == null ? 0 : msg.length, 0, suffix, withReturn);
- }
-
-
- /**
- * Absorb the last part of the message and squeeze the Keccak sponge
- *
- * @param msg The rest of the message
- * @param msglen The length of the partial message in while bytes
- * @return The hash sum
- */
- public static byte[] digest(byte[] msg, int msglen)
- {
- return digest(msg, msg == null ? 0 : msg.length, 0, SHA3.SHA3_SUFFIX, true);
- }
-
-
- /**
- * Absorb the last part of the message and squeeze the Keccak sponge
- *
- * @param msg The rest of the message
- * @param msglen The length of the partial message in while bytes
- * @param suffix The suffix concatenate to the message
- * @return The hash sum
- */
- public static byte[] digest(byte[] msg, int msglen, String suffix)
- {
- return digest(msg, msg == null ? 0 : msg.length, 0, suffix, true);
- }
-
-
- /**
- * Absorb the last part of the message and squeeze the Keccak sponge
- *
- * @param msg The rest of the message
- * @param msglen The length of the partial message in while bytes
- * @param bits The number of bits at the end of the message not covered by <tt>msglen</tt>
- * @return The hash sum
- */
- public static byte[] digest(byte[] msg, int msglen, int bits)
- {
- return digest(msg, msg == null ? 0 : msg.length, bits, SHA3.SHA3_SUFFIX, true);
- }
-
-
- /**
- * Absorb the last part of the message and squeeze the Keccak sponge
- *
- * @param msg The rest of the message
- * @param msglen The length of the partial message in while bytes
- * @param bits The number of bits at the end of the message not covered by <tt>msglen</tt>
- * @param suffix The suffix concatenate to the message
- * @return The hash sum
- */
- public static byte[] digest(byte[] msg, int msglen, int bits, String suffix)
- {
- return digest(msg, msg == null ? 0 : msg.length, bits, suffix, true);
- }
-
-
- /**
- * Absorb the last part of the message and squeeze the Keccak sponge
- *
- * @param msg The rest of the message
- * @param msglen The length of the partial message in while bytes
- * @param withReturn Whether to return the hash instead of just do a quick squeeze phrase and return {@code null}
- * @return The hash sum, or {@code null} if <tt>withReturn</tt> is {@code false}
- */
- public static byte[] digest(byte[] msg, int msglen, boolean withReturn)
- {
- return digest(msg, msg == null ? 0 : msg.length, 0, SHA3.SHA3_SUFFIX, withReturn);
- }
-
-
- /**
- * Absorb the last part of the message and squeeze the Keccak sponge
- *
- * @param msg The rest of the message
- * @param msglen The length of the partial message in while bytes
- * @param suffix The suffix concatenate to the message
- * @param withReturn Whether to return the hash instead of just do a quick squeeze phrase and return {@code null}
- * @return The hash sum, or {@code null} if <tt>withReturn</tt> is {@code false}
- */
- public static byte[] digest(byte[] msg, int msglen, String suffix, boolean withReturn)
- {
- return digest(msg, msg == null ? 0 : msg.length, 0, suffix, withReturn);
- }
-
-
- /**
- * Absorb the last part of the message and squeeze the Keccak sponge
- *
- * @param msg The rest of the message
- * @param msglen The length of the partial message in while bytes
- * @param bits The number of bits at the end of the message not covered by <tt>msglen</tt>
- * @param withReturn Whether to return the hash instead of just do a quick squeeze phrase and return {@code null}
- * @return The hash sum, or {@code null} if <tt>withReturn</tt> is {@code false}
- */
- public static byte[] digest(byte[] msg, int msglen, int bits, boolean withReturn)
- {
- return digest(msg, msg == null ? 0 : msg.length, 0, SHA3.SHA3_SUFFIX, withReturn);
- }
-
-
- /**
- * Absorb the last part of the message and squeeze the Keccak sponge
- *
- * @param msg The rest of the message
- * @param msglen The length of the partial message
- * @param bits The number of bits at the end of the message not covered by <tt>msglen</tt>
- * @param suffix The suffix concatenate to the message
- * @param withReturn Whether to return the hash instead of just do a quick squeeze phrase and return {@code null}
- * @return The hash sum, or {@code null} if <tt>withReturn</tt> is {@code false}
- */
- public static byte[] digest(byte[] msg, int msglen, int bits, String suffix, boolean withReturn)
- {
- int[] suffix_ = new int[suffix.length()];
- for (int i = 0, n = suffix_.length; i < n; i++)
- suffix_[i] = suffix.charAt(i) == '1' ? 1 : 0;
-
- return digest(msg, msglen, bits, suffix_, withReturn);
- }
-
-
- /**
- * Absorb the last part of the message and squeeze the Keccak sponge
- *
- * @param msg The rest of the message
- * @param msglen The length of the partial message
- * @param bits The number of bits at the end of the message not covered by <tt>msglen</tt>
- * @param suffix The suffix concatenate to the message
- * @param withReturn Whether to return the hash instead of just do a quick squeeze phrase and return {@code null}
- * @return The hash sum, or {@code null} if <tt>withReturn</tt> is {@code false}
- */
- public static native byte[] digest(byte[] msg, int msglen, int bits, int[] suffix, boolean withReturn);
-
-
- /**
- * Force a round of Keccak-f
- */
- public static void simpleSqueeze()
- {
- simpleSqueeze(1);
- }
-
-
- /**
- * Force some rounds of Keccak-f
- *
- * @param times The number of rounds
- */
- public static native void simpleSqueeze(int times);
-
-
- /**
- * Squeeze as much as is needed to get a digest
- */
- public static void fastSqueeze()
- {
- fastSqueeze(1);
- }
-
-
- /**
- * Squeeze as much as is needed to get a digest a number of times
- *
- * @param times The number of digests
- */
- public static native void fastSqueeze(int times);
-
-
- /**
- * Squeeze out another digest
- *
- * @return The hash sum
- */
- public static native byte[] squeeze();
-
-}
-
diff --git a/java-c-jni/sha3sum.java b/java-c-jni/sha3sum.java
deleted file mode 100644
index 9347c93..0000000
--- a/java-c-jni/sha3sum.java
+++ /dev/null
@@ -1,485 +0,0 @@
-/**
- * sha3sum – SHA-3 (Keccak) checksum calculator
- *
- * Copyright © 2013, 2014 Mattias Andrée (maandree@member.fsf.org)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-import java.io.*;
-import java.util.*;
-
-
-/**
- * SHA-3/Keccak checksum calculator
- *
- * @author Mattias Andrée <a href="mailto:maandree@member.fsf.org">maandree@member.fsf.org</a>
- */
-public class sha3sum
-{
- /**
- * This is the main entry point of the program
- *
- * @param args Command line arguments
- * @throws IOException On I/O error (such as broken pipes)
- */
- public static void main(String[] args) throws IOException
- {
- run("sha3sum", args);
- }
-
-
- /**
- * Run the program
- *
- * @param cmd The command
- * @param argv Command line arguments
- * @throws IOException On I/O error (such as broken pipes)
- */
- public static void run(String cmd, String[] argv) throws IOException
- {
- if (cmd.indexOf('/') >= 0)
- cmd = cmd.substring(cmd.lastIndexOf('/') + 1);
- if (cmd.endsWith(".jar"))
- cmd = cmd.substring(0, cmd.length() - 4);
- cmd = cmd.intern();
-
- Integer O = null; int _o = 512; /* --outputsize */
- if (cmd == "sha3-224sum") _o = 224;
- else if (cmd == "sha3-256sum") _o = 256;
- else if (cmd == "sha3-384sum") _o = 384;
- else if (cmd == "sha3-512sum") _o = 512;
- Integer S = null; int _s = 1600; /* --statesize */
- Integer C = null; int _c = _s - (_o << 1); /* --capacity */
- Integer R = null; int _r = _s - _c; /* --bitrate */
- Integer W = null; int _w = _s / 25; /* --wordsize */
- Integer I = null; int _i = 1; /* --iterations */
- Integer J = null; int _j = 1; /* --squeezes */
- int o = 0, s = 0, r = 0, c = 0, w = 0, i = 0, j = 0;
-
- boolean binary = false, hex = false;
- int multi = 0;
-
- String[] files = new String[argv.length + 1];
- int fptr = 0;
- boolean dashed = false;
- String[] linger = null;
-
- String[] args = new String[argv.length + 1];
- System.arraycopy(argv, 0, args, 0, argv.length);
- for (int a = 0, an = args.length; a < an; a++)
- { String arg = args[a];
- arg = arg == null ? null : arg.intern();
- if (linger != null)
- {
- linger[0] = linger[0].intern();
- if ((linger[0] == "-h") || (linger[0] == "--help"))
- {
- System.out.println("");
- System.out.println("SHA-3/Keccak checksum calculator");
- System.out.println("");
- System.out.println("USAGE: sha3sum [option...] < file");
- System.out.println(" sha3sum [option...] file...");
- System.out.println("");
- System.out.println("");
- System.out.println("OPTIONS:");
- System.out.println(" -r BITRATE");
- System.out.println(" --bitrate The bitrate to use for checksum. (default: " + _r + ")");
- System.out.println(" ");
- System.out.println(" -c CAPACITY");
- System.out.println(" --capacity The capacity to use for checksum. (default: " + _c + ")");
- System.out.println(" ");
- System.out.println(" -w WORDSIZE");
- System.out.println(" --wordsize The word size to use for checksum. (default: " + _w + ")");
- System.out.println(" ");
- System.out.println(" -o OUTPUTSIZE");
- System.out.println(" --outputsize The output size to use for checksum. (default: " + _o + ")");
- System.out.println(" ");
- System.out.println(" -s STATESIZE");
- System.out.println(" --statesize The state size to use for checksum. (default: " + _s + ")");
- System.out.println(" ");
- System.out.println(" -i ITERATIONS");
- System.out.println(" --iterations The number of hash iterations to run. (default: " + _i + ")");
- System.out.println(" ");
- System.out.println(" -j SQUEEZES");
- System.out.println(" --squeezes The number of hash squeezes to run. (default: " + _j + ")");
- System.out.println(" ");
- System.out.println(" -x");
- System.out.println(" --hex Read the input in hexadecimal, rather than binary.");
- System.out.println(" ");
- System.out.println(" -b");
- System.out.println(" --binary Print the checksum in binary, rather than hexadecimal.");
- System.out.println(" ");
- System.out.println(" -m");
- System.out.println(" --multi Print the checksum at all iterations.");
- System.out.println("");
- System.out.println("");
- System.out.println("COPYRIGHT:");
- System.out.println("");
- System.out.println("Copyright © 2013, 2014 Mattias Andrée (maandree@member.fsf.org)");
- System.out.println("");
- System.out.println("This program is free software: you can redistribute it and/or modify");
- System.out.println("it under the terms of the GNU Affero General Public License as published by");
- System.out.println("the Free Software Foundation, either version 3 of the License, or");
- System.out.println("(at your option) any later version.");
- System.out.println("");
- System.out.println("This program is distributed in the hope that it will be useful,");
- System.out.println("but WITHOUT ANY WARRANTY; without even the implied warranty of");
- System.out.println("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the");
- System.out.println("GNU Affero General Public License for more details.");
- System.out.println("");
- System.out.println("You should have received a copy of the GNU Affero General Public License");
- System.out.println("along with this program. If not, see <http://www.gnu.org/licenses/>.");
- System.out.println("");
- System.exit(0);
- }
- else
- {
- if (linger[1] == null)
- {
- linger[1] = arg;
- arg = null;
- }
- if ((linger[0] == "-r") || (linger[0] == "--bitrate"))
- R = Integer.valueOf(linger[1]);
- else if ((linger[0] == "-c") || (linger[0] == "--capacity"))
- C = Integer.valueOf(linger[1]);
- else if ((linger[0] == "-w") || (linger[0] == "--wordsize"))
- W = Integer.valueOf(linger[1]);
- else if ((linger[0] == "-o") || (linger[0] == "--outputsize"))
- O = Integer.valueOf(linger[1]);
- else if ((linger[0] == "-s") || (linger[0] == "--statesize"))
- S = Integer.valueOf(linger[1]);
- else if ((linger[0] == "-i") || (linger[0] == "--iterations"))
- I = Integer.valueOf(linger[1]);
- else if ((linger[0] == "-j") || (linger[0] == "--squeezes"))
- J = Integer.valueOf(linger[1]);
- else
- {
- System.err.println(cmd + ": unrecognised option: " + linger[0]);
- System.exit(1);
- }
- }
- linger = null;
- if (arg == null)
- continue;
- }
- if (arg == null)
- continue;
- if (dashed)
- files[fptr++] = arg == "-" ? null : arg;
- else if (arg == "--")
- dashed = true;
- else if (arg == "-")
- files[fptr++] = null;
- else if (arg.startsWith("--"))
- if (arg.indexOf('=') >= 0)
- linger = new String[] { arg.substring(0, arg.indexOf('=')), arg.substring(arg.indexOf('=') + 1) };
- else
- if (arg == "--binary")
- binary = true;
- else if (arg == "--multi")
- multi++;
- else if (arg == "--hex")
- hex = true;
- else
- linger = new String[] { arg, null };
- else if (arg.startsWith("-"))
- {
- arg = arg.substring(1);
- if (arg.charAt(0) == 'b')
- {
- binary = true;
- arg = arg.substring(1);
- }
- else if (arg.charAt(0) == 'm')
- {
- multi++;
- arg = arg.substring(1);
- }
- else if (arg.charAt(0) == 'x')
- {
- hex = true;
- arg = arg.substring(1);
- }
- else if (arg.length() == 1)
- linger = new String[] { "-" + arg, null };
- else
- linger = new String[] { "-" + arg.charAt(0), arg.substring(1) };
- }
- else
- files[fptr++] = arg;
- }
-
-
- i = I == null ? _i : I.intValue();
- j = J == null ? _j : J.intValue();
-
- if (S != null)
- { s = S.intValue();
- if ((s <= 0) || (s > 1600) || (s % 25 != 0))
- { System.err.println(cmd + ": the state size must be a positive multiple of 25 and is limited to 1600.");
- System.exit(6);
- } }
-
- if (W != null)
- { w = W.intValue();
- if ((w <= 0) || (w > 64))
- { System.err.println(cmd + ": the word size must be positive and is limited to 64.");
- System.exit(6);
- }
- if ((S != null) && (s != w * 25))
- { System.err.println(cmd + ": the state size must be 25 times of the word size.");
- System.exit(6);
- }
- else if (S == null)
- S = new Integer(w * 25);
- }
-
- if (C != null)
- { c = C.intValue();
- if ((c <= 0) || ((c & 7) != 0))
- { System.err.println(cmd + ": the capacity must be a positive multiple of 8.");
- System.exit(6);
- } }
-
- if (R != null)
- { r = R.intValue();
- if ((r <= 0) || ((r & 7) != 0))
- { System.err.println(cmd + ": the bitrate must be a positive multiple of 8.");
- System.exit(6);
- } }
-
- if (O != null)
- { o = O.intValue();
- if (o <= 0)
- { System.err.println(cmd + ": the output size must be positive.");
- System.exit(6);
- } }
-
-
- if ((R == null) && (C == null) && (O == null)) // s?
- { c = -((r = (o = ((((s = S == null ? _s : s) << 5) / 100 + 7) >> 3) << 3) << 1) - s);
- o = o < 8 ? 8 : o;
- }
- else if ((R == null) && (C == null)) // !o s?
- { r = _r;
- c = _c;
- s = S == null ? (r + c) : s;
- }
- else if (R == null) // !c o? s?
- { r = (s = S == null ? _s : s) - c;
- o = O == null ? (c == 8 ? 8 : (c << 1)) : o;
- }
- else if (C == null) // !r o? s?
- { c = (s = S == null ? _s : s) - r;
- o = O == null ? (c == 8 ? 8 : (c << 1)) : o;
- }
- else // !r !c o? s?
- { s = S == null ? (r + c) : s;
- o = O == null ? (c == 8 ? 8 : (c << 1)) : o;
- }
-
-
- System.err.println("Bitrate: " + r);
- System.err.println("Capacity: " + c);
- System.err.println("Word size: " + w);
- System.err.println("State size: " + s);
- System.err.println("Output size: " + o);
- System.err.println("Iterations: " + i);
- System.err.println("Squeezes: " + j);
-
-
- if (r > s)
- { System.err.println(cmd + ": the bitrate must not be higher than the state size.");
- System.exit(6);
- }
- if (c > s)
- { System.err.println(cmd + ": the capacity must not be higher than the state size.");
- System.exit(6);
- }
- if (r + c != s)
- { System.err.println(cmd + ": the sum of the bitrate and the capacity must equal the state size.");
- System.exit(6);
- }
-
-
- if (fptr == 0)
- files[fptr++] = null;
- if (i < 1)
- {
- System.err.println(cmd + ": sorry, I will only do at least one hash iteration!");
- System.exit(3);
- }
- if (j < 1)
- {
- System.err.println(cmd + ": sorry, I will only do at least one squeeze iteration!");
- System.exit(3);
- }
-
- byte[] stdin = null;
- boolean fail = false;
- String filename;
-
- for (int f = 0; f < fptr; f++)
- { String rc = "";
- String fn = (filename = files[f]) == null ? "/dev/stdin" : filename;
- InputStream file = null;
- try
- {
- byte[] bs;
- if ((filename != null) || (stdin == null))
- {
- file = new FileInputStream(fn);
- SHA3.initialise(r, c, o);
- int blksize = 4096; /** XXX os.stat(os.path.realpath(fn)).st_size; **/
- byte[] chunk = new byte[blksize];
- for (;;)
- {
- int read = file.read(chunk, 0, blksize);
- if (read <= 0)
- break;
- if (hex == false)
- SHA3.update(chunk, read);
- else
- {
- int n = read >> 1;
- for (int k = 0; k < n; k++)
- { byte a = chunk[k << 1], b = chunk[(k << 1) | 1];
- chunk[k] = (byte)((((a & 15) + (a <= '9' ? 0 : 9)) << 4) | ((b & 15) + (b <= '9' ? 0 : 9)));
- }
- SHA3.update(chunk, n);
- }
- }
- bs = SHA3.digest(j == 1);
- if (j > 2)
- SHA3.fastSqueeze(j - 2);
- if (j > 1)
- bs = SHA3.squeeze();
- if (filename == null)
- stdin = bs;
- }
- else
- bs = stdin;
- if (multi == 0)
- {
- for (int k = 1; k < i; k++)
- {
- SHA3.initialise(r, c, o);
- bs = SHA3.digest(bs, j == 1);
- if (j > 2)
- SHA3.fastSqueeze(j - 2);
- if (j > 1)
- bs = SHA3.squeeze();
- }
- if (binary)
- System.out.write(bs);
- else
- { for (int b = 0, bn = bs.length; b < bn; b++)
- { rc += "0123456789ABCDEF".charAt((bs[b] >> 4) & 15);
- rc += "0123456789ABCDEF".charAt(bs[b] & 15);
- }
- rc += " " + (filename == null ? "-" : filename) + "\n";
- System.out.print(rc);
- }
- }
- else if (multi == 1)
- {
- byte[] out = null;
- if (binary)
- System.out.write(bs);
- else
- {
- out = new byte[(bs.length << 1) + 1];
- for (int b = 0, bn = bs.length; b < bn; b++)
- { out[ b << 1 ] = (byte)("0123456789ABCDEF".charAt((bs[b] >> 4) & 15));
- out[(b << 1) | 1] = (byte)("0123456789ABCDEF".charAt(bs[b] & 15));
- }
- out[out.length - 1] = '\n';
- System.out.write(out);
- }
- for (int k = 1; k < i; k++)
- {
- SHA3.initialise(r, c, o);
- bs = SHA3.digest(bs, j == 1);
- if (j > 2)
- SHA3.fastSqueeze(j - 2);
- if (j > 1)
- bs = SHA3.squeeze();
- if (binary)
- System.out.write(bs);
- else
- {
- for (int b = 0, bn = bs.length; b < bn; b++)
- { out[ b << 1 ] = (byte)("0123456789ABCDEF".charAt((bs[b] >> 4) & 15));
- out[(b << 1) | 1] = (byte)("0123456789ABCDEF".charAt(bs[b] & 15));
- }
- System.out.write(out);
- }
- }
- }
- else
- {
- HashSet<String> got = new HashSet<String>();
- String loop = null;
- byte[] out = new byte[(bs.length << 1)];
- for (int k = 0; k < i; k++)
- {
- if (k > 0)
- { SHA3.initialise(r, c, o);
- bs = SHA3.digest(bs, j == 1);
- if (j > 2)
- SHA3.fastSqueeze(j - 2);
- if (j > 1)
- bs = SHA3.squeeze();
- }
- for (int b = 0, bn = bs.length; b < bn; b++)
- { out[ b << 1 ] = (byte)("0123456789ABCDEF".charAt((bs[b] >> 4) & 15));
- out[(b << 1) | 1] = (byte)("0123456789ABCDEF".charAt(bs[b] & 15));
- }
- String now = new String(out, "UTF-8");
- if (loop == null)
- if (got.contains(now))
- loop = now;
- else
- got.add(now);
- if ((loop != null) && (loop.equals(now)))
- now = "\033[31m" + now + "\033[00m";
- System.out.println(now);
- }
- if (loop != null)
- System.err.println("\033[01;31mLoop found\033[00m");
- }
- System.out.flush();
- }
- catch (final IOException err)
- { System.err.println(cmd + ": cannot read file: " + filename + ": " + err);
- fail = true;
- }
- finally
- { if (file != null)
- try
- { file.close();
- }
- catch (final Throwable ignore)
- { //ignore
- } } }
-
- System.out.flush();
- if (fail)
- System.exit(5);
- }
-
-}
-
diff --git a/java/ConcurrentSHA3.java b/java/ConcurrentSHA3.java
deleted file mode 100644
index 69425b9..0000000
--- a/java/ConcurrentSHA3.java
+++ /dev/null
@@ -1,963 +0,0 @@
-/**
- * sha3sum – SHA-3 (Keccak) checksum calculator
- *
- * Copyright © 2013, 2014 Mattias Andrée (maandree@member.fsf.org)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-/**
- * SHA-3/Keccak hash algorithm implementation with support for concurrent threads
- *
- * @author Mattias Andrée <a href="mailto:maandree@member.fsf.org">maandree@member.fsf.org</a>
- */
-public class ConcurrentSHA3
-{
- /**
- * Suffix the message when calculating the Keccak hash sum
- */
- public static final String KECCAK_SUFFIX = "";
-
- /**
- * Suffix the message when calculating the SHA-3 hash sum
- */
- public static final String SHA3_SUFFIX = "01";
-
- /**
- * Suffix the message when calculating the RawSHAKE hash sum
- */
- public static final String RawSHAKE_SUFFIX = "11";
-
- /**
- * Suffix the message when calculating the SHAKE hash sum
- */
- public static final String SHAKE_SUFFIX = "1111";
-
-
- /**
- * Round contants
- */
- private static final long[] RC = {
- 0x0000000000000001L, 0x0000000000008082L, 0x800000000000808AL, 0x8000000080008000L,
- 0x000000000000808BL, 0x0000000080000001L, 0x8000000080008081L, 0x8000000000008009L,
- 0x000000000000008AL, 0x0000000000000088L, 0x0000000080008009L, 0x000000008000000AL,
- 0x000000008000808BL, 0x800000000000008BL, 0x8000000000008089L, 0x8000000000008003L,
- 0x8000000000008002L, 0x8000000000000080L, 0x000000000000800AL, 0x800000008000000AL,
- 0x8000000080008081L, 0x8000000000008080L, 0x0000000080000001L, 0x8000000080008008L};
-
-
-
- /**
- * <p>Constructor</p>
- * <p>
- * Do not forget to run {@link #Initialise(int, int, int)}
- * </p>
- */
- public ConcurrentSHA3()
- {
- /* Do nothing */
- }
-
-
-
- /**
- * Keccak-f round temporary
- */
- private long[] B = new long[25];
-
- /**
- * Keccak-f round temporary
- */
- private long[] C = new long[5];
-
-
- /**
- * The bitrate
- */
- private int r = 0;
-
- /**
- * The capacity
- */
- private int c = 0;
-
- /**
- * The output size
- */
- private int n = 0;
-
- /**
- * The state size
- */
- private int b = 0;
-
- /**
- * The word size
- */
- private int w = 0;
-
- /**
- * The word mask
- */
- private long wmod = 0;
-
- /**
- * ℓ, the binary logarithm of the word size
- */
- private int l = 0;
-
- /**
- * 12 + 2ℓ, the number of rounds
- */
- private int nr = 0;
-
-
- /**
- * Message chunk that is being processed
- */
- private byte[] message = null;
-
- /**
- * The current state
- */
- private long[] S = null;
-
- /**
- * Left over water to fill the sponge with at next update
- */
- private byte[] M = null;
-
- /**
- * Pointer for {@link #M}
- */
- private int mptr = 0;
-
-
-
- /**
- * Rotate a word
- *
- * @param x The value to rotate
- * @param n Rotation steps, may not be 0
- * @return The value rotated
- */
- private long rotate(long x, int n)
- {
- long m;
- return ((x >>> (this.w - (m = n % this.w))) + (x << m)) & this.wmod;
- }
-
-
- /**
- * Rotate a 64-bit word
- *
- * @param x The value to rotate
- * @param n Rotation steps, may not be 0
- * @return The value rotated
- */
- private static long rotate64(long x, int n)
- {
- return (x >>> (64 - n)) + (x << n);
- }
-
-
- /**
- * Binary logarithm
- *
- * @param x The value of which to calculate the binary logarithm
- * @return The binary logarithm
- */
- private static int lb(int x)
- {
- int rc = 0;
- if ((x & 0xFF00) != 0) { rc += 8; x >>= 8; }
- if ((x & 0x00F0) != 0) { rc += 4; x >>= 4; }
- if ((x & 0x000C) != 0) { rc += 2; x >>= 2; }
- if ((x & 0x0002) != 0) rc += 1;
- return rc;
- }
-
- /**
- * Perform one round of computation
- *
- * @param A The current state
- * @param rc Round constant
- */
- private void keccakFRound(long[] A, long rc)
- {
- /* θ step (step 1 of 3) */
- for (int i = 0, j = 0; i < 5; i++, j += 5)
- this.C[i] = (A[j] ^ A[j + 1]) ^ (A[j + 2] ^ A[j + 3]) ^ A[j + 4];
-
- long da, db, dc, dd, de;
-
- if (this.w == 64)
- {
- /* ρ and π steps, with last two part of θ */
- this.B[0] = A[ 0] ^ (da = this.C[4] ^ ConcurrentSHA3.rotate64(this.C[1], 1));
- this.B[1] = ConcurrentSHA3.rotate64(A[15] ^ (dd = this.C[2] ^ ConcurrentSHA3.rotate64(this.C[4], 1)), 28);
- this.B[2] = ConcurrentSHA3.rotate64(A[ 5] ^ (db = this.C[0] ^ ConcurrentSHA3.rotate64(this.C[2], 1)), 1);
- this.B[3] = ConcurrentSHA3.rotate64(A[20] ^ (de = this.C[3] ^ ConcurrentSHA3.rotate64(this.C[0], 1)), 27);
- this.B[4] = ConcurrentSHA3.rotate64(A[10] ^ (dc = this.C[1] ^ ConcurrentSHA3.rotate64(this.C[3], 1)), 62);
-
- this.B[5] = ConcurrentSHA3.rotate64(A[ 6] ^ db, 44);
- this.B[6] = ConcurrentSHA3.rotate64(A[21] ^ de, 20);
- this.B[7] = ConcurrentSHA3.rotate64(A[11] ^ dc, 6);
- this.B[8] = ConcurrentSHA3.rotate64(A[ 1] ^ da, 36);
- this.B[9] = ConcurrentSHA3.rotate64(A[16] ^ dd, 55);
-
- this.B[10] = ConcurrentSHA3.rotate64(A[12] ^ dc, 43);
- this.B[11] = ConcurrentSHA3.rotate64(A[ 2] ^ da, 3);
- this.B[12] = ConcurrentSHA3.rotate64(A[17] ^ dd, 25);
- this.B[13] = ConcurrentSHA3.rotate64(A[ 7] ^ db, 10);
- this.B[14] = ConcurrentSHA3.rotate64(A[22] ^ de, 39);
-
- this.B[15] = ConcurrentSHA3.rotate64(A[18] ^ dd, 21);
- this.B[16] = ConcurrentSHA3.rotate64(A[ 8] ^ db, 45);
- this.B[17] = ConcurrentSHA3.rotate64(A[23] ^ de, 8);
- this.B[18] = ConcurrentSHA3.rotate64(A[13] ^ dc, 15);
- this.B[19] = ConcurrentSHA3.rotate64(A[ 3] ^ da, 41);
-
- this.B[20] = ConcurrentSHA3.rotate64(A[24] ^ de, 14);
- this.B[21] = ConcurrentSHA3.rotate64(A[14] ^ dc, 61);
- this.B[22] = ConcurrentSHA3.rotate64(A[ 4] ^ da, 18);
- this.B[23] = ConcurrentSHA3.rotate64(A[19] ^ dd, 56);
- this.B[24] = ConcurrentSHA3.rotate64(A[ 9] ^ db, 2);
- }
- else
- {
- /* ρ and π steps, with last two part of θ */
- this.B[0] = A[ 0] ^ (da = this.C[4] ^ this.rotate(this.C[1], 1));
- this.B[1] = this.rotate(A[15] ^ (dd = this.C[2] ^ this.rotate(this.C[4], 1)), 28);
- this.B[2] = this.rotate(A[ 5] ^ (db = this.C[0] ^ this.rotate(this.C[2], 1)), 1);
- this.B[3] = this.rotate(A[20] ^ (de = this.C[3] ^ this.rotate(this.C[0], 1)), 27);
- this.B[4] = this.rotate(A[10] ^ (dc = this.C[1] ^ this.rotate(this.C[3], 1)), 62);
-
- this.B[5] = this.rotate(A[ 6] ^ db, 44);
- this.B[6] = this.rotate(A[21] ^ de, 20);
- this.B[7] = this.rotate(A[11] ^ dc, 6);
- this.B[8] = this.rotate(A[ 1] ^ da, 36);
- this.B[9] = this.rotate(A[16] ^ dd, 55);
-
- this.B[10] = this.rotate(A[12] ^ dc, 43);
- this.B[11] = this.rotate(A[ 2] ^ da, 3);
- this.B[12] = this.rotate(A[17] ^ dd, 25);
- this.B[13] = this.rotate(A[ 7] ^ db, 10);
- this.B[14] = this.rotate(A[22] ^ de, 39);
-
- this.B[15] = this.rotate(A[18] ^ dd, 21);
- this.B[16] = this.rotate(A[ 8] ^ db, 45);
- this.B[17] = this.rotate(A[23] ^ de, 8);
- this.B[18] = this.rotate(A[13] ^ dc, 15);
- this.B[19] = this.rotate(A[ 3] ^ da, 41);
-
- this.B[20] = this.rotate(A[24] ^ de, 14);
- this.B[21] = this.rotate(A[14] ^ dc, 61);
- this.B[22] = this.rotate(A[ 4] ^ da, 18);
- this.B[23] = this.rotate(A[19] ^ dd, 56);
- this.B[24] = this.rotate(A[ 9] ^ db, 2);
- }
-
- /* ξ step */
- for (int i = 0; i < 15; i++)
- A[i ] = this.B[i ] ^ ((~(this.B[i + 5])) & this.B[i + 10]);
- for (int i = 0; i < 5; i++)
- {
- A[i + 15] = this.B[i + 15] ^ ((~(this.B[i + 20])) & this.B[i ]);
- A[i + 20] = this.B[i + 20] ^ ((~(this.B[i ])) & this.B[i + 5]);
- }
-
- /* ι step */
- A[0] ^= rc;
- }
-
-
- /**
- * Perform Keccak-f function
- *
- * @param A The current state
- */
- private void keccakF(long[] A)
- {
- if (this.nr == 24)
- for (int i = 0; i < 24; i++)
- this.keccakFRound(A, ConcurrentSHA3.RC[i]);
- else
- for (int i = 0; i < this.nr; i++)
- this.keccakFRound(A, ConcurrentSHA3.RC[i] & this.wmod);
- }
-
-
- /**
- * Convert a chunk of byte:s to a word
- *
- * @param n {@code Math.min(SHA3.message.length, rr) + msgoff}
- * msgoff The number of times to loop has run times the bitrate
- * rr Bitrate in bytes
- * @param ww Word size in bytes
- * @param off The offset in the message
- * @return Lane
- */
- private long toLane(int n, int ww, int off)
- {
- long rc = 0;
- for (int i = off + ww - 1; i >= off; i--)
- rc = (rc << 8) | ((i < n) ? (long)(this.message[i] & 255) : 0L);
- return rc;
- }
-
-
- /**
- * Convert a chunk of byte:s to a 64-bit word
- *
- * @param n {@code Math.min(SHA3.message.length, rr) + msgoff}
- * msgoff The number of times to loop has run times the bitrate
- * rr Bitrate in bytes
- * @param off The offset in the message
- * @return Lane
- */
- private long toLane64(int n, int off)
- {
- return ((off + 7 < n) ? ((long)(this.message[off + 7] & 255) << 56) : 0L) |
- ((off + 6 < n) ? ((long)(this.message[off + 6] & 255) << 48) : 0L) |
- ((off + 5 < n) ? ((long)(this.message[off + 5] & 255) << 40) : 0L) |
- ((off + 4 < n) ? ((long)(this.message[off + 4] & 255) << 32) : 0L) |
- ((off + 3 < n) ? ((long)(this.message[off + 3] & 255) << 24) : 0L) |
- ((off + 2 < n) ? ((long)(this.message[off + 2] & 255) << 16) : 0L) |
- ((off + 1 < n) ? ((long)(this.message[off + 1] & 255) << 8) : 0L) |
- ((off < n) ? ((long)(this.message[off] & 255)) : 0L);
- }
-
-
- /**
- * pad 10*1
- *
- * @param msg The message to pad
- * @param len The length of the message
- * @param r The bitrate
- * @param bits The number of bits in the end of the message that does not make a whole byte
- * @return The actual length of {@link #message}
- */
- private int pad10star1(byte[] msg, int len, int r, int bits)
- {
- len = ((len - (bits + 7) / 8) << 3) + bits;
-
- int nrf = len >> 3;
- int nbrf = len & 7;
- int ll = len % r;
-
- byte b = (byte)(nbrf == 0 ? 1 : (msg[nrf] | (1 << nbrf)));
-
- if ((r - 8 <= ll) && (ll <= r - 2))
- {
- this.message = new byte[len = nrf + 1];
- this.message[nrf] = (byte)(b ^ 128);
- }
- else
- {
- len = (nrf + 1) << 3;
- len = ((len - (len % r) + (r - 8)) >> 3) + 1;
- this.message = new byte[len];
- this.message[nrf] = b;
- this.message[len - 1] = -128;
- }
-
- System.arraycopy(msg, 0, this.message, 0, nrf);
- return len;
- }
-
-
- /**
- * Initialise Keccak sponge
- *
- * @param r The bitrate
- * @param c The capacity
- * @param n The output size
- */
- public void initialise(int r, int c, int n)
- {
- this.r = r;
- this.c = c;
- this.n = n;
- this.b = r + c;
- this.w = this.b / 25;
- this.l = ConcurrentSHA3.lb(this.w);
- this.nr = 12 + (this.l << 1);
- this.wmod = w == 64 ? -1L : (1L << this.w) - 1L;
- this.S = new long[25];
- if ((this.M == null) || ((this.r * this.b) >> 2 != this.M.length))
- this.M = new byte[(this.r * this.b) >> 2];
- this.mptr = 0;
- if (this.message == null)
- this.message = new byte[8 << 10];
- }
-
-
- /**
- * Absorb the more of the message message to the Keccak sponge
- *
- * @param msg The partial message
- */
- public void update(byte[] msg)
- {
- this.update(msg, msg.length);
- }
-
-
- /**
- * Absorb the more of the message message to the Keccak sponge
- *
- * @param msg The partial message
- * @param msglen The length of the partial message
- */
- public void update(byte[] msg, int msglen)
- {
- int rr = this.r >> 3;
- int ww = this.w >> 3;
-
- if (this.mptr + msglen > this.M.length)
- System.arraycopy(this.M, 0, this.M = new byte[(this.M.length + msglen) << 1], 0, this.mptr);
- System.arraycopy(msg, 0, this.M, this.mptr, msglen);
- int len = this.mptr += msglen;
- len -= len % ((this.r * this.b) >> 3);
- System.arraycopy(this.M, 0, (this.message.length < len) ? (this.message = new byte[len]) : this.message, 0, len);
- System.arraycopy(this.M, len, this.M, 0, this.mptr -= len);
- int n = Math.min(len, rr);
-
- /* Absorbing phase */
- if (ww == 8)
- for (int i = 0; i < len; i += rr)
- {
- this.S[ 0] ^= this.toLane64(n, i + 0);
- this.S[ 5] ^= this.toLane64(n, i + 8);
- this.S[10] ^= this.toLane64(n, i + 16);
- this.S[15] ^= this.toLane64(n, i + 24);
- this.S[20] ^= this.toLane64(n, i + 32);
- this.S[ 1] ^= this.toLane64(n, i + 40);
- this.S[ 6] ^= this.toLane64(n, i + 48);
- this.S[11] ^= this.toLane64(n, i + 56);
- this.S[16] ^= this.toLane64(n, i + 64);
- this.S[21] ^= this.toLane64(n, i + 72);
- this.S[ 2] ^= this.toLane64(n, i + 80);
- this.S[ 7] ^= this.toLane64(n, i + 88);
- this.S[12] ^= this.toLane64(n, i + 96);
- this.S[17] ^= this.toLane64(n, i + 104);
- this.S[22] ^= this.toLane64(n, i + 112);
- this.S[ 3] ^= this.toLane64(n, i + 120);
- this.S[ 8] ^= this.toLane64(n, i + 128);
- this.S[13] ^= this.toLane64(n, i + 136);
- this.S[18] ^= this.toLane64(n, i + 144);
- this.S[23] ^= this.toLane64(n, i + 152);
- this.S[ 4] ^= this.toLane64(n, i + 160);
- this.S[ 9] ^= this.toLane64(n, i + 168);
- this.S[14] ^= this.toLane64(n, i + 176);
- this.S[19] ^= this.toLane64(n, i + 184);
- this.S[24] ^= this.toLane64(n, i + 192);
- this.keccakF(this.S);
- n += rr;
- }
- else
- for (int i = 0; i < len; i += rr)
- {
- this.S[ 0] ^= this.toLane(n, ww, i + 0 );
- this.S[ 5] ^= this.toLane(n, ww, i + ww);
- this.S[10] ^= this.toLane(n, ww, i + 2 * ww);
- this.S[15] ^= this.toLane(n, ww, i + 3 * ww);
- this.S[20] ^= this.toLane(n, ww, i + 4 * ww);
- this.S[ 1] ^= this.toLane(n, ww, i + 5 * ww);
- this.S[ 6] ^= this.toLane(n, ww, i + 6 * ww);
- this.S[11] ^= this.toLane(n, ww, i + 7 * ww);
- this.S[16] ^= this.toLane(n, ww, i + 8 * ww);
- this.S[21] ^= this.toLane(n, ww, i + 9 * ww);
- this.S[ 2] ^= this.toLane(n, ww, i + 10 * ww);
- this.S[ 7] ^= this.toLane(n, ww, i + 11 * ww);
- this.S[12] ^= this.toLane(n, ww, i + 12 * ww);
- this.S[17] ^= this.toLane(n, ww, i + 13 * ww);
- this.S[22] ^= this.toLane(n, ww, i + 14 * ww);
- this.S[ 3] ^= this.toLane(n, ww, i + 15 * ww);
- this.S[ 8] ^= this.toLane(n, ww, i + 16 * ww);
- this.S[13] ^= this.toLane(n, ww, i + 17 * ww);
- this.S[18] ^= this.toLane(n, ww, i + 18 * ww);
- this.S[23] ^= this.toLane(n, ww, i + 19 * ww);
- this.S[ 4] ^= this.toLane(n, ww, i + 20 * ww);
- this.S[ 9] ^= this.toLane(n, ww, i + 21 * ww);
- this.S[14] ^= this.toLane(n, ww, i + 22 * ww);
- this.S[19] ^= this.toLane(n, ww, i + 23 * ww);
- this.S[24] ^= this.toLane(n, ww, i + 24 * ww);
- this.keccakF(this.S);
- n += rr;
- }
- }
-
-
- /**
- * Squeeze the Keccak sponge
- *
- * @return The hash sum
- */
- public byte[] digest()
- {
- return digest(null, 0, 0, SHA3.SHA3_SUFFIX, true);
- }
-
-
- /**
- * Squeeze the Keccak sponge
- *
- * @param suffix The suffix concatenate to the message
- * @return The hash sum
- */
- public byte[] digest(String suffix)
- {
- return digest(null, 0, 0, suffix, true);
- }
-
-
- /**
- * Squeeze the Keccak sponge
- *
- * @param withReturn Whether to return the hash instead of just do a quick squeeze phrase and return {@code null}
- * @return The hash sum, or {@code null} if <tt>withReturn</tt> is {@code false}
- */
- public byte[] digest(boolean withReturn)
- {
- return digest(null, 0, 0, SHA3.SHA3_SUFFIX, withReturn);
- }
-
-
- /**
- * Squeeze the Keccak sponge
- *
- * @param suffix The suffix concatenate to the message
- * @param withReturn Whether to return the hash instead of just do a quick squeeze phrase and return {@code null}
- * @return The hash sum, or {@code null} if <tt>withReturn</tt> is {@code false}
- */
- public byte[] digest(String suffix, boolean withReturn)
- {
- return digest(null, 0, 0, suffix, withReturn);
- }
-
-
- /**
- * Absorb the last part of the message and squeeze the Keccak sponge
- *
- * @param msg The rest of the message
- * @return The hash sum
- */
- public byte[] digest(byte[] msg)
- {
- return digest(msg, msg == null ? 0 : msg.length, 0, SHA3.SHA3_SUFFIX, true);
- }
-
-
- /**
- * Absorb the last part of the message and squeeze the Keccak sponge
- *
- * @param msg The rest of the message
- * @param suffix The suffix concatenate to the message
- * @return The hash sum
- */
- public byte[] digest(byte[] msg, String suffix)
- {
- return digest(msg, msg == null ? 0 : msg.length, 0, suffix, true);
- }
-
-
- /**
- * Absorb the last part of the message and squeeze the Keccak sponge
- *
- * @param msg The rest of the message
- * @param withReturn Whether to return the hash instead of just do a quick squeeze phrase and return {@code null}
- * @return The hash sum, or {@code null} if <tt>withReturn</tt> is {@code false}
- */
- public byte[] digest(byte[] msg, boolean withReturn)
- {
- return digest(msg, msg == null ? 0 : msg.length, 0, SHA3.SHA3_SUFFIX, withReturn);
- }
-
-
- /**
- * Absorb the last part of the message and squeeze the Keccak sponge
- *
- * @param msg The rest of the message
- * @param suffix The suffix concatenate to the message
- * @param withReturn Whether to return the hash instead of just do a quick squeeze phrase and return {@code null}
- * @return The hash sum, or {@code null} if <tt>withReturn</tt> is {@code false}
- */
- public byte[] digest(byte[] msg, String suffix, boolean withReturn)
- {
- return digest(msg, msg == null ? 0 : msg.length, 0, suffix, withReturn);
- }
-
-
- /**
- * Absorb the last part of the message and squeeze the Keccak sponge
- *
- * @param msg The rest of the message
- * @param msglen The length of the partial message in while bytes
- * @return The hash sum
- */
- public byte[] digest(byte[] msg, int msglen)
- {
- return digest(msg, msg == null ? 0 : msg.length, 0, SHA3.SHA3_SUFFIX, true);
- }
-
-
- /**
- * Absorb the last part of the message and squeeze the Keccak sponge
- *
- * @param msg The rest of the message
- * @param msglen The length of the partial message in while bytes
- * @param suffix The suffix concatenate to the message
- * @return The hash sum
- */
- public byte[] digest(byte[] msg, int msglen, String suffix)
- {
- return digest(msg, msg == null ? 0 : msg.length, 0, suffix, true);
- }
-
-
- /**
- * Absorb the last part of the message and squeeze the Keccak sponge
- *
- * @param msg The rest of the message
- * @param msglen The length of the partial message in while bytes
- * @param bits The number of bits at the end of the message not covered by <tt>msglen</tt>
- * @return The hash sum
- */
- public byte[] digest(byte[] msg, int msglen, int bits)
- {
- return digest(msg, msg == null ? 0 : msg.length, bits, SHA3.SHA3_SUFFIX, true);
- }
-
-
- /**
- * Absorb the last part of the message and squeeze the Keccak sponge
- *
- * @param msg The rest of the message
- * @param msglen The length of the partial message in while bytes
- * @param bits The number of bits at the end of the message not covered by <tt>msglen</tt>
- * @param suffix The suffix concatenate to the message
- * @return The hash sum
- */
- public byte[] digest(byte[] msg, int msglen, int bits, String suffix)
- {
- return digest(msg, msg == null ? 0 : msg.length, bits, suffix, true);
- }
-
-
- /**
- * Absorb the last part of the message and squeeze the Keccak sponge
- *
- * @param msg The rest of the message
- * @param msglen The length of the partial message in while bytes
- * @param withReturn Whether to return the hash instead of just do a quick squeeze phrase and return {@code null}
- * @return The hash sum, or {@code null} if <tt>withReturn</tt> is {@code false}
- */
- public byte[] digest(byte[] msg, int msglen, boolean withReturn)
- {
- return digest(msg, msg == null ? 0 : msg.length, 0, SHA3.SHA3_SUFFIX, withReturn);
- }
-
-
- /**
- * Absorb the last part of the message and squeeze the Keccak sponge
- *
- * @param msg The rest of the message
- * @param msglen The length of the partial message in while bytes
- * @param suffix The suffix concatenate to the message
- * @param withReturn Whether to return the hash instead of just do a quick squeeze phrase and return {@code null}
- * @return The hash sum, or {@code null} if <tt>withReturn</tt> is {@code false}
- */
- public byte[] digest(byte[] msg, int msglen, String suffix, boolean withReturn)
- {
- return digest(msg, msg == null ? 0 : msg.length, 0, suffix, withReturn);
- }
-
-
- /**
- * Absorb the last part of the message and squeeze the Keccak sponge
- *
- * @param msg The rest of the message
- * @param msglen The length of the partial message in while bytes
- * @param bits The number of bits at the end of the message not covered by <tt>msglen</tt>
- * @param withReturn Whether to return the hash instead of just do a quick squeeze phrase and return {@code null}
- * @return The hash sum, or {@code null} if <tt>withReturn</tt> is {@code false}
- */
- public byte[] digest(byte[] msg, int msglen, int bits, boolean withReturn)
- {
- return digest(msg, msg == null ? 0 : msg.length, 0, SHA3.SHA3_SUFFIX, withReturn);
- }
-
-
- /**
- * Absorb the last part of the message and squeeze the Keccak sponge
- *
- * @param msg The rest of the message
- * @param msglen The length of the partial message
- * @param bits The number of bits at the end of the message not covered by <tt>msglen</tt>
- * @param suffix The suffix concatenate to the message
- * @param withReturn Whether to return the hash instead of just do a quick squeeze phrase and return {@code null}
- * @return The hash sum, or {@code null} if <tt>withReturn</tt> is {@code false}
- */
- public byte[] digest(byte[] msg, int msglen, int bits, String suffix, boolean withReturn)
- {
- int len;
- byte last_byte = 0;
- if ((msg == null) || (msglen == 0))
- {
- msg = new byte[0];
- bits = 0;
- }
-
- msglen += bits / 8;
- if ((bits %= 8) != 0)
- last_byte = msg[msglen];
-
- byte[] msg_end = new byte[(suffix.length() + bits + 7) / 8];
- int msg_end_ptr = 0;
- for (int i = 0, n = suffix.length(); i < n; i++)
- {
- byte bit = (byte)(suffix.charAt(i) - '0');
- last_byte |= bit << bits++;
- if (bits == 8)
- {
- msg_end[msg_end_ptr++] = last_byte;
- last_byte = 0;
- bits = 0;
- }
- }
- if (bits != 0)
- msg_end[msg_end_ptr++] = last_byte;
- if (msg_end_ptr > 0)
- {
- if (msglen + msg_end_ptr > msg.length)
- System.arraycopy(msg, 0, msg = new byte[msglen + msg_end_ptr], 0, msglen);
- System.arraycopy(msg_end, 0, msg, msglen, msg_end_ptr);
- msglen += msg_end_ptr;
- }
-
- if (this.mptr + msglen > this.M.length)
- System.arraycopy(this.M, 0, this.M = new byte[this.M.length + msglen], 0, this.mptr);
- System.arraycopy(msg, 0, this.M, this.mptr, msglen);
- len = this.pad10star1(this.M, this.mptr + msglen, this.r, bits);
-
- int rr = this.r >> 3;
- int nn = (this.n + 7) >> 3;
- int ww = this.w >> 3;
-
- int n = Math.min(len, rr);
-
- /* Absorbing phase */
- if (ww == 8)
- for (int i = 0; i < len; i += rr)
- {
- this.S[ 0] ^= this.toLane64(n, i + 0);
- this.S[ 5] ^= this.toLane64(n, i + 8);
- this.S[10] ^= this.toLane64(n, i + 16);
- this.S[15] ^= this.toLane64(n, i + 24);
- this.S[20] ^= this.toLane64(n, i + 32);
- this.S[ 1] ^= this.toLane64(n, i + 40);
- this.S[ 6] ^= this.toLane64(n, i + 48);
- this.S[11] ^= this.toLane64(n, i + 56);
- this.S[16] ^= this.toLane64(n, i + 64);
- this.S[21] ^= this.toLane64(n, i + 72);
- this.S[ 2] ^= this.toLane64(n, i + 80);
- this.S[ 7] ^= this.toLane64(n, i + 88);
- this.S[12] ^= this.toLane64(n, i + 96);
- this.S[17] ^= this.toLane64(n, i + 104);
- this.S[22] ^= this.toLane64(n, i + 112);
- this.S[ 3] ^= this.toLane64(n, i + 120);
- this.S[ 8] ^= this.toLane64(n, i + 128);
- this.S[13] ^= this.toLane64(n, i + 136);
- this.S[18] ^= this.toLane64(n, i + 144);
- this.S[23] ^= this.toLane64(n, i + 152);
- this.S[ 4] ^= this.toLane64(n, i + 160);
- this.S[ 9] ^= this.toLane64(n, i + 168);
- this.S[14] ^= this.toLane64(n, i + 176);
- this.S[19] ^= this.toLane64(n, i + 184);
- this.S[24] ^= this.toLane64(n, i + 192);
- this.keccakF(this.S);
- n += rr;
- }
- else
- for (int i = 0; i < len; i += rr)
- {
- this.S[ 0] ^= this.toLane(n, ww, i + 0 );
- this.S[ 5] ^= this.toLane(n, ww, i + ww);
- this.S[10] ^= this.toLane(n, ww, i + 2 * ww);
- this.S[15] ^= this.toLane(n, ww, i + 3 * ww);
- this.S[20] ^= this.toLane(n, ww, i + 4 * ww);
- this.S[ 1] ^= this.toLane(n, ww, i + 5 * ww);
- this.S[ 6] ^= this.toLane(n, ww, i + 6 * ww);
- this.S[11] ^= this.toLane(n, ww, i + 7 * ww);
- this.S[16] ^= this.toLane(n, ww, i + 8 * ww);
- this.S[21] ^= this.toLane(n, ww, i + 9 * ww);
- this.S[ 2] ^= this.toLane(n, ww, i + 10 * ww);
- this.S[ 7] ^= this.toLane(n, ww, i + 11 * ww);
- this.S[12] ^= this.toLane(n, ww, i + 12 * ww);
- this.S[17] ^= this.toLane(n, ww, i + 13 * ww);
- this.S[22] ^= this.toLane(n, ww, i + 14 * ww);
- this.S[ 3] ^= this.toLane(n, ww, i + 15 * ww);
- this.S[ 8] ^= this.toLane(n, ww, i + 16 * ww);
- this.S[13] ^= this.toLane(n, ww, i + 17 * ww);
- this.S[18] ^= this.toLane(n, ww, i + 18 * ww);
- this.S[23] ^= this.toLane(n, ww, i + 19 * ww);
- this.S[ 4] ^= this.toLane(n, ww, i + 20 * ww);
- this.S[ 9] ^= this.toLane(n, ww, i + 21 * ww);
- this.S[14] ^= this.toLane(n, ww, i + 22 * ww);
- this.S[19] ^= this.toLane(n, ww, i + 23 * ww);
- this.S[24] ^= this.toLane(n, ww, i + 24 * ww);
- this.keccakF(this.S);
- n += rr;
- }
-
- /* Squeezing phase */
- if (withReturn)
- {
- byte[] rc = new byte[(this.n + 7) >> 3];
- int ptr = 0;
-
- int olen = this.n;
- int j = 0;
- int ni = rr / ww;
- while (olen > 0)
- {
- int i = 0;
- while ((i < ni) && (j < nn))
- {
- long v = this.S[(i % 5) * 5 + i / 5];
- for (int k = 0; k < ww; k++)
- {
- if (j < nn)
- {
- rc[ptr] = (byte)v;
- ptr += 1;
- }
- v >>= 8;
- j += 1;
- }
- i += 1;
- }
- olen -= this.r;
- if (olen > 0)
- this.keccakF(this.S);
- }
- if ((this.n & 7) != 0)
- rc[rc.length - 1] &= (1 << (this.n & 7)) - 1;
-
- return rc;
- }
- int olen = this.n;
- while ((olen -= this.r) > 0)
- this.keccakF(this.S);
- return null;
- }
-
-
- /**
- * Force a round of Keccak-f
- */
- public void simpleSqueeze()
- {
- this.keccakF(this.S);
- }
-
-
- /**
- * Force some rounds of Keccak-f
- *
- * @param times The number of rounds
- */
- public void simpleSqueeze(int times)
- {
- for (int i = 0; i < times; i++)
- this.keccakF(this.S);
- }
-
-
- /**
- * Squeeze as much as is needed to get a digest
- */
- public void fastSqueeze()
- {
- this.keccakF(this.S); /* Last squeeze did not do a ending squeeze */
- int olen = this.n;
- while ((olen -= this.r) > 0)
- this.keccakF(this.S);
- }
-
-
- /**
- * Squeeze as much as is needed to get a digest a number of times
- *
- * @param times The number of digests
- */
- public void fastSqueeze(int times)
- {
- for (int i = 0; i < times; i++)
- {
- this.keccakF(this.S); /* Last squeeze did not do a ending squeeze */
- int olen = this.n;
- while ((olen -= this.r) > 0)
- this.keccakF(this.S);
- }
- }
-
-
- /**
- * Squeeze out another digest
- *
- * @return The hash sum
- */
- public byte[] squeeze()
- {
- this.keccakF(this.S); /* Last squeeze did not do a ending squeeze */
-
- int nn, ww = this.w >> 3;
- byte[] rc = new byte[nn = (this.n + 7) >> 3];
-
- int olen = this.n;
- int j = 0, ptr = 0;
- int ni = (this.r >> 3) / ww;
- while (olen > 0)
- {
- int i = 0;
- while ((i < ni) && (j < nn))
- {
- long v = this.S[(i % 5) * 5 + i / 5];
- for (int k = 0; k < ww; k++)
- {
- if (j < nn)
- {
- rc[ptr] = (byte)v;
- ptr += 1;
- }
- v >>= 8;
- j += 1;
- }
- i += 1;
- }
- olen -= this.r;
- if (olen > 0)
- this.keccakF(this.S);
- }
- if ((this.n & 7) != 0)
- rc[rc.length - 1] &= (1 << (this.n & 7)) - 1;
-
- return rc;
- }
-
-}
diff --git a/java/SHA3.java b/java/SHA3.java
deleted file mode 100644
index 9f41a00..0000000
--- a/java/SHA3.java
+++ /dev/null
@@ -1,969 +0,0 @@
-/**
- * sha3sum – SHA-3 (Keccak) checksum calculator
- *
- * Copyright © 2013, 2014 Mattias Andrée (maandree@member.fsf.org)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-/**
- * SHA-3/Keccak hash algorithm implementation
- *
- * @author Mattias Andrée <a href="mailto:maandree@member.fsf.org">maandree@member.fsf.org</a>
- */
-public class SHA3
-{
- /**
- * Suffix the message when calculating the Keccak hash sum
- */
- public static final String KECCAK_SUFFIX = "";
-
- /**
- * Suffix the message when calculating the SHA-3 hash sum
- */
- public static final String SHA3_SUFFIX = "01";
-
- /**
- * Suffix the message when calculating the RawSHAKE hash sum
- */
- public static final String RawSHAKE_SUFFIX = "11";
-
- /**
- * Suffix the message when calculating the SHAKE hash sum
- */
- public static final String SHAKE_SUFFIX = "1111";
-
-
- /**
- * Round contants
- */
- private static final long[] RC = {
- 0x0000000000000001L, 0x0000000000008082L, 0x800000000000808AL, 0x8000000080008000L,
- 0x000000000000808BL, 0x0000000080000001L, 0x8000000080008081L, 0x8000000000008009L,
- 0x000000000000008AL, 0x0000000000000088L, 0x0000000080008009L, 0x000000008000000AL,
- 0x000000008000808BL, 0x800000000000008BL, 0x8000000000008089L, 0x8000000000008003L,
- 0x8000000000008002L, 0x8000000000000080L, 0x000000000000800AL, 0x800000008000000AL,
- 0x8000000080008081L, 0x8000000000008080L, 0x0000000080000001L, 0x8000000080008008L};
-
- /**
- * Keccak-f round temporary
- */
- private static long[] B = new long[25];
-
- /**
- * Keccak-f round temporary
- */
- private static long[] C = new long[5];
-
-
- /**
- * The bitrate
- */
- private static int r = 0;
-
- /**
- * The capacity
- */
- private static int c = 0;
-
- /**
- * The output size
- */
- private static int n = 0;
-
- /**
- * The state size
- */
- private static int b = 0;
-
- /**
- * The word size
- */
- private static int w = 0;
-
- /**
- * The word mask
- */
- private static long wmod = 0;
-
- /**
- * ℓ, the binary logarithm of the word size
- */
- private static int l = 0;
-
- /**
- * 12 + 2ℓ, the number of rounds
- */
- private static int nr = 0;
-
-
- /**
- * Message chunk that is being processes
- */
- private static byte[] message = null;
-
- /**
- * The current state
- */
- private static long[] S = null;
-
- /**
- * Left over water to fill the sponge with at next update
- */
- private static byte[] M = null;
-
- /**
- * Pointer for {@link #M}
- */
- private static int mptr = 0;
-
-
-
- /**
- * Hidden constructor
- */
- private SHA3()
- {
- // Inhibit instansiation
- }
-
-
-
- /**
- * Rotate a word
- *
- * @param x The value to rotate
- * @param n Rotation steps, may not be 0
- * @return The value rotated
- */
- private static long rotate(long x, int n)
- {
- long m;
- return ((x >>> (SHA3.w - (m = n % SHA3.w))) + (x << m)) & SHA3.wmod;
- }
-
-
- /**
- * Rotate a 64-bit word
- *
- * @param x The value to rotate
- * @param n Rotation steps, may not be 0
- * @return The value rotated
- */
- private static long rotate64(long x, int n)
- {
- return (x >>> (64 - n)) + (x << n);
- }
-
-
- /**
- * Binary logarithm
- *
- * @param x The value of which to calculate the binary logarithm
- * @return The binary logarithm
- */
- private static int lb(int x)
- {
- int rc = 0;
- if ((x & 0xFF00) != 0) { rc += 8; x >>= 8; }
- if ((x & 0x00F0) != 0) { rc += 4; x >>= 4; }
- if ((x & 0x000C) != 0) { rc += 2; x >>= 2; }
- if ((x & 0x0002) != 0) rc += 1;
- return rc;
- }
-
- /**
- * Perform one round of computation
- *
- * @param A The current state
- * @param rc Round constant
- */
- private static void keccakFRound(long[] A, long rc)
- {
- /* θ step (step 1 of 3) */
- for (int i = 0, j = 0; i < 5; i++, j += 5)
- SHA3.C[i] = (A[j] ^ A[j + 1]) ^ (A[j + 2] ^ A[j + 3]) ^ A[j + 4];
-
- long da, db, dc, dd, de;
-
- if (SHA3.w == 64)
- {
- /* ρ and π steps, with last two part of θ */
- SHA3.B[0] = A[ 0] ^ (da = SHA3.C[4] ^ SHA3.rotate64(SHA3.C[1], 1));
- SHA3.B[1] = SHA3.rotate64(A[15] ^ (dd = SHA3.C[2] ^ SHA3.rotate64(SHA3.C[4], 1)), 28);
- SHA3.B[2] = SHA3.rotate64(A[ 5] ^ (db = SHA3.C[0] ^ SHA3.rotate64(SHA3.C[2], 1)), 1);
- SHA3.B[3] = SHA3.rotate64(A[20] ^ (de = SHA3.C[3] ^ SHA3.rotate64(SHA3.C[0], 1)), 27);
- SHA3.B[4] = SHA3.rotate64(A[10] ^ (dc = SHA3.C[1] ^ SHA3.rotate64(SHA3.C[3], 1)), 62);
-
- SHA3.B[5] = SHA3.rotate64(A[ 6] ^ db, 44);
- SHA3.B[6] = SHA3.rotate64(A[21] ^ de, 20);
- SHA3.B[7] = SHA3.rotate64(A[11] ^ dc, 6);
- SHA3.B[8] = SHA3.rotate64(A[ 1] ^ da, 36);
- SHA3.B[9] = SHA3.rotate64(A[16] ^ dd, 55);
-
- SHA3.B[10] = SHA3.rotate64(A[12] ^ dc, 43);
- SHA3.B[11] = SHA3.rotate64(A[ 2] ^ da, 3);
- SHA3.B[12] = SHA3.rotate64(A[17] ^ dd, 25);
- SHA3.B[13] = SHA3.rotate64(A[ 7] ^ db, 10);
- SHA3.B[14] = SHA3.rotate64(A[22] ^ de, 39);
-
- SHA3.B[15] = SHA3.rotate64(A[18] ^ dd, 21);
- SHA3.B[16] = SHA3.rotate64(A[ 8] ^ db, 45);
- SHA3.B[17] = SHA3.rotate64(A[23] ^ de, 8);
- SHA3.B[18] = SHA3.rotate64(A[13] ^ dc, 15);
- SHA3.B[19] = SHA3.rotate64(A[ 3] ^ da, 41);
-
- SHA3.B[20] = SHA3.rotate64(A[24] ^ de, 14);
- SHA3.B[21] = SHA3.rotate64(A[14] ^ dc, 61);
- SHA3.B[22] = SHA3.rotate64(A[ 4] ^ da, 18);
- SHA3.B[23] = SHA3.rotate64(A[19] ^ dd, 56);
- SHA3.B[24] = SHA3.rotate64(A[ 9] ^ db, 2);
- }
- else
- {
- /* ρ and π steps, with last two part of θ */
- SHA3.B[0] = A[ 0] ^ (da = SHA3.C[4] ^ SHA3.rotate(SHA3.C[1], 1));
- SHA3.B[1] = SHA3.rotate(A[15] ^ (dd = SHA3.C[2] ^ SHA3.rotate(SHA3.C[4], 1)), 28);
- SHA3.B[2] = SHA3.rotate(A[ 5] ^ (db = SHA3.C[0] ^ SHA3.rotate(SHA3.C[2], 1)), 1);
- SHA3.B[3] = SHA3.rotate(A[20] ^ (de = SHA3.C[3] ^ SHA3.rotate(SHA3.C[0], 1)), 27);
- SHA3.B[4] = SHA3.rotate(A[10] ^ (dc = SHA3.C[1] ^ SHA3.rotate(SHA3.C[3], 1)), 62);
-
- SHA3.B[5] = SHA3.rotate(A[ 6] ^ db, 44);
- SHA3.B[6] = SHA3.rotate(A[21] ^ de, 20);
- SHA3.B[7] = SHA3.rotate(A[11] ^ dc, 6);
- SHA3.B[8] = SHA3.rotate(A[ 1] ^ da, 36);
- SHA3.B[9] = SHA3.rotate(A[16] ^ dd, 55);
-
- SHA3.B[10] = SHA3.rotate(A[12] ^ dc, 43);
- SHA3.B[11] = SHA3.rotate(A[ 2] ^ da, 3);
- SHA3.B[12] = SHA3.rotate(A[17] ^ dd, 25);
- SHA3.B[13] = SHA3.rotate(A[ 7] ^ db, 10);
- SHA3.B[14] = SHA3.rotate(A[22] ^ de, 39);
-
- SHA3.B[15] = SHA3.rotate(A[18] ^ dd, 21);
- SHA3.B[16] = SHA3.rotate(A[ 8] ^ db, 45);
- SHA3.B[17] = SHA3.rotate(A[23] ^ de, 8);
- SHA3.B[18] = SHA3.rotate(A[13] ^ dc, 15);
- SHA3.B[19] = SHA3.rotate(A[ 3] ^ da, 41);
-
- SHA3.B[20] = SHA3.rotate(A[24] ^ de, 14);
- SHA3.B[21] = SHA3.rotate(A[14] ^ dc, 61);
- SHA3.B[22] = SHA3.rotate(A[ 4] ^ da, 18);
- SHA3.B[23] = SHA3.rotate(A[19] ^ dd, 56);
- SHA3.B[24] = SHA3.rotate(A[ 9] ^ db, 2);
- }
-
- /* ξ step */
- for (int i = 0; i < 15; i++)
- A[i ] = SHA3.B[i ] ^ ((~(SHA3.B[i + 5])) & SHA3.B[i + 10]);
- for (int i = 0; i < 5; i++)
- {
- A[i + 15] = SHA3.B[i + 15] ^ ((~(SHA3.B[i + 20])) & SHA3.B[i ]);
- A[i + 20] = SHA3.B[i + 20] ^ ((~(SHA3.B[i ])) & SHA3.B[i + 5]);
- }
-
- /* ι step */
- A[0] ^= rc;
- }
-
-
- /**
- * Perform Keccak-f function
- *
- * @param A The current state
- */
- private static void keccakF(long[] A)
- {
- if (SHA3.nr == 24)
- for (int i = 0; i < 24; i++)
- SHA3.keccakFRound(A, SHA3.RC[i]);
- else
- for (int i = 0; i < SHA3.nr; i++)
- SHA3.keccakFRound(A, SHA3.RC[i] & SHA3.wmod);
- }
-
-
- /**
- * Convert a chunk of byte:s to a word
- *
- * @param n {@code Math.min(SHA3.message.length, rr) + msgoff}
- * msgoff The number of times to loop has run times the bitrate
- * rr Bitrate in bytes
- * @param ww Word size in bytes
- * @param off The offset in the message
- * @return Lane
- */
- private static long toLane(int n, int ww, int off)
- {
- long rc = 0;
- for (int i = off + ww - 1; i >= off; i--)
- rc = (rc << 8) | ((i < n) ? (long)(SHA3.message[i] & 255) : 0L);
- return rc;
- }
-
-
- /**
- * Convert a chunk of byte:s to a 64-bit word
- *
- * @param n {@code Math.min(SHA3.message.length, rr) + msgoff}
- * msgoff The number of times to loop has run times the bitrate
- * rr Bitrate in bytes
- * @param off The offset in the message
- * @return Lane
- */
- private static long toLane64(int n, int off)
- {
- return ((off + 7 < n) ? ((long)(SHA3.message[off + 7] & 255) << 56) : 0L) |
- ((off + 6 < n) ? ((long)(SHA3.message[off + 6] & 255) << 48) : 0L) |
- ((off + 5 < n) ? ((long)(SHA3.message[off + 5] & 255) << 40) : 0L) |
- ((off + 4 < n) ? ((long)(SHA3.message[off + 4] & 255) << 32) : 0L) |
- ((off + 3 < n) ? ((long)(SHA3.message[off + 3] & 255) << 24) : 0L) |
- ((off + 2 < n) ? ((long)(SHA3.message[off + 2] & 255) << 16) : 0L) |
- ((off + 1 < n) ? ((long)(SHA3.message[off + 1] & 255) << 8) : 0L) |
- ((off < n) ? ((long)(SHA3.message[off] & 255)) : 0L);
- }
-
-
- /**
- * pad 10*1
- *
- * @param msg The message to pad
- * @param len The length of the message
- * @param r The bitrate
- * @param bits The number of bits in the end of the message that does not make a whole byte
- * @return The actual length of {@link #message}
- */
- private static int pad10star1(byte[] msg, int len, int r, int bits)
- {
- len = ((len - (bits + 7) / 8) << 3) + bits;
-
- int nrf = len >> 3;
- int nbrf = len & 7;
- int ll = len % r;
-
- byte b = (byte)(nbrf == 0 ? 1 : (msg[nrf] | (1 << nbrf)));
-
- if ((r - 8 <= ll) && (ll <= r - 2))
- {
- SHA3.message = new byte[len = nrf + 1];
- SHA3.message[nrf] = (byte)(b ^ 128);
- }
- else
- {
- len = (nrf + 1) << 3;
- len = ((len - (len % r) + (r - 8)) >> 3) + 1;
- SHA3.message = new byte[len];
- SHA3.message[nrf] = b;
- SHA3.message[len - 1] = -128;
- }
-
- System.arraycopy(msg, 0, SHA3.message, 0, nrf);
- return len;
- }
-
-
- /**
- * Initialise Keccak sponge
- *
- * @param r The bitrate
- * @param c The capacity
- * @param n The output size
- */
- public static void initialise(int r, int c, int n)
- {
- SHA3.r = r;
- SHA3.c = c;
- SHA3.n = n;
- SHA3.b = r + c;
- SHA3.w = SHA3.b / 25;
- SHA3.l = SHA3.lb(SHA3.w);
- SHA3.nr = 12 + (SHA3.l << 1);
- SHA3.wmod = w == 64 ? -1L : (1L << SHA3.w) - 1L;
- SHA3.S = new long[25];
- if ((SHA3.M == null) || ((SHA3.r * SHA3.b) >> 2 != SHA3.M.length))
- SHA3.M = new byte[(SHA3.r * SHA3.b) >> 2];
- SHA3.mptr = 0;
- if (SHA3.message == null)
- SHA3.message = new byte[8 << 10];
- }
-
-
- /**
- * Free up static resources
- */
- public static void dispose()
- {
- SHA3.S = null;
- SHA3.M = null;
- SHA3.message = null;
- }
-
-
- /**
- * Absorb the more of the message message to the Keccak sponge
- *
- * @param msg The partial message
- */
- public static void update(byte[] msg)
- {
- update(msg, msg.length);
- }
-
-
- /**
- * Absorb the more of the message message to the Keccak sponge
- *
- * @param msg The partial message
- * @param msglen The length of the partial message
- */
- public static void update(byte[] msg, int msglen)
- {
- int rr = SHA3.r >> 3;
- int ww = SHA3.w >> 3;
-
- if (SHA3.mptr + msglen > SHA3.M.length)
- System.arraycopy(SHA3.M, 0, SHA3.M = new byte[(SHA3.M.length + msglen) << 1], 0, SHA3.mptr);
- System.arraycopy(msg, 0, SHA3.M, SHA3.mptr, msglen);
- int len = SHA3.mptr += msglen;
- len -= len % ((SHA3.r * SHA3.b) >> 3);
- System.arraycopy(SHA3.M, 0, (SHA3.message.length < len) ? (SHA3.message = new byte[len]) : SHA3.message, 0, len);
- System.arraycopy(SHA3.M, len, SHA3.M, 0, SHA3.mptr -= len);
- int n = Math.min(len, rr);
-
- /* Absorbing phase */
- if (ww == 8)
- for (int i = 0; i < len; i += rr)
- {
- SHA3.S[ 0] ^= SHA3.toLane64(n, i + 0);
- SHA3.S[ 5] ^= SHA3.toLane64(n, i + 8);
- SHA3.S[10] ^= SHA3.toLane64(n, i + 16);
- SHA3.S[15] ^= SHA3.toLane64(n, i + 24);
- SHA3.S[20] ^= SHA3.toLane64(n, i + 32);
- SHA3.S[ 1] ^= SHA3.toLane64(n, i + 40);
- SHA3.S[ 6] ^= SHA3.toLane64(n, i + 48);
- SHA3.S[11] ^= SHA3.toLane64(n, i + 56);
- SHA3.S[16] ^= SHA3.toLane64(n, i + 64);
- SHA3.S[21] ^= SHA3.toLane64(n, i + 72);
- SHA3.S[ 2] ^= SHA3.toLane64(n, i + 80);
- SHA3.S[ 7] ^= SHA3.toLane64(n, i + 88);
- SHA3.S[12] ^= SHA3.toLane64(n, i + 96);
- SHA3.S[17] ^= SHA3.toLane64(n, i + 104);
- SHA3.S[22] ^= SHA3.toLane64(n, i + 112);
- SHA3.S[ 3] ^= SHA3.toLane64(n, i + 120);
- SHA3.S[ 8] ^= SHA3.toLane64(n, i + 128);
- SHA3.S[13] ^= SHA3.toLane64(n, i + 136);
- SHA3.S[18] ^= SHA3.toLane64(n, i + 144);
- SHA3.S[23] ^= SHA3.toLane64(n, i + 152);
- SHA3.S[ 4] ^= SHA3.toLane64(n, i + 160);
- SHA3.S[ 9] ^= SHA3.toLane64(n, i + 168);
- SHA3.S[14] ^= SHA3.toLane64(n, i + 176);
- SHA3.S[19] ^= SHA3.toLane64(n, i + 184);
- SHA3.S[24] ^= SHA3.toLane64(n, i + 192);
- SHA3.keccakF(SHA3.S);
- n += rr;
- }
- else
- for (int i = 0; i < len; i += rr)
- {
- SHA3.S[ 0] ^= SHA3.toLane(n, ww, i + 0 );
- SHA3.S[ 5] ^= SHA3.toLane(n, ww, i + ww);
- SHA3.S[10] ^= SHA3.toLane(n, ww, i + 2 * ww);
- SHA3.S[15] ^= SHA3.toLane(n, ww, i + 3 * ww);
- SHA3.S[20] ^= SHA3.toLane(n, ww, i + 4 * ww);
- SHA3.S[ 1] ^= SHA3.toLane(n, ww, i + 5 * ww);
- SHA3.S[ 6] ^= SHA3.toLane(n, ww, i + 6 * ww);
- SHA3.S[11] ^= SHA3.toLane(n, ww, i + 7 * ww);
- SHA3.S[16] ^= SHA3.toLane(n, ww, i + 8 * ww);
- SHA3.S[21] ^= SHA3.toLane(n, ww, i + 9 * ww);
- SHA3.S[ 2] ^= SHA3.toLane(n, ww, i + 10 * ww);
- SHA3.S[ 7] ^= SHA3.toLane(n, ww, i + 11 * ww);
- SHA3.S[12] ^= SHA3.toLane(n, ww, i + 12 * ww);
- SHA3.S[17] ^= SHA3.toLane(n, ww, i + 13 * ww);
- SHA3.S[22] ^= SHA3.toLane(n, ww, i + 14 * ww);
- SHA3.S[ 3] ^= SHA3.toLane(n, ww, i + 15 * ww);
- SHA3.S[ 8] ^= SHA3.toLane(n, ww, i + 16 * ww);
- SHA3.S[13] ^= SHA3.toLane(n, ww, i + 17 * ww);
- SHA3.S[18] ^= SHA3.toLane(n, ww, i + 18 * ww);
- SHA3.S[23] ^= SHA3.toLane(n, ww, i + 19 * ww);
- SHA3.S[ 4] ^= SHA3.toLane(n, ww, i + 20 * ww);
- SHA3.S[ 9] ^= SHA3.toLane(n, ww, i + 21 * ww);
- SHA3.S[14] ^= SHA3.toLane(n, ww, i + 22 * ww);
- SHA3.S[19] ^= SHA3.toLane(n, ww, i + 23 * ww);
- SHA3.S[24] ^= SHA3.toLane(n, ww, i + 24 * ww);
- SHA3.keccakF(SHA3.S);
- n += rr;
- }
- }
-
-
- /**
- * Squeeze the Keccak sponge
- *
- * @return The hash sum
- */
- public static byte[] digest()
- {
- return digest(null, 0, 0, SHA3.SHA3_SUFFIX, true);
- }
-
-
- /**
- * Squeeze the Keccak sponge
- *
- * @param suffix The suffix concatenate to the message
- * @return The hash sum
- */
- public static byte[] digest(String suffix)
- {
- return digest(null, 0, 0, suffix, true);
- }
-
-
- /**
- * Squeeze the Keccak sponge
- *
- * @param withReturn Whether to return the hash instead of just do a quick squeeze phrase and return {@code null}
- * @return The hash sum, or {@code null} if <tt>withReturn</tt> is {@code false}
- */
- public static byte[] digest(boolean withReturn)
- {
- return digest(null, 0, 0, SHA3.SHA3_SUFFIX, withReturn);
- }
-
-
- /**
- * Squeeze the Keccak sponge
- *
- * @param suffix The suffix concatenate to the message
- * @param withReturn Whether to return the hash instead of just do a quick squeeze phrase and return {@code null}
- * @return The hash sum, or {@code null} if <tt>withReturn</tt> is {@code false}
- */
- public static byte[] digest(String suffix, boolean withReturn)
- {
- return digest(null, 0, 0, suffix, withReturn);
- }
-
-
- /**
- * Absorb the last part of the message and squeeze the Keccak sponge
- *
- * @param msg The rest of the message
- * @return The hash sum
- */
- public static byte[] digest(byte[] msg)
- {
- return digest(msg, msg == null ? 0 : msg.length, 0, SHA3.SHA3_SUFFIX, true);
- }
-
-
- /**
- * Absorb the last part of the message and squeeze the Keccak sponge
- *
- * @param msg The rest of the message
- * @param suffix The suffix concatenate to the message
- * @return The hash sum
- */
- public static byte[] digest(byte[] msg, String suffix)
- {
- return digest(msg, msg == null ? 0 : msg.length, 0, suffix, true);
- }
-
-
- /**
- * Absorb the last part of the message and squeeze the Keccak sponge
- *
- * @param msg The rest of the message
- * @param withReturn Whether to return the hash instead of just do a quick squeeze phrase and return {@code null}
- * @return The hash sum, or {@code null} if <tt>withReturn</tt> is {@code false}
- */
- public static byte[] digest(byte[] msg, boolean withReturn)
- {
- return digest(msg, msg == null ? 0 : msg.length, 0, SHA3.SHA3_SUFFIX, withReturn);
- }
-
-
- /**
- * Absorb the last part of the message and squeeze the Keccak sponge
- *
- * @param msg The rest of the message
- * @param suffix The suffix concatenate to the message
- * @param withReturn Whether to return the hash instead of just do a quick squeeze phrase and return {@code null}
- * @return The hash sum, or {@code null} if <tt>withReturn</tt> is {@code false}
- */
- public static byte[] digest(byte[] msg, String suffix, boolean withReturn)
- {
- return digest(msg, msg == null ? 0 : msg.length, 0, suffix, withReturn);
- }
-
-
- /**
- * Absorb the last part of the message and squeeze the Keccak sponge
- *
- * @param msg The rest of the message
- * @param msglen The length of the partial message in while bytes
- * @return The hash sum
- */
- public static byte[] digest(byte[] msg, int msglen)
- {
- return digest(msg, msg == null ? 0 : msg.length, 0, SHA3.SHA3_SUFFIX, true);
- }
-
-
- /**
- * Absorb the last part of the message and squeeze the Keccak sponge
- *
- * @param msg The rest of the message
- * @param msglen The length of the partial message in while bytes
- * @param suffix The suffix concatenate to the message
- * @return The hash sum
- */
- public static byte[] digest(byte[] msg, int msglen, String suffix)
- {
- return digest(msg, msg == null ? 0 : msg.length, 0, suffix, true);
- }
-
-
- /**
- * Absorb the last part of the message and squeeze the Keccak sponge
- *
- * @param msg The rest of the message
- * @param msglen The length of the partial message in while bytes
- * @param bits The number of bits at the end of the message not covered by <tt>msglen</tt>
- * @return The hash sum
- */
- public static byte[] digest(byte[] msg, int msglen, int bits)
- {
- return digest(msg, msg == null ? 0 : msg.length, bits, SHA3.SHA3_SUFFIX, true);
- }
-
-
- /**
- * Absorb the last part of the message and squeeze the Keccak sponge
- *
- * @param msg The rest of the message
- * @param msglen The length of the partial message in while bytes
- * @param bits The number of bits at the end of the message not covered by <tt>msglen</tt>
- * @param suffix The suffix concatenate to the message
- * @return The hash sum
- */
- public static byte[] digest(byte[] msg, int msglen, int bits, String suffix)
- {
- return digest(msg, msg == null ? 0 : msg.length, bits, suffix, true);
- }
-
-
- /**
- * Absorb the last part of the message and squeeze the Keccak sponge
- *
- * @param msg The rest of the message
- * @param msglen The length of the partial message in while bytes
- * @param withReturn Whether to return the hash instead of just do a quick squeeze phrase and return {@code null}
- * @return The hash sum, or {@code null} if <tt>withReturn</tt> is {@code false}
- */
- public static byte[] digest(byte[] msg, int msglen, boolean withReturn)
- {
- return digest(msg, msg == null ? 0 : msg.length, 0, SHA3.SHA3_SUFFIX, withReturn);
- }
-
-
- /**
- * Absorb the last part of the message and squeeze the Keccak sponge
- *
- * @param msg The rest of the message
- * @param msglen The length of the partial message in while bytes
- * @param suffix The suffix concatenate to the message
- * @param withReturn Whether to return the hash instead of just do a quick squeeze phrase and return {@code null}
- * @return The hash sum, or {@code null} if <tt>withReturn</tt> is {@code false}
- */
- public static byte[] digest(byte[] msg, int msglen, String suffix, boolean withReturn)
- {
- return digest(msg, msg == null ? 0 : msg.length, 0, suffix, withReturn);
- }
-
-
- /**
- * Absorb the last part of the message and squeeze the Keccak sponge
- *
- * @param msg The rest of the message
- * @param msglen The length of the partial message in while bytes
- * @param bits The number of bits at the end of the message not covered by <tt>msglen</tt>
- * @param withReturn Whether to return the hash instead of just do a quick squeeze phrase and return {@code null}
- * @return The hash sum, or {@code null} if <tt>withReturn</tt> is {@code false}
- */
- public static byte[] digest(byte[] msg, int msglen, int bits, boolean withReturn)
- {
- return digest(msg, msg == null ? 0 : msg.length, 0, SHA3.SHA3_SUFFIX, withReturn);
- }
-
-
- /**
- * Absorb the last part of the message and squeeze the Keccak sponge
- *
- * @param msg The rest of the message
- * @param msglen The length of the partial message in while bytes
- * @param bits The number of bits at the end of the message not covered by <tt>msglen</tt>
- * @param suffix The suffix concatenate to the message
- * @param withReturn Whether to return the hash instead of just do a quick squeeze phrase and return {@code null}
- * @return The hash sum, or {@code null} if <tt>withReturn</tt> is {@code false}
- */
- public static byte[] digest(byte[] msg, int msglen, int bits, String suffix, boolean withReturn)
- {
- int len;
- byte last_byte = 0;
- if ((msg == null) || (msglen == 0))
- {
- msg = new byte[0];
- bits = 0;
- }
-
- msglen += bits / 8;
- if ((bits %= 8) != 0)
- last_byte = msg[msglen];
-
- byte[] msg_end = new byte[(suffix.length() + bits + 7) / 8];
- int msg_end_ptr = 0;
- for (int i = 0, n = suffix.length(); i < n; i++)
- {
- byte bit = (byte)(suffix.charAt(i) - '0');
- last_byte |= bit << bits++;
- if (bits == 8)
- {
- msg_end[msg_end_ptr++] = last_byte;
- last_byte = 0;
- bits = 0;
- }
- }
- if (bits != 0)
- msg_end[msg_end_ptr++] = last_byte;
- if (msg_end_ptr > 0)
- {
- if (msglen + msg_end_ptr > msg.length)
- System.arraycopy(msg, 0, msg = new byte[msglen + msg_end_ptr], 0, msglen);
- System.arraycopy(msg_end, 0, msg, msglen, msg_end_ptr);
- msglen += msg_end_ptr;
- }
-
- if (SHA3.mptr + msglen > SHA3.M.length)
- System.arraycopy(SHA3.M, 0, SHA3.M = new byte[SHA3.M.length + msglen], 0, SHA3.mptr);
- System.arraycopy(msg, 0, SHA3.M, SHA3.mptr, msglen);
- len = SHA3.pad10star1(SHA3.M, SHA3.mptr + msglen, SHA3.r, bits);
-
- int rr = SHA3.r >> 3;
- int nn = (SHA3.n + 7) >> 3;
- int ww = SHA3.w >> 3;
-
- int n = Math.min(len, rr);
-
- /* Absorbing phase */
- if (ww == 8)
- for (int i = 0; i < len; i += rr)
- {
- SHA3.S[ 0] ^= SHA3.toLane64(n, i + 0);
- SHA3.S[ 5] ^= SHA3.toLane64(n, i + 8);
- SHA3.S[10] ^= SHA3.toLane64(n, i + 16);
- SHA3.S[15] ^= SHA3.toLane64(n, i + 24);
- SHA3.S[20] ^= SHA3.toLane64(n, i + 32);
- SHA3.S[ 1] ^= SHA3.toLane64(n, i + 40);
- SHA3.S[ 6] ^= SHA3.toLane64(n, i + 48);
- SHA3.S[11] ^= SHA3.toLane64(n, i + 56);
- SHA3.S[16] ^= SHA3.toLane64(n, i + 64);
- SHA3.S[21] ^= SHA3.toLane64(n, i + 72);
- SHA3.S[ 2] ^= SHA3.toLane64(n, i + 80);
- SHA3.S[ 7] ^= SHA3.toLane64(n, i + 88);
- SHA3.S[12] ^= SHA3.toLane64(n, i + 96);
- SHA3.S[17] ^= SHA3.toLane64(n, i + 104);
- SHA3.S[22] ^= SHA3.toLane64(n, i + 112);
- SHA3.S[ 3] ^= SHA3.toLane64(n, i + 120);
- SHA3.S[ 8] ^= SHA3.toLane64(n, i + 128);
- SHA3.S[13] ^= SHA3.toLane64(n, i + 136);
- SHA3.S[18] ^= SHA3.toLane64(n, i + 144);
- SHA3.S[23] ^= SHA3.toLane64(n, i + 152);
- SHA3.S[ 4] ^= SHA3.toLane64(n, i + 160);
- SHA3.S[ 9] ^= SHA3.toLane64(n, i + 168);
- SHA3.S[14] ^= SHA3.toLane64(n, i + 176);
- SHA3.S[19] ^= SHA3.toLane64(n, i + 184);
- SHA3.S[24] ^= SHA3.toLane64(n, i + 192);
- SHA3.keccakF(SHA3.S);
- n += rr;
- }
- else
- for (int i = 0; i < len; i += rr)
- {
- SHA3.S[ 0] ^= SHA3.toLane(n, ww, i + 0 );
- SHA3.S[ 5] ^= SHA3.toLane(n, ww, i + ww);
- SHA3.S[10] ^= SHA3.toLane(n, ww, i + 2 * ww);
- SHA3.S[15] ^= SHA3.toLane(n, ww, i + 3 * ww);
- SHA3.S[20] ^= SHA3.toLane(n, ww, i + 4 * ww);
- SHA3.S[ 1] ^= SHA3.toLane(n, ww, i + 5 * ww);
- SHA3.S[ 6] ^= SHA3.toLane(n, ww, i + 6 * ww);
- SHA3.S[11] ^= SHA3.toLane(n, ww, i + 7 * ww);
- SHA3.S[16] ^= SHA3.toLane(n, ww, i + 8 * ww);
- SHA3.S[21] ^= SHA3.toLane(n, ww, i + 9 * ww);
- SHA3.S[ 2] ^= SHA3.toLane(n, ww, i + 10 * ww);
- SHA3.S[ 7] ^= SHA3.toLane(n, ww, i + 11 * ww);
- SHA3.S[12] ^= SHA3.toLane(n, ww, i + 12 * ww);
- SHA3.S[17] ^= SHA3.toLane(n, ww, i + 13 * ww);
- SHA3.S[22] ^= SHA3.toLane(n, ww, i + 14 * ww);
- SHA3.S[ 3] ^= SHA3.toLane(n, ww, i + 15 * ww);
- SHA3.S[ 8] ^= SHA3.toLane(n, ww, i + 16 * ww);
- SHA3.S[13] ^= SHA3.toLane(n, ww, i + 17 * ww);
- SHA3.S[18] ^= SHA3.toLane(n, ww, i + 18 * ww);
- SHA3.S[23] ^= SHA3.toLane(n, ww, i + 19 * ww);
- SHA3.S[ 4] ^= SHA3.toLane(n, ww, i + 20 * ww);
- SHA3.S[ 9] ^= SHA3.toLane(n, ww, i + 21 * ww);
- SHA3.S[14] ^= SHA3.toLane(n, ww, i + 22 * ww);
- SHA3.S[19] ^= SHA3.toLane(n, ww, i + 23 * ww);
- SHA3.S[24] ^= SHA3.toLane(n, ww, i + 24 * ww);
- SHA3.keccakF(SHA3.S);
- n += rr;
- }
-
- /* Squeezing phase */
- if (withReturn)
- {
- byte[] rc = new byte[(SHA3.n + 7) >> 3];
- int ptr = 0;
-
- int olen = SHA3.n;
- int j = 0;
- int ni = rr / ww;
- while (olen > 0)
- {
- int i = 0;
- while ((i < ni) && (j < nn))
- {
- long v = SHA3.S[(i % 5) * 5 + i / 5];
- for (int k = 0; k < ww; k++)
- {
- if (j < nn)
- {
- rc[ptr] = (byte)v;
- ptr += 1;
- }
- v >>= 8;
- j += 1;
- }
- i += 1;
- }
- olen -= SHA3.r;
- if (olen > 0)
- SHA3.keccakF(SHA3.S);
- }
- if ((SHA3.n & 7) != 0)
- rc[rc.length - 1] &= (1 << (SHA3.n & 7)) - 1;
-
- return rc;
- }
- int olen = SHA3.n;
- while ((olen -= SHA3.r) > 0)
- SHA3.keccakF(SHA3.S);
- return null;
- }
-
-
- /**
- * Force a round of Keccak-f
- */
- public static void simpleSqueeze()
- {
- SHA3.keccakF(SHA3.S);
- }
-
-
- /**
- * Force some rounds of Keccak-f
- *
- * @param times The number of rounds
- */
- public static void simpleSqueeze(int times)
- {
- for (int i = 0; i < times; i++)
- SHA3.keccakF(SHA3.S);
- }
-
-
- /**
- * Squeeze as much as is needed to get a digest
- */
- public static void fastSqueeze()
- {
- SHA3.keccakF(SHA3.S); /* Last squeeze did not do a ending squeeze */
- int olen = SHA3.n;
- while ((olen -= SHA3.r) > 0)
- SHA3.keccakF(SHA3.S);
- }
-
-
- /**
- * Squeeze as much as is needed to get a digest a number of times
- *
- * @param times The number of digests
- */
- public static void fastSqueeze(int times)
- {
- for (int i = 0; i < times; i++)
- {
- SHA3.keccakF(SHA3.S); /* Last squeeze did not do a ending squeeze */
- int olen = SHA3.n;
- while ((olen -= SHA3.r) > 0)
- SHA3.keccakF(SHA3.S);
- }
- }
-
-
- /**
- * Squeeze out another digest
- *
- * @return The hash sum
- */
- public static byte[] squeeze()
- {
- SHA3.keccakF(SHA3.S); /* Last squeeze did not do a ending squeeze */
-
- int nn, ww = SHA3.w >> 3;
- byte[] rc = new byte[nn = (SHA3.n + 7) >> 3];
-
- int olen = SHA3.n;
- int j = 0, ptr = 0;
- int ni = (SHA3.r >> 3) / ww;
- while (olen > 0)
- {
- int i = 0;
- while ((i < ni) && (j < nn))
- {
- long v = SHA3.S[(i % 5) * 5 + i / 5];
- for (int k = 0; k < ww; k++)
- {
- if (j < nn)
- {
- rc[ptr] = (byte)v;
- ptr += 1;
- }
- v >>= 8;
- j += 1;
- }
- i += 1;
- }
- olen -= SHA3.r;
- if (olen > 0)
- SHA3.keccakF(SHA3.S);
- }
- if ((SHA3.n & 7) != 0)
- rc[rc.length - 1] &= (1 << (SHA3.n & 7)) - 1;
-
- return rc;
- }
-
-}
diff --git a/java/sha3_256sum.java b/java/sha3_256sum.java
deleted file mode 100644
index 06375f2..0000000
--- a/java/sha3_256sum.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/**
- * sha3sum – SHA-3 (Keccak) checksum calculator
- *
- * Copyright © 2013, 2014 Mattias Andrée (maandree@member.fsf.org)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-import java.io.*;
-import java.util.*;
-
-
-/**
- * SHA-3/Keccak checksum calculator with 256 bit output
- *
- * @author Mattias Andrée <a href="mailto:maandree@member.fsf.org">maandree@member.fsf.org</a>
- */
-public class sha3_256sum
-{
- /**
- * This is the main entry point of the program
- *
- * @param args Command line arguments
- * @throws IOException On I/O error (such as broken pipes)
- */
- public static void main(String[] args) throws IOException
- {
- sha3sum.run("sha3-256sum", args);
- }
-}
-
diff --git a/java/sha3_384sum.java b/java/sha3_384sum.java
deleted file mode 100644
index 40128f4..0000000
--- a/java/sha3_384sum.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/**
- * sha3sum – SHA-3 (Keccak) checksum calculator
- *
- * Copyright © 2013, 2014 Mattias Andrée (maandree@member.fsf.org)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-import java.io.*;
-import java.util.*;
-
-
-/**
- * SHA-3/Keccak checksum calculator with 384 bit output
- *
- * @author Mattias Andrée <a href="mailto:maandree@member.fsf.org">maandree@member.fsf.org</a>
- */
-public class sha3_384sum
-{
- /**
- * This is the main entry point of the program
- *
- * @param args Command line arguments
- * @throws IOException On I/O error (such as broken pipes)
- */
- public static void main(String[] args) throws IOException
- {
- sha3sum.run("sha3-384sum", args);
- }
-}
-
diff --git a/java/sha3_512sum.java b/java/sha3_512sum.java
deleted file mode 100644
index 60387d5..0000000
--- a/java/sha3_512sum.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/**
- * sha3sum – SHA-3 (Keccak) checksum calculator
- *
- * Copyright © 2013, 2014 Mattias Andrée (maandree@member.fsf.org)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-import java.io.*;
-import java.util.*;
-
-
-/**
- * SHA-3/Keccak checksum calculator with 512 bit output
- *
- * @author Mattias Andrée <a href="mailto:maandree@member.fsf.org">maandree@member.fsf.org</a>
- */
-public class sha3_512sum
-{
- /**
- * This is the main entry point of the program
- *
- * @param args Command line arguments
- * @throws IOException On I/O error (such as broken pipes)
- */
- public static void main(String[] args) throws IOException
- {
- sha3sum.run("sha3-512sum", args);
- }
-}
-
diff --git a/java/sha3sum.java b/java/sha3sum.java
deleted file mode 100644
index 7d70caf..0000000
--- a/java/sha3sum.java
+++ /dev/null
@@ -1,485 +0,0 @@
-/**
- * sha3sum – SHA-3 (Keccak) checksum calculator
- *
- * Copyright © 2013, 2014 Mattias Andrée (maandree@member.fsf.org)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-import java.io.*;
-import java.util.*;
-
-
-/**
- * SHA-3/Keccak checksum calculator
- *
- * @author Mattias Andrée <a href="mailto:maandree@member.fsf.org">maandree@member.fsf.org</a>
- */
-public class sha3sum
-{
- /**
- * This is the main entry point of the program
- *
- * @param args Command line arguments
- * @throws IOException On I/O error (such as broken pipes)
- */
- public static void main(String[] args) throws IOException
- {
- run("sha3sum", args);
- }
-
-
- /**
- * Run the program
- *
- * @param cmd The command
- * @param argv Command line arguments
- * @throws IOException On I/O error (such as broken pipes)
- */
- public static void run(String cmd, String[] argv) throws IOException
- {
- if (cmd.indexOf('/') >= 0)
- cmd = cmd.substring(cmd.lastIndexOf('/') + 1);
- if (cmd.endsWith(".jar"))
- cmd = cmd.substring(0, cmd.length() - 4);
- cmd = cmd.intern();
-
- Integer O = null; int _o = 512; /* --outputsize */
- if (cmd == "sha3-224sum") _o = 224;
- else if (cmd == "sha3-256sum") _o = 256;
- else if (cmd == "sha3-384sum") _o = 384;
- else if (cmd == "sha3-512sum") _o = 512;
- Integer S = null; int _s = 1600; /* --statesize */
- Integer C = null; int _c = _s - (_o << 1); /* --capacity */
- Integer R = null; int _r = _s - _c; /* --bitrate */
- Integer W = null; int _w = _s / 25; /* --wordsize */
- Integer I = null; int _i = 1; /* --iterations */
- Integer J = null; int _j = 1; /* --squeezes */
- int o = 0, s = 0, r = 0, c = 0, w = 0, i = 0, j = 0;
-
- boolean binary = false, hex = false;
- int multi = 0;
-
- String[] files = new String[argv.length + 1];
- int fptr = 0;
- boolean dashed = false;
- String[] linger = null;
-
- String[] args = new String[argv.length + 1];
- System.arraycopy(argv, 0, args, 0, argv.length);
- for (int a = 0, an = args.length; a < an; a++)
- { String arg = args[a];
- arg = arg == null ? null : arg.intern();
- if (linger != null)
- {
- linger[0] = linger[0].intern();
- if ((linger[0] == "-h") || (linger[0] == "--help"))
- {
- System.out.println("");
- System.out.println("SHA-3/Keccak checksum calculator");
- System.out.println("");
- System.out.println("USAGE: sha3sum [option...] < file");
- System.out.println(" sha3sum [option...] file...");
- System.out.println("");
- System.out.println("");
- System.out.println("OPTIONS:");
- System.out.println(" -r BITRATE");
- System.out.println(" --bitrate The bitrate to use for ckecksum. (default: " + _r + ")");
- System.out.println(" ");
- System.out.println(" -c CAPACITY");
- System.out.println(" --capacity The capacity to use for checksum. (default: " + _c + ")");
- System.out.println(" ");
- System.out.println(" -w WORDSIZE");
- System.out.println(" --wordsize The word size to use for checksum. (default: " + _w + ")");
- System.out.println(" ");
- System.out.println(" -o OUTPUTSIZE");
- System.out.println(" --outputsize The output size to use for checksum. (default: " + _o + ")");
- System.out.println(" ");
- System.out.println(" -s STATESIZE");
- System.out.println(" --statesize The state size to use for checksum. (default: " + _s + ")");
- System.out.println(" ");
- System.out.println(" -i ITERATIONS");
- System.out.println(" --iterations The number of hash iterations to run. (default: " + _i + ")");
- System.out.println(" ");
- System.out.println(" -j SQUEEZES");
- System.out.println(" --squeezes The number of hash squeezes to run. (default: " + _j + ")");
- System.out.println(" ");
- System.out.println(" -x");
- System.out.println(" --hex Read the input in hexadecimal, rather than binary.");
- System.out.println(" ");
- System.out.println(" -b");
- System.out.println(" --binary Print the checksum in binary, rather than hexadecimal.");
- System.out.println(" ");
- System.out.println(" -m");
- System.out.println(" --multi Print the checksum at all iterations.");
- System.out.println("");
- System.out.println("");
- System.out.println("COPYRIGHT:");
- System.out.println("");
- System.out.println("Copyright © 2013, 2014 Mattias Andrée (maandree@member.fsf.org)");
- System.out.println("");
- System.out.println("This program is free software: you can redistribute it and/or modify");
- System.out.println("it under the terms of the GNU Affero General Public License as published by");
- System.out.println("the Free Software Foundation, either version 3 of the License, or");
- System.out.println("(at your option) any later version.");
- System.out.println("");
- System.out.println("This program is distributed in the hope that it will be useful,");
- System.out.println("but WITHOUT ANY WARRANTY; without even the implied warranty of");
- System.out.println("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the");
- System.out.println("GNU Affero General Public License for more details.");
- System.out.println("");
- System.out.println("You should have received a copy of the GNU Affero General Public License");
- System.out.println("along with this program. If not, see <http://www.gnu.org/licenses/>.");
- System.out.println("");
- System.exit(0);
- }
- else
- {
- if (linger[1] == null)
- {
- linger[1] = arg;
- arg = null;
- }
- if ((linger[0] == "-r") || (linger[0] == "--bitrate"))
- R = Integer.valueOf(linger[1]);
- else if ((linger[0] == "-c") || (linger[0] == "--capacity"))
- C = Integer.valueOf(linger[1]);
- else if ((linger[0] == "-w") || (linger[0] == "--wordsize"))
- W = Integer.valueOf(linger[1]);
- else if ((linger[0] == "-o") || (linger[0] == "--outputsize"))
- O = Integer.valueOf(linger[1]);
- else if ((linger[0] == "-s") || (linger[0] == "--statesize"))
- S = Integer.valueOf(linger[1]);
- else if ((linger[0] == "-i") || (linger[0] == "--iterations"))
- I = Integer.valueOf(linger[1]);
- else if ((linger[0] == "-j") || (linger[0] == "--squeezes"))
- J = Integer.valueOf(linger[1]);
- else
- {
- System.err.println(cmd + ": unrecognised option: " + linger[0]);
- System.exit(1);
- }
- }
- linger = null;
- if (arg == null)
- continue;
- }
- if (arg == null)
- continue;
- if (dashed)
- files[fptr++] = arg == "-" ? null : arg;
- else if (arg == "--")
- dashed = true;
- else if (arg == "-")
- files[fptr++] = null;
- else if (arg.startsWith("--"))
- if (arg.indexOf('=') >= 0)
- linger = new String[] { arg.substring(0, arg.indexOf('=')), arg.substring(arg.indexOf('=') + 1) };
- else
- if (arg == "--binary")
- binary = true;
- else if (arg == "--multi")
- multi++;
- else if (arg == "--hex")
- hex = true;
- else
- linger = new String[] { arg, null };
- else if (arg.startsWith("-"))
- {
- arg = arg.substring(1);
- if (arg.charAt(0) == 'b')
- {
- binary = true;
- arg = arg.substring(1);
- }
- else if (arg.charAt(0) == 'm')
- {
- multi++;
- arg = arg.substring(1);
- }
- else if (arg.charAt(0) == 'x')
- {
- hex = true;
- arg = arg.substring(1);
- }
- else if (arg.length() == 1)
- linger = new String[] { "-" + arg, null };
- else
- linger = new String[] { "-" + arg.charAt(0), arg.substring(1) };
- }
- else
- files[fptr++] = arg;
- }
-
-
- i = I == null ? _i : I.intValue();
- j = J == null ? _j : J.intValue();
-
- if (S != null)
- { s = S.intValue();
- if ((s <= 0) || (s > 1600) || (s % 25 != 0))
- { System.err.println(cmd + ": the state size must be a positive multiple of 25 and is limited to 1600.");
- System.exit(6);
- } }
-
- if (W != null)
- { w = W.intValue();
- if ((w <= 0) || (w > 64))
- { System.err.println(cmd + ": the word size must be positive and is limited to 64.");
- System.exit(6);
- }
- if ((S != null) && (s != w * 25))
- { System.err.println(cmd + ": the state size must be 25 times of the word size.");
- System.exit(6);
- }
- else if (S == null)
- S = new Integer(w * 25);
- }
-
- if (C != null)
- { c = C.intValue();
- if ((c <= 0) || ((c & 7) != 0))
- { System.err.println(cmd + ": the capacity must be a positive multiple of 8.");
- System.exit(6);
- } }
-
- if (R != null)
- { r = R.intValue();
- if ((r <= 0) || ((r & 7) != 0))
- { System.err.println(cmd + ": the bitrate must be a positive multiple of 8.");
- System.exit(6);
- } }
-
- if (O != null)
- { o = O.intValue();
- if (o <= 0)
- { System.err.println(cmd + ": the output size must be positive.");
- System.exit(6);
- } }
-
-
- if ((R == null) && (C == null) && (O == null)) // s?
- { c = -((r = (o = ((((s = S == null ? _s : s) << 5) / 100 + 7) >> 3) << 3) << 1) - s);
- o = o < 8 ? 8 : o;
- }
- else if ((R == null) && (C == null)) // !o s?
- { r = _r;
- c = _c;
- s = S == null ? (r + c) : s;
- }
- else if (R == null) // !c o? s?
- { r = (s = S == null ? _s : s) - c;
- o = O == null ? (c == 8 ? 8 : (c << 1)) : o;
- }
- else if (C == null) // !r o? s?
- { c = (s = S == null ? _s : s) - r;
- o = O == null ? (c == 8 ? 8 : (c << 1)) : o;
- }
- else // !r !c o? s?
- { s = S == null ? (r + c) : s;
- o = O == null ? (c == 8 ? 8 : (c << 1)) : o;
- }
-
-
- System.err.println("Bitrate: " + r);
- System.err.println("Capacity: " + c);
- System.err.println("Word size: " + w);
- System.err.println("State size: " + s);
- System.err.println("Output size: " + o);
- System.err.println("Iterations: " + i);
- System.err.println("Squeezes: " + j);
-
-
- if (r > s)
- { System.err.println(cmd + ": the bitrate must not be higher than the state size.");
- System.exit(6);
- }
- if (c > s)
- { System.err.println(cmd + ": the capacity must not be higher than the state size.");
- System.exit(6);
- }
- if (r + c != s)
- { System.err.println(cmd + ": the sum of the bitrate and the capacity must equal the state size.");
- System.exit(6);
- }
-
-
- if (fptr == 0)
- files[fptr++] = null;
- if (i < 1)
- {
- System.err.println(cmd + ": sorry, I will only do at least one hash iteration!");
- System.exit(3);
- }
- if (j < 1)
- {
- System.err.println(cmd + ": sorry, I will only do at least one squeeze iteration!");
- System.exit(3);
- }
-
- byte[] stdin = null;
- boolean fail = false;
- String filename;
-
- for (int f = 0; f < fptr; f++)
- { String rc = "";
- String fn = (filename = files[f]) == null ? "/dev/stdin" : filename;
- InputStream file = null;
- try
- {
- byte[] bs;
- if ((filename != null) || (stdin == null))
- {
- file = new FileInputStream(fn);
- SHA3.initialise(r, c, o);
- int blksize = 4096; /** XXX os.stat(os.path.realpath(fn)).st_size; **/
- byte[] chunk = new byte[blksize];
- for (;;)
- {
- int read = file.read(chunk, 0, blksize);
- if (read <= 0)
- break;
- if (hex == false)
- SHA3.update(chunk, read);
- else
- {
- int n = read >> 1;
- for (int k = 0; k < n; k++)
- { byte a = chunk[k << 1], b = chunk[(k << 1) | 1];
- chunk[k] = (byte)((((a & 15) + (a <= '9' ? 0 : 9)) << 4) | ((b & 15) + (b <= '9' ? 0 : 9)));
- }
- SHA3.update(chunk, n);
- }
- }
- bs = SHA3.digest(j == 1);
- if (j > 2)
- SHA3.fastSqueeze(j - 2);
- if (j > 1)
- bs = SHA3.squeeze();
- if (filename == null)
- stdin = bs;
- }
- else
- bs = stdin;
- if (multi == 0)
- {
- for (int k = 1; k < i; k++)
- {
- SHA3.initialise(r, c, o);
- bs = SHA3.digest(bs, j == 1);
- if (j > 2)
- SHA3.fastSqueeze(j - 2);
- if (j > 1)
- bs = SHA3.squeeze();
- }
- if (binary)
- System.out.write(bs);
- else
- { for (int b = 0, bn = bs.length; b < bn; b++)
- { rc += "0123456789ABCDEF".charAt((bs[b] >> 4) & 15);
- rc += "0123456789ABCDEF".charAt(bs[b] & 15);
- }
- rc += " " + (filename == null ? "-" : filename) + "\n";
- System.out.print(rc);
- }
- }
- else if (multi == 1)
- {
- byte[] out = null;
- if (binary)
- System.out.write(bs);
- else
- {
- out = new byte[(bs.length << 1) + 1];
- for (int b = 0, bn = bs.length; b < bn; b++)
- { out[ b << 1 ] = (byte)("0123456789ABCDEF".charAt((bs[b] >> 4) & 15));
- out[(b << 1) | 1] = (byte)("0123456789ABCDEF".charAt(bs[b] & 15));
- }
- out[out.length - 1] = '\n';
- System.out.write(out);
- }
- for (int k = 1; k < i; k++)
- {
- SHA3.initialise(r, c, o);
- bs = SHA3.digest(bs, j == 1);
- if (j > 2)
- SHA3.fastSqueeze(j - 2);
- if (j > 1)
- bs = SHA3.squeeze();
- if (binary)
- System.out.write(bs);
- else
- {
- for (int b = 0, bn = bs.length; b < bn; b++)
- { out[ b << 1 ] = (byte)("0123456789ABCDEF".charAt((bs[b] >> 4) & 15));
- out[(b << 1) | 1] = (byte)("0123456789ABCDEF".charAt(bs[b] & 15));
- }
- System.out.write(out);
- }
- }
- }
- else
- {
- HashSet<String> got = new HashSet<String>();
- String loop = null;
- byte[] out = new byte[(bs.length << 1)];
- for (int k = 0; k < i; k++)
- {
- if (k > 0)
- { SHA3.initialise(r, c, o);
- bs = SHA3.digest(bs, j == 1);
- if (j > 2)
- SHA3.fastSqueeze(j - 2);
- if (j > 1)
- bs = SHA3.squeeze();
- }
- for (int b = 0, bn = bs.length; b < bn; b++)
- { out[ b << 1 ] = (byte)("0123456789ABCDEF".charAt((bs[b] >> 4) & 15));
- out[(b << 1) | 1] = (byte)("0123456789ABCDEF".charAt(bs[b] & 15));
- }
- String now = new String(out, "UTF-8");
- if (loop == null)
- if (got.contains(now))
- loop = now;
- else
- got.add(now);
- if ((loop != null) && (loop.equals(now)))
- now = "\033[31m" + now + "\033[00m";
- System.out.println(now);
- }
- if (loop != null)
- System.err.println("\033[01;31mLoop found\033[00m");
- }
- System.out.flush();
- }
- catch (final IOException err)
- { System.err.println(cmd + ": cannot read file: " + filename + ": " + err);
- fail = true;
- }
- finally
- { if (file != null)
- try
- { file.close();
- }
- catch (final Throwable ignore)
- { //ignore
- } } }
-
- System.out.flush();
- if (fail)
- System.exit(5);
- }
-
-}
-
diff --git a/python2/sha3.py b/python2/sha3.py
deleted file mode 100644
index ecc3bc8..0000000
--- a/python2/sha3.py
+++ /dev/null
@@ -1,668 +0,0 @@
-#!/usr/bin/env python2
-# -*- coding: utf-8 -*-
-'''
-sha3sum – SHA-3 (Keccak) checksum calculator
-
-Copyright © 2013, 2014 Mattias Andrée (maandree@member.fsf.org)
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU Affero General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Affero General Public License for more details.
-
-You should have received a copy of the GNU Affero General Public License
-along with this program. If not, see <http://www.gnu.org/licenses/>.
-'''
-
-class SHA3:
- '''
- SHA-3/Keccak hash algorithm implementation
-
- @author Mattias Andrée (maandree@member.fsf.org)
- '''
-
-
- KECCAK_SUFFIX = ''
- '''
- :str Suffix the message when calculating the Keccak hash sum
- '''
-
- SHA3_SUFFIX = '01'
- '''
- :str Suffix the message when calculating the SHA-3 hash sum
- '''
-
- RawSHAKE_SUFFIX = '11'
- '''
- :str Suffix the message when calculating the RawSHAKE hash sum
- '''
-
- SHAKE_SUFFIX = '1111'
- '''
- :str Suffix the message when calculating the SHAKE hash sum
- '''
-
-
- def __init__(self):
- '''
- Constructor
- '''
-
- self.RC = [0x0000000000000001, 0x0000000000008082, 0x800000000000808A, 0x8000000080008000,
- 0x000000000000808B, 0x0000000080000001, 0x8000000080008081, 0x8000000000008009,
- 0x000000000000008A, 0x0000000000000088, 0x0000000080008009, 0x000000008000000A,
- 0x000000008000808B, 0x800000000000008B, 0x8000000000008089, 0x8000000000008003,
- 0x8000000000008002, 0x8000000000000080, 0x000000000000800A, 0x800000008000000A,
- 0x8000000080008081, 0x8000000000008080, 0x0000000080000001, 0x8000000080008008]
- '''
- :list<int> Round contants
- '''
-
- self.B = [0] * 25
- '''
- :list<int> Keccak-f round temporary
- '''
-
- self.C = [0] * 5
- '''
- :list<int> Keccak-f round temporary
- '''
-
-
- (self.r, self.c, self.n, self.b, self.w, self.wmod, self.l, self.nr) = (0, 0, 0, 0, 0, 0, 0, 0)
- '''
- r:int The bitrate
- c:int The capacity
- n:int The output size
- b:int The state size
- w:int The word size
- wmod:int The word mask
- l:int ℓ, the binary logarithm of the word size
- nr:int 12 + 2ℓ, the number of rounds
- '''
-
- self.S = None
- '''
- :list<int> The current state
- '''
-
- self.M = None
- '''
- :bytes Left over water to fill the sponge with at next update
- '''
-
-
-
- def rotate(self, x, n):
- '''
- Rotate a word
-
- @param x:int The value to rotate
- @param n:int Rotation steps
- @return :int The value rotated
- '''
- m = n % self.w
- return ((x >> (self.w - m)) + (x << m)) & self.wmod
-
-
- def rotate64(self, x, n):
- '''
- Rotate a 64-bit word
-
- @param x:int The value to rotate
- @param n:int Rotation steps
- @return :int The value rotated
- '''
- return ((x >> (64 - n)) + (x << n)) & 0xFFFFFFFFFFFFFFFF
-
-
- def lb(self, x):
- '''
- Binary logarithm
-
- @param x:int The value of which to calculate the binary logarithm
- @return :int The binary logarithm
- '''
- rc = 0
- if (x & 0xFF00) != 0: rc += 8 ; x >>= 8
- if (x & 0x00F0) != 0: rc += 4 ; x >>= 4
- if (x & 0x000C) != 0: rc += 2 ; x >>= 2
- if (x & 0x0002) != 0: rc += 1
- return rc
-
-
- def keccakFRound(self, A, rc):
- '''
- Perform one round of computation
-
- @param A:list<int> The current state
- @param rc:int Round constant
- '''
- if self.w == 64:
- # θ step (step 1 and 2 of 3)
- self.C[0] = (A[0] ^ A[1]) ^ (A[2] ^ A[3]) ^ A[4]
- self.C[2] = (A[10] ^ A[11]) ^ (A[12] ^ A[13]) ^ A[14]
- db = self.C[0] ^ self.rotate64(self.C[2], 1)
- self.C[4] = (A[20] ^ A[21]) ^ (A[22] ^ A[23]) ^ A[24]
- dd = self.C[2] ^ self.rotate64(self.C[4], 1)
- self.C[1] = (A[5] ^ A[6]) ^ (A[7] ^ A[8]) ^ A[9]
- da = self.C[4] ^ self.rotate64(self.C[1], 1)
- self.C[3] = (A[15] ^ A[16]) ^ (A[17] ^ A[18]) ^ A[19]
- dc = self.C[1] ^ self.rotate64(self.C[3], 1)
- de = self.C[3] ^ self.rotate64(self.C[0], 1)
-
- # ρ and π steps, with last part of θ
- self.B[0] = self.rotate64(A[0] ^ da, 0)
- self.B[1] = self.rotate64(A[15] ^ dd, 28)
- self.B[2] = self.rotate64(A[5] ^ db, 1)
- self.B[3] = self.rotate64(A[20] ^ de, 27)
- self.B[4] = self.rotate64(A[10] ^ dc, 62)
-
- self.B[5] = self.rotate64(A[6] ^ db, 44)
- self.B[6] = self.rotate64(A[21] ^ de, 20)
- self.B[7] = self.rotate64(A[11] ^ dc, 6)
- self.B[8] = self.rotate64(A[1] ^ da, 36)
- self.B[9] = self.rotate64(A[16] ^ dd, 55)
-
- self.B[10] = self.rotate64(A[12] ^ dc, 43)
- self.B[11] = self.rotate64(A[2] ^ da, 3)
- self.B[12] = self.rotate64(A[17] ^ dd, 25)
- self.B[13] = self.rotate64(A[7] ^ db, 10)
- self.B[14] = self.rotate64(A[22] ^ de, 39)
-
- self.B[15] = self.rotate64(A[18] ^ dd, 21)
- self.B[16] = self.rotate64(A[8] ^ db, 45)
- self.B[17] = self.rotate64(A[23] ^ de, 8)
- self.B[18] = self.rotate64(A[13] ^ dc, 15)
- self.B[19] = self.rotate64(A[3] ^ da, 41)
-
- self.B[20] = self.rotate64(A[24] ^ de, 14)
- self.B[21] = self.rotate64(A[14] ^ dc, 61)
- self.B[22] = self.rotate64(A[4] ^ da, 18)
- self.B[23] = self.rotate64(A[19] ^ dd, 56)
- self.B[24] = self.rotate64(A[9] ^ db, 2)
- else:
- # θ step (step 1 and 2 of 3)
- self.C[0] = (A[0] ^ A[1]) ^ (A[2] ^ A[3]) ^ A[4]
- self.C[2] = (A[10] ^ A[11]) ^ (A[12] ^ A[13]) ^ A[14]
- db = self.C[0] ^ self.rotate(self.C[2], 1)
- self.C[4] = (A[20] ^ A[21]) ^ (A[22] ^ A[23]) ^ A[24]
- dd = self.C[2] ^ self.rotate(self.C[4], 1)
- self.C[1] = (A[5] ^ A[6]) ^ (A[7] ^ A[8]) ^ A[9]
- da = self.C[4] ^ self.rotate(self.C[1], 1)
- self.C[3] = (A[15] ^ A[16]) ^ (A[17] ^ A[18]) ^ A[19]
- dc = self.C[1] ^ self.rotate(self.C[3], 1)
- de = self.C[3] ^ self.rotate(self.C[0], 1)
-
- # ρ and π steps, with last part of θ
- self.B[0] = self.rotate(A[0] ^ da, 0)
- self.B[1] = self.rotate(A[15] ^ dd, 28)
- self.B[2] = self.rotate(A[5] ^ db, 1)
- self.B[3] = self.rotate(A[20] ^ de, 27)
- self.B[4] = self.rotate(A[10] ^ dc, 62)
-
- self.B[5] = self.rotate(A[6] ^ db, 44)
- self.B[6] = self.rotate(A[21] ^ de, 20)
- self.B[7] = self.rotate(A[11] ^ dc, 6)
- self.B[8] = self.rotate(A[1] ^ da, 36)
- self.B[9] = self.rotate(A[16] ^ dd, 55)
-
- self.B[10] = self.rotate(A[12] ^ dc, 43)
- self.B[11] = self.rotate(A[2] ^ da, 3)
- self.B[12] = self.rotate(A[17] ^ dd, 25)
- self.B[13] = self.rotate(A[7] ^ db, 10)
- self.B[14] = self.rotate(A[22] ^ de, 39)
-
- self.B[15] = self.rotate(A[18] ^ dd, 21)
- self.B[16] = self.rotate(A[8] ^ db, 45)
- self.B[17] = self.rotate(A[23] ^ de, 8)
- self.B[18] = self.rotate(A[13] ^ dc, 15)
- self.B[19] = self.rotate(A[3] ^ da, 41)
-
- self.B[20] = self.rotate(A[24] ^ de, 14)
- self.B[21] = self.rotate(A[14] ^ dc, 61)
- self.B[22] = self.rotate(A[4] ^ da, 18)
- self.B[23] = self.rotate(A[19] ^ dd, 56)
- self.B[24] = self.rotate(A[9] ^ db, 2)
-
- # ξ step
- A[0] = self.B[0] ^ ((~(self.B[5])) & self.B[10])
- A[1] = self.B[1] ^ ((~(self.B[6])) & self.B[11])
- A[2] = self.B[2] ^ ((~(self.B[7])) & self.B[12])
- A[3] = self.B[3] ^ ((~(self.B[8])) & self.B[13])
- A[4] = self.B[4] ^ ((~(self.B[9])) & self.B[14])
-
- A[5] = self.B[5] ^ ((~(self.B[10])) & self.B[15])
- A[6] = self.B[6] ^ ((~(self.B[11])) & self.B[16])
- A[7] = self.B[7] ^ ((~(self.B[12])) & self.B[17])
- A[8] = self.B[8] ^ ((~(self.B[13])) & self.B[18])
- A[9] = self.B[9] ^ ((~(self.B[14])) & self.B[19])
-
- A[10] = self.B[10] ^ ((~(self.B[15])) & self.B[20])
- A[11] = self.B[11] ^ ((~(self.B[16])) & self.B[21])
- A[12] = self.B[12] ^ ((~(self.B[17])) & self.B[22])
- A[13] = self.B[13] ^ ((~(self.B[18])) & self.B[23])
- A[14] = self.B[14] ^ ((~(self.B[19])) & self.B[24])
-
- A[15] = self.B[15] ^ ((~(self.B[20])) & self.B[0])
- A[16] = self.B[16] ^ ((~(self.B[21])) & self.B[1])
- A[17] = self.B[17] ^ ((~(self.B[22])) & self.B[2])
- A[18] = self.B[18] ^ ((~(self.B[23])) & self.B[3])
- A[19] = self.B[19] ^ ((~(self.B[24])) & self.B[4])
-
- A[20] = self.B[20] ^ ((~(self.B[0])) & self.B[5])
- A[21] = self.B[21] ^ ((~(self.B[1])) & self.B[6])
- A[22] = self.B[22] ^ ((~(self.B[2])) & self.B[7])
- A[23] = self.B[23] ^ ((~(self.B[3])) & self.B[8])
- A[24] = self.B[24] ^ ((~(self.B[4])) & self.B[9])
-
- # ι step
- A[0] ^= rc
-
-
- def keccakF(self, A):
- '''
- Perform Keccak-f function
-
- @param A:list<int> The current state
- '''
- if (self.nr == 24):
- self.keccakFRound(A, 0x0000000000000001)
- self.keccakFRound(A, 0x0000000000008082)
- self.keccakFRound(A, 0x800000000000808A)
- self.keccakFRound(A, 0x8000000080008000)
- self.keccakFRound(A, 0x000000000000808B)
- self.keccakFRound(A, 0x0000000080000001)
- self.keccakFRound(A, 0x8000000080008081)
- self.keccakFRound(A, 0x8000000000008009)
- self.keccakFRound(A, 0x000000000000008A)
- self.keccakFRound(A, 0x0000000000000088)
- self.keccakFRound(A, 0x0000000080008009)
- self.keccakFRound(A, 0x000000008000000A)
- self.keccakFRound(A, 0x000000008000808B)
- self.keccakFRound(A, 0x800000000000008B)
- self.keccakFRound(A, 0x8000000000008089)
- self.keccakFRound(A, 0x8000000000008003)
- self.keccakFRound(A, 0x8000000000008002)
- self.keccakFRound(A, 0x8000000000000080)
- self.keccakFRound(A, 0x000000000000800A)
- self.keccakFRound(A, 0x800000008000000A)
- self.keccakFRound(A, 0x8000000080008081)
- self.keccakFRound(A, 0x8000000000008080)
- self.keccakFRound(A, 0x0000000080000001)
- self.keccakFRound(A, 0x8000000080008008)
- else:
- for i in range(self.nr):
- self.keccakFRound(A, self.RC[i] & self.wmod)
-
-
- def toLane(self, message, n, ww, off):
- '''
- Convert a chunk of byte:s to a word
-
- @param message:bytes The message
- @param n:int `min(len(message), rr)`
- rr:int Bitrate in bytes
- @param ww:int Word size in bytes
- @param off:int The offset in the message
- @return :int Lane
- '''
- rc = 0
- i = off + ww - 1
- while i >= off:
- rc = (rc << 8) | (message[i] if (i < n) else 0)
- i -= 1
- return rc
-
-
- def toLane64(self, message, n, off):
- '''
- Convert a chunk of byte:s to a 64-bit word
-
- @param message:bytes The message
- @param n:int `min(len(message), rr)`
- rr:int Bitrate in bytes
- @param off:int The offset in the message
- @return :int Lane
- '''
- return ((message[off + 7] << 56) if (off + 7 < n) else 0) | \
- ((message[off + 6] << 48) if (off + 6 < n) else 0) | \
- ((message[off + 5] << 40) if (off + 5 < n) else 0) | \
- ((message[off + 4] << 32) if (off + 4 < n) else 0) | \
- ((message[off + 3] << 24) if (off + 3 < n) else 0) | \
- ((message[off + 2] << 16) if (off + 2 < n) else 0) | \
- ((message[off + 1] << 8) if (off + 1 < n) else 0) | \
- ((message[off]) if (off < n) else 0)
-
-
- def pad10star1(self, msg, r, bits):
- '''
- pad 10*1
-
- @param msg:bytes The message to pad
- @param r:int The bitrate
- @param bits:int The number of bits in the end of the message that does not make a whole byte
- @return :bytes The message padded
- '''
- nnn = ((len(msg) - (bits + 7) // 8) << 3) + bits
-
- nrf = nnn >> 3
- nbrf = nnn & 7
- ll = nnn % r
-
- bbbb = 1 if nbrf == 0 else (msg[nrf] | (1 << nbrf))
-
- message = None
- if ((r - 8 <= ll) and (ll <= r - 2)):
- message = [bbbb ^ 128]
- else:
- nnn = (nrf + 1) << 3
- nnn = ((nnn - (nnn % r) + (r - 8)) >> 3) + 1
- message = [0] * (nnn - nrf)
- message[0] = bbbb
- nnn -= nrf
- message[nnn - 1] = 0x80
-
- return msg[:nrf] + message
-
-
- def initialise(self, r, c, n):
- '''
- Initialise Keccak sponge
-
- @param r:int The bitrate
- @param c:int The capacity
- @param n:int The output size
- '''
- self.r = r
- self.c = c
- self.n = n
- self.b = r + c
- self.w = self.b // 25
- self.l = self.lb(self.w)
- self.nr = 12 + (self.l << 1)
- self.wmod = (1 << self.w) - 1
- self.S = [0] * 25
- self.M = []
-
-
- def update(self, msg, msglen = None):
- '''
- Absorb the more of the message message to the Keccak sponge
-
- @param msg:bytes The partial message
- @param msglen:int The length of the partial message in whole bytes
- '''
- if msglen is not None:
- msg = msg[:msglen]
-
- rr = self.r >> 3
- ww = self.w >> 3
-
- self.M += msg
- nnn = len(self.M)
- nnn -= nnn % ((self.r * self.b) >> 3)
- message = self.M[:nnn]
- self.M = self.M[nnn:]
-
- # Absorbing phase
- if ww == 8:
- for i in range(0, nnn, rr):
- n = min(len(message), rr)
- self.S[ 0] ^= self.toLane64(message, n, 0)
- self.S[ 5] ^= self.toLane64(message, n, 8)
- self.S[10] ^= self.toLane64(message, n, 16)
- self.S[15] ^= self.toLane64(message, n, 24)
- self.S[20] ^= self.toLane64(message, n, 32)
- self.S[ 1] ^= self.toLane64(message, n, 40)
- self.S[ 6] ^= self.toLane64(message, n, 48)
- self.S[11] ^= self.toLane64(message, n, 56)
- self.S[16] ^= self.toLane64(message, n, 64)
- self.S[21] ^= self.toLane64(message, n, 72)
- self.S[ 2] ^= self.toLane64(message, n, 80)
- self.S[ 7] ^= self.toLane64(message, n, 88)
- self.S[12] ^= self.toLane64(message, n, 96)
- self.S[17] ^= self.toLane64(message, n, 104)
- self.S[22] ^= self.toLane64(message, n, 112)
- self.S[ 3] ^= self.toLane64(message, n, 120)
- self.S[ 8] ^= self.toLane64(message, n, 128)
- self.S[13] ^= self.toLane64(message, n, 136)
- self.S[18] ^= self.toLane64(message, n, 144)
- self.S[23] ^= self.toLane64(message, n, 152)
- self.S[ 4] ^= self.toLane64(message, n, 160)
- self.S[ 9] ^= self.toLane64(message, n, 168)
- self.S[14] ^= self.toLane64(message, n, 176)
- self.S[19] ^= self.toLane64(message, n, 184)
- self.S[24] ^= self.toLane64(message, n, 192)
- self.keccakF(self.S)
- message = message[rr:]
- else:
- for i in range(0, nnn, rr):
- n = min(len(message), rr)
- self.S[ 0] ^= self.toLane(message, n, ww, 0)
- self.S[ 5] ^= self.toLane(message, n, ww, ww)
- self.S[10] ^= self.toLane(message, n, ww, 2 * ww)
- self.S[15] ^= self.toLane(message, n, ww, 3 * ww)
- self.S[20] ^= self.toLane(message, n, ww, 4 * ww)
- self.S[ 1] ^= self.toLane(message, n, ww, 5 * ww)
- self.S[ 6] ^= self.toLane(message, n, ww, 6 * ww)
- self.S[11] ^= self.toLane(message, n, ww, 7 * ww)
- self.S[16] ^= self.toLane(message, n, ww, 8 * ww)
- self.S[21] ^= self.toLane(message, n, ww, 9 * ww)
- self.S[ 2] ^= self.toLane(message, n, ww, 10 * ww)
- self.S[ 7] ^= self.toLane(message, n, ww, 11 * ww)
- self.S[12] ^= self.toLane(message, n, ww, 12 * ww)
- self.S[17] ^= self.toLane(message, n, ww, 13 * ww)
- self.S[22] ^= self.toLane(message, n, ww, 14 * ww)
- self.S[ 3] ^= self.toLane(message, n, ww, 15 * ww)
- self.S[ 8] ^= self.toLane(message, n, ww, 16 * ww)
- self.S[13] ^= self.toLane(message, n, ww, 17 * ww)
- self.S[18] ^= self.toLane(message, n, ww, 18 * ww)
- self.S[23] ^= self.toLane(message, n, ww, 19 * ww)
- self.S[ 4] ^= self.toLane(message, n, ww, 20 * ww)
- self.S[ 9] ^= self.toLane(message, n, ww, 21 * ww)
- self.S[14] ^= self.toLane(message, n, ww, 22 * ww)
- self.S[19] ^= self.toLane(message, n, ww, 23 * ww)
- self.S[24] ^= self.toLane(message, n, ww, 24 * ww)
- self.keccakF(self.S)
- message = message[rr:]
-
-
- def digest(self, msg = None, msglen = None, bits = 0, suffix = SHA3_SUFFIX, withReturn = None):
- '''
- Absorb the last part of the message and squeeze the Keccak sponge
-
- @param msg:bytes? The rest of the message
- @param msglen:int The length of the partial message in whole bytes
- @param bits:int The number of bits at the end of the message not covered by `msglen`
- @param suffix:str The suffix concatenate to the message
- @param withReturn:bool Whether to return the hash instead of just do a quick squeeze phrase and return `None`
- @return :bytes? The hash sum, or `None` if `withReturn` is `False`
- '''
- if msg is None:
- msg, last_byte = [], 0
- bits = 0
- else:
- msg, last_byte = msg[:msglen + bits // 8], (0 if bits % 8 == 0 else msg[msglen])
- bits %= 8
- last_byte &= (1 << bits) - 1
- msg_end = []
- for bit in suffix:
- last_byte |= int(bit) << bits
- bits += 1
- if bits == 8:
- msg_end.append(last_byte)
- last_byte = 0
- bits = 0
- if not bits == 0:
- msg_end.append(last_byte)
- msg += msg_end
- message = self.pad10star1(self.M + msg, self.r, bits)
- self.M = None
- nnn = len(message)
-
- rr = self.r >> 3
- nn = (self.n + 7) >> 3
- ww = self.w >> 3
-
- # Absorbing phase
- if ww == 8:
- for i in range(0, nnn, rr):
- n = min(len(message), rr)
- self.S[ 0] ^= self.toLane64(message, n, 0)
- self.S[ 5] ^= self.toLane64(message, n, 8)
- self.S[10] ^= self.toLane64(message, n, 16)
- self.S[15] ^= self.toLane64(message, n, 24)
- self.S[20] ^= self.toLane64(message, n, 32)
- self.S[ 1] ^= self.toLane64(message, n, 40)
- self.S[ 6] ^= self.toLane64(message, n, 48)
- self.S[11] ^= self.toLane64(message, n, 56)
- self.S[16] ^= self.toLane64(message, n, 64)
- self.S[21] ^= self.toLane64(message, n, 72)
- self.S[ 2] ^= self.toLane64(message, n, 80)
- self.S[ 7] ^= self.toLane64(message, n, 88)
- self.S[12] ^= self.toLane64(message, n, 96)
- self.S[17] ^= self.toLane64(message, n, 104)
- self.S[22] ^= self.toLane64(message, n, 112)
- self.S[ 3] ^= self.toLane64(message, n, 120)
- self.S[ 8] ^= self.toLane64(message, n, 128)
- self.S[13] ^= self.toLane64(message, n, 136)
- self.S[18] ^= self.toLane64(message, n, 144)
- self.S[23] ^= self.toLane64(message, n, 152)
- self.S[ 4] ^= self.toLane64(message, n, 160)
- self.S[ 9] ^= self.toLane64(message, n, 168)
- self.S[14] ^= self.toLane64(message, n, 176)
- self.S[19] ^= self.toLane64(message, n, 184)
- self.S[24] ^= self.toLane64(message, n, 192)
- self.keccakF(self.S)
- message = message[rr:]
- else:
- for i in range(0, nnn, rr):
- n = min(len(message), rr)
- self.S[ 0] ^= self.toLane(message, n, ww, 0)
- self.S[ 5] ^= self.toLane(message, n, ww, ww)
- self.S[10] ^= self.toLane(message, n, ww, 2 * ww)
- self.S[15] ^= self.toLane(message, n, ww, 3 * ww)
- self.S[20] ^= self.toLane(message, n, ww, 4 * ww)
- self.S[ 1] ^= self.toLane(message, n, ww, 5 * ww)
- self.S[ 6] ^= self.toLane(message, n, ww, 6 * ww)
- self.S[11] ^= self.toLane(message, n, ww, 7 * ww)
- self.S[16] ^= self.toLane(message, n, ww, 8 * ww)
- self.S[21] ^= self.toLane(message, n, ww, 9 * ww)
- self.S[ 2] ^= self.toLane(message, n, ww, 10 * ww)
- self.S[ 7] ^= self.toLane(message, n, ww, 11 * ww)
- self.S[12] ^= self.toLane(message, n, ww, 12 * ww)
- self.S[17] ^= self.toLane(message, n, ww, 13 * ww)
- self.S[22] ^= self.toLane(message, n, ww, 14 * ww)
- self.S[ 3] ^= self.toLane(message, n, ww, 15 * ww)
- self.S[ 8] ^= self.toLane(message, n, ww, 16 * ww)
- self.S[13] ^= self.toLane(message, n, ww, 17 * ww)
- self.S[18] ^= self.toLane(message, n, ww, 18 * ww)
- self.S[23] ^= self.toLane(message, n, ww, 19 * ww)
- self.S[ 4] ^= self.toLane(message, n, ww, 20 * ww)
- self.S[ 9] ^= self.toLane(message, n, ww, 21 * ww)
- self.S[14] ^= self.toLane(message, n, ww, 22 * ww)
- self.S[19] ^= self.toLane(message, n, ww, 23 * ww)
- self.S[24] ^= self.toLane(message, n, ww, 24 * ww)
- self.keccakF(self.S)
- message = message[rr:]
-
- # Squeezing phase
- if withReturn:
- rc = [0] * ((self.n + 7) >> 3)
- ptr = 0
-
- olen = self.n
- j = 0
- ni = rr // ww
- while olen > 0:
- i = 0
- while (i < ni) and (j < nn):
- v = self.S[(i % 5) * 5 + i // 5]
- for _ in range(ww):
- if j < nn:
- rc[ptr] = v & 255
- ptr += 1
- v >>= 8
- j += 1
- i += 1
- olen -= self.r
- if olen > 0:
- self.keccakF(self.S)
- if (self.n & 7) != 0:
- rc[len(rc) - 1] &= (1 << (self.n & 7)) - 1
-
- return rc
-
- olen = self.n
- while olen > self.r:
- olen -= self.r
- self.keccakF(self.S)
- return None
-
-
- def simpleSqueeze(self, times = 1):
- '''
- Force some rounds of Keccak-f
-
- @param times:int The number of rounds
- '''
- for i in range(times):
- self.keccakF(self.S)
-
-
- def fastSqueeze(self, times = 1):
- '''
- Squeeze as much as is needed to get a digest a number of times
-
- @param times:int The number of digests
- '''
- for i in range(times):
- self.keccakF(self.S) # Last squeeze did not do a ending squeeze
- olen = self.n
- while olen > self.r:
- olen -= self.r
- self.keccakF(self.S)
-
-
- def squeeze(self):
- '''
- Squeeze out another digest
-
- @return :bytes The hash sum
- '''
- self.keccakF(self.S) # Last squeeze did not do a ending squeeze
-
- nn = (self.n + 7) >> 3
- ww = self.w >> 3
- rc = [0] * nn
- olen = self.n
- j = 0
- ptr = 0
- ni = (self.r >> 3) // ww
-
- while olen > 0:
- i = 0
- while (i < ni) and (j < nn):
- v = self.S[(i % 5) * 5 + i // 5]
- for _ in range(ww):
- if j < nn:
- rc[ptr] = v
- ptr += 1
- v >>= 8
- j += 1
- i += 1
- olen -= self.r
- if olen > 0:
- self.keccakF(self.S)
-
- if (self.n & 7) != 0:
- rc[len(rc) - 1] &= (1 << (self.n & 7)) - 1
-
- return rc
-
diff --git a/python2/sha3sum.py b/python2/sha3sum.py
deleted file mode 100755
index ce00cb3..0000000
--- a/python2/sha3sum.py
+++ /dev/null
@@ -1,398 +0,0 @@
-#!/usr/bin/env python2
-# -*- coding: utf-8 -*-
-'''
-sha3sum – SHA-3 (Keccak) checksum calculator
-
-Copyright © 2013, 2014 Mattias Andrée (maandree@member.fsf.org)
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU Affero General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Affero General Public License for more details.
-
-You should have received a copy of the GNU Affero General Public License
-along with this program. If not, see <http://www.gnu.org/licenses/>.
-'''
-
-import sys
-import os
-
-from sha3 import SHA3
-
-
-stdout = os.fdopen(1, 'w')
-stderr = os.fdopen(2, 'w')
-
-
-def printerr(text, end = '\n'):
- stderr.write(text + end)
- stderr.flush()
-
-
-def write(data):
- stdout.write(data)
-
-
-def flush():
- stdout.flush()
-
-
-
-if __name__ == '__main__':
- cmd = sys.argv[0]
- args = sys.argv[1:]
- if '/' in cmd:
- cmd = cmd[cmd.rfind('/') + 1:]
- if cmd.endswith('.py'):
- cmd = cmd[:-3]
-
- (O, S, R, C, W, I, J) = (None, None, None, None, None, None, None)
- (o, s, r, c, w, i, j) = (0, 0, 0, 0, 0, 0, 0)
- _o = 512 # --outputsize
- if cmd == 'sha3-224sum': _o = 224
- elif cmd == 'sha3-256sum': _o = 256
- elif cmd == 'sha3-384sum': _o = 384
- elif cmd == 'sha3-512sum': _o = 512
- _s = 1600 # --statesize
- _c = _s - (_o << 1) # --capacity
- _r = _s - _c # --bitrate
- _w = _s / 25 # --wordsize
- _i = 1 # --iterations
- _j = 1 # --squeezes
- (binary, hex, multi) = (False, False, 0)
-
- files = []
- dashed = False
- linger = None
-
- for arg in args + [None]:
- if linger is not None:
- if linger[0] in ('-h', '--help'):
- sys.stderr.buffer.write(('''
-SHA-3/Keccak checksum calculator
-
-USAGE: sha3sum [option...] < file
- sha3sum [option...] file...
-
-
-OPTIONS:
- -r BITRATE
- --bitrate The bitrate to use for checksum. (default: %d)
-
- -c CAPACITY
- --capacity The capacity to use for checksum. (default: %d)
-
- -w WORDSIZE
- --wordsize The word size to use for checksum. (default: %d)
-
- -o OUTPUTSIZE
- --outputsize The output size to use for checksum. (default: %d)
-
- -s STATESIZE
- --statesize The state size to use for checksum. (default: %d)
-
- -i ITERATIONS
- --iterations The number of hash iterations to run. (default: %d)
-
- -j SQUEEZES
- --squeezes The number of hash squeezes to run. (default: %d)
-
- -x
- --hex Read the input in hexadecimal, rather than binary.
-
- -b
- --binary Print the checksum in binary, rather than hexadecimal.
-
- -m
- --multi Print the checksum at all iterations.
-
-
-COPYRIGHT:
-
-Copyright © 2013, 2014 Mattias Andrée (maandree@member.fsf.org)
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU Affero General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Affero General Public License for more details.
-
-You should have received a copy of the GNU Affero General Public License
-along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-''' % (_r, _c, _w, _o, _s, _i, _j)).encode('utf-8'))
- sys.stderr.buffer.flush()
- exit(0)
- else:
- if linger[1] is None:
- linger[1] = arg
- arg = None
- if linger[0] in ('-r', '--bitrate'):
- R = int(linger[1])
- elif linger[0] in ('-c', '--capacity'):
- C = int(linger[1])
- elif linger[0] in ('-w', '--wordsize'):
- W = int(linger[1])
- elif linger[0] in ('-o', '--outputsize'):
- O = int(linger[1])
- elif linger[0] in ('-s', '--statesize'):
- S = int(linger[1])
- elif linger[0] in ('-i', '--iterations'):
- I = int(linger[1])
- elif linger[0] in ('-j', '--squeezes'):
- J = int(linger[1])
- else:
- printerr(sys.argv[0] + ': unrecognised option: ' + linger[0])
- sys.exit(1)
- linger = None
- if arg is None:
- continue
- if arg is None:
- continue
- if dashed:
- files.append(None if arg == '-' else arg)
- elif arg == '--':
- dashed = True
- elif arg == '-':
- files.append(None)
- elif arg.startswith('--'):
- if '=' in arg:
- linger = (arg[:arg.find('=')], arg[arg.find('=') + 1:])
- else:
- if arg == '--binary':
- binary = True
- elif arg == '--multi':
- multi += 1
- elif arg == '--hex':
- hex = True
- else:
- linger = [arg, None]
- elif arg.startswith('-'):
- arg = arg[1:]
- if arg[0] == 'b':
- binary = True
- arg = arg[1:]
- elif arg[0] == 'b':
- multi += 1
- arg = arg[1:]
- elif arg[0] == 'x':
- hex = True
- arg = arg[1:]
- elif len(arg) == 1:
- linger = ['-' + arg, None]
- else:
- linger = ['-' + arg[0], arg[1:]]
- else:
- files.append(arg)
-
-
- i = _i if I is None else I
- j = _j if J is None else J
-
-
- if S is not None:
- s = S
- if ((s <= 0) or (s > 1600) or (s % 25 != 0)):
- printerr(cmd + ': the state size must be a positive multiple of 25 and is limited to 1600.')
- sys.exit(6)
-
- if W is not None:
- w = W
- if (w <= 0) or (w > 64):
- printerr(cmd + ': the word size must be positive and is limited to 64.')
- sys.exit(6)
- if (S is not None) and (s != w * 25):
- printerr(cmd + ': the state size must be 25 times of the word size.')
- sys.exit(6)
- elif S is None:
- S = w * 25
-
- if C is not None:
- c = C
- if (c <= 0) or ((c & 7) != 0):
- printerr(cmd + ': the capacity must be a positive multiple of 8.')
- sys.exit(6)
-
- if R is not None:
- r = R
- if (r <= 0) or ((r & 7) != 0):
- printerr(cmd + ': the bitrate must be a positive multiple of 8.')
- sys.exit(6)
-
- if O is not None:
- o = O
- if o <= 0:
- printerr(cmd + ': the output size must be positive.')
- sys.exit(6)
-
-
- if (R is None) and (C is None) and (O is None): ## s?
- s = _s if S is None else s
- o = (((s << 5) // 100 + 7) >> 3) << 3
- r = o << 1
- c = s - r
- o = 8 if o < 8 else o
- elif (R is None) and (C is None): ## !o s?
- r = _r
- c = _c
- s = (r + c) if S is None else s
- elif R is None: ## !c o? s?
- s = _s if S is None else s
- r = s - c
- o = (8 if c == 8 else (c << 1)) if O is None else o
- elif C is None: ## !r o? s?
- s = _s if S is None else s
- c = s - r
- o = (8 if c == 8 else (c << 1)) if O is None else o
- else: ## !r !c o? s?
- s = (r + c) if S is None else s
- o = (8 if c == 8 else (c << 1)) if O is None else o
-
-
- printerr('Bitrate: %d' % r)
- printerr('Capacity: %d' % c)
- printerr('Word size: %d' % w)
- printerr('State size: %d' % s)
- printerr('Output size: %d' % o)
- printerr('Iterations: %d' % i)
- printerr('Squeezes: %d' % j)
-
-
- if r > s:
- printerr(cmd + ': the bitrate must not be higher than the state size.')
- sys.exit(6)
- if c > s:
- printerr(cmd + ': the capacity must not be higher than the state size.')
- sys.exit(6)
- if r + c != s:
- printerr(cmd + ': the sum of the bitrate and the capacity must equal the state size.')
- sys.exit(6)
-
-
- if len(files) == 0:
- files.append(None)
- if i < 1:
- printerr(cmd + ': sorry, I will only do at least one hash iteration!\n')
- sys.exit(3)
- if j < 1:
- printerr(cmd + ': sorry, I will only do at least one squeeze iteration!\n')
- sys.exit(3)
- stdin = None
- fail = False
- sha = SHA3()
- for filename in files:
- rc = ''
- fn = '/dev/stdin' if filename is None else filename
- with open(fn, 'rb') as file:
- try:
- if (filename is not None) or (stdin is None):
- sha.initialise(r, c, o)
- blksize = 4096
- try:
- blksize = os.stat(os.path.realpath(fn)).st_blksize
- if blksize <= 0:
- blksize = 4096
- except:
- pass
- while True:
- chunk = [ord(b) for b in file.read(blksize)]
- if len(chunk) == 0:
- break
- if not hex:
- sha.update(chunk)
- else:
- n = len(chunk) >> 1
- for _ in range(n):
- (a, b) = (chunk[_ << 1], chunk[(_ << 1 | 1)])
- a = ((a & 15) + (0 if a <= '9' else 9)) << 4
- b = (b & 15) + (0 if b <= '9' else 0)
- chunk[_] = a | b
- sha.update(chunk, n)
- bs = sha.digest(withReturn = j == 1)
- if j > 2:
- sha.fastSqueeze(j - 2)
- if j > 1:
- bs = sha.squeeze();
- if filename is None:
- stdin = bs
- else:
- bs = stdin
- if multi == 0:
- for _ in range(i - 1):
- sha.initialise(r, c, o)
- bs = sha.digest(bs, withReturn = j == 1)
- if j > 2:
- sha.fastSqueeze(j - 2)
- if j > 1:
- bs = sha.squeeze();
- if binary:
- write(bs)
- else:
- for b in bs:
- rc += "0123456789ABCDEF"[b >> 4]
- rc += "0123456789ABCDEF"[b & 15]
- rc += ' ' + ('-' if filename is None else filename) + '\n'
- write(rc.encode('utf-8'))
- elif multi == 1:
- if binary:
- write(bs)
- else:
- for b in bs:
- rc += "0123456789ABCDEF"[b >> 4]
- rc += "0123456789ABCDEF"[b & 15]
- rc += '\n'
- write(rc.encode('UTF-8'))
- for _ in range(i - 1):
- sha.initialise(r, c, o)
- bs = sha.digest(bs, j == 1)
- if j > 2:
- sha.fastSqueeze(j - 2)
- if j > 1:
- bs = sha.squeeze();
- if binary:
- write(bs);
- else:
- rc = ''
- for b in bs:
- rc += "0123456789ABCDEF"[b >> 4]
- rc += "0123456789ABCDEF"[b & 15]
- rc += '\n'
- write(rc.encode('UTF-8'))
- else:
- got = set()
- loop = None
- for _ in range(i):
- if _ > 0:
- pass
- rc = ''
- for b in bs:
- rc += "0123456789ABCDEF"[b >> 4]
- rc += "0123456789ABCDEF"[b & 15]
- if loop is None:
- if rc in got:
- loop = rc
- else:
- got.add(rc)
- if loop == rc:
- rc = '\033[31m%s\033[00m' % rc;
- write(rc.encode('utf-8'))
- flush()
- if loop is not None:
- printerr('\033[01;31mLoop found\033[00m')
- flush()
- except Exception as err:
- printerr(cmd + ': cannot read file: ' + fn + ': ' + str(err))
- fail = True
- flush()
- if fail:
- sys.exit(5)
-
diff --git a/python3/sha3.py b/python3/sha3.py
deleted file mode 100644
index 639be46..0000000
--- a/python3/sha3.py
+++ /dev/null
@@ -1,661 +0,0 @@
-#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
-'''
-sha3sum – SHA-3 (Keccak) checksum calculator
-
-Copyright © 2013, 2014 Mattias Andrée (maandree@member.fsf.org)
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU Affero General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Affero General Public License for more details.
-
-You should have received a copy of the GNU Affero General Public License
-along with this program. If not, see <http://www.gnu.org/licenses/>.
-'''
-
-class SHA3:
- '''
- SHA-3/Keccak hash algorithm implementation
-
- @author Mattias Andrée (maandree@member.fsf.org)
- '''
-
-
- KECCAK_SUFFIX = ''
- '''
- :str Suffix the message when calculating the Keccak hash sum
- '''
-
- SHA3_SUFFIX = '01'
- '''
- :str Suffix the message when calculating the SHA-3 hash sum
- '''
-
- RawSHAKE_SUFFIX = '11'
- '''
- :str Suffix the message when calculating the RawSHAKE hash sum
- '''
-
- SHAKE_SUFFIX = '1111'
- '''
- :str Suffix the message when calculating the SHAKE hash sum
- '''
-
-
- def __init__(self):
- '''
- Constructor
- '''
-
- self.RC = [0x0000000000000001, 0x0000000000008082, 0x800000000000808A, 0x8000000080008000,
- 0x000000000000808B, 0x0000000080000001, 0x8000000080008081, 0x8000000000008009,
- 0x000000000000008A, 0x0000000000000088, 0x0000000080008009, 0x000000008000000A,
- 0x000000008000808B, 0x800000000000008B, 0x8000000000008089, 0x8000000000008003,
- 0x8000000000008002, 0x8000000000000080, 0x000000000000800A, 0x800000008000000A,
- 0x8000000080008081, 0x8000000000008080, 0x0000000080000001, 0x8000000080008008]
- '''
- :list<int> Round contants
- '''
-
- self.B = [0] * 25
- '''
- :list<int> Keccak-f round temporary
- '''
-
- self.C = [0] * 5
- '''
- :list<int> Keccak-f round temporary
- '''
-
-
- (self.r, self.c, self.n, self.b, self.w, self.wmod, self.l, self.nr) = (0, 0, 0, 0, 0, 0, 0, 0)
- '''
- r:int The bitrate
- c:int The capacity
- n:int The output size
- b:int The state size
- w:int The word size
- wmod:int The word mask
- l:int ℓ, the binary logarithm of the word size
- nr:int 12 + 2ℓ, the number of rounds
- '''
-
- self.S = None
- '''
- :list<int> The current state
- '''
-
- self.M = None
- '''
- :bytes Left over water to fill the sponge with at next update
- '''
-
-
-
- def rotate(self, x, n):
- '''
- Rotate a word
-
- @param x:int The value to rotate
- @param n:int Rotation steps
- @return :int The value rotated
- '''
- m = n % self.w
- return ((x >> (self.w - m)) + (x << m)) & self.wmod
-
-
- def rotate64(self, x, n):
- '''
- Rotate a 64-bit word
-
- @param x:int The value to rotate
- @param n:int Rotation steps
- @return :int The value rotated
- '''
- return ((x >> (64 - n)) + (x << n)) & 0xFFFFFFFFFFFFFFFF
-
-
- def lb(self, x):
- '''
- Binary logarithm
-
- @param x:int The value of which to calculate the binary logarithm
- @return :int The binary logarithm
- '''
- rc = 0
- if (x & 0xFF00) != 0: rc += 8 ; x >>= 8
- if (x & 0x00F0) != 0: rc += 4 ; x >>= 4
- if (x & 0x000C) != 0: rc += 2 ; x >>= 2
- if (x & 0x0002) != 0: rc += 1
- return rc
-
-
- def keccakFRound(self, A, rc):
- '''
- Perform one round of computation
-
- @param A:list<int> The current state
- @param rc:int Round constant
- '''
- if self.w == 64:
- # θ step (step 1 and 2 of 3)
- self.C[0] = (A[0] ^ A[1]) ^ (A[2] ^ A[3]) ^ A[4]
- self.C[2] = (A[10] ^ A[11]) ^ (A[12] ^ A[13]) ^ A[14]
- db = self.C[0] ^ self.rotate64(self.C[2], 1)
- self.C[4] = (A[20] ^ A[21]) ^ (A[22] ^ A[23]) ^ A[24]
- dd = self.C[2] ^ self.rotate64(self.C[4], 1)
- self.C[1] = (A[5] ^ A[6]) ^ (A[7] ^ A[8]) ^ A[9]
- da = self.C[4] ^ self.rotate64(self.C[1], 1)
- self.C[3] = (A[15] ^ A[16]) ^ (A[17] ^ A[18]) ^ A[19]
- dc = self.C[1] ^ self.rotate64(self.C[3], 1)
- de = self.C[3] ^ self.rotate64(self.C[0], 1)
-
- # ρ and π steps, with last part of θ
- self.B[0] = self.rotate64(A[0] ^ da, 0)
- self.B[1] = self.rotate64(A[15] ^ dd, 28)
- self.B[2] = self.rotate64(A[5] ^ db, 1)
- self.B[3] = self.rotate64(A[20] ^ de, 27)
- self.B[4] = self.rotate64(A[10] ^ dc, 62)
-
- self.B[5] = self.rotate64(A[6] ^ db, 44)
- self.B[6] = self.rotate64(A[21] ^ de, 20)
- self.B[7] = self.rotate64(A[11] ^ dc, 6)
- self.B[8] = self.rotate64(A[1] ^ da, 36)
- self.B[9] = self.rotate64(A[16] ^ dd, 55)
-
- self.B[10] = self.rotate64(A[12] ^ dc, 43)
- self.B[11] = self.rotate64(A[2] ^ da, 3)
- self.B[12] = self.rotate64(A[17] ^ dd, 25)
- self.B[13] = self.rotate64(A[7] ^ db, 10)
- self.B[14] = self.rotate64(A[22] ^ de, 39)
-
- self.B[15] = self.rotate64(A[18] ^ dd, 21)
- self.B[16] = self.rotate64(A[8] ^ db, 45)
- self.B[17] = self.rotate64(A[23] ^ de, 8)
- self.B[18] = self.rotate64(A[13] ^ dc, 15)
- self.B[19] = self.rotate64(A[3] ^ da, 41)
-
- self.B[20] = self.rotate64(A[24] ^ de, 14)
- self.B[21] = self.rotate64(A[14] ^ dc, 61)
- self.B[22] = self.rotate64(A[4] ^ da, 18)
- self.B[23] = self.rotate64(A[19] ^ dd, 56)
- self.B[24] = self.rotate64(A[9] ^ db, 2)
- else:
- # θ step (step 1 and 2 of 3)
- self.C[0] = (A[0] ^ A[1]) ^ (A[2] ^ A[3]) ^ A[4]
- self.C[2] = (A[10] ^ A[11]) ^ (A[12] ^ A[13]) ^ A[14]
- db = self.C[0] ^ self.rotate(self.C[2], 1)
- self.C[4] = (A[20] ^ A[21]) ^ (A[22] ^ A[23]) ^ A[24]
- dd = self.C[2] ^ self.rotate(self.C[4], 1)
- self.C[1] = (A[5] ^ A[6]) ^ (A[7] ^ A[8]) ^ A[9]
- da = self.C[4] ^ self.rotate(self.C[1], 1)
- self.C[3] = (A[15] ^ A[16]) ^ (A[17] ^ A[18]) ^ A[19]
- dc = self.C[1] ^ self.rotate(self.C[3], 1)
- de = self.C[3] ^ self.rotate(self.C[0], 1)
-
- # ρ and π steps, with last part of θ
- self.B[0] = self.rotate(A[0] ^ da, 0)
- self.B[1] = self.rotate(A[15] ^ dd, 28)
- self.B[2] = self.rotate(A[5] ^ db, 1)
- self.B[3] = self.rotate(A[20] ^ de, 27)
- self.B[4] = self.rotate(A[10] ^ dc, 62)
-
- self.B[5] = self.rotate(A[6] ^ db, 44)
- self.B[6] = self.rotate(A[21] ^ de, 20)
- self.B[7] = self.rotate(A[11] ^ dc, 6)
- self.B[8] = self.rotate(A[1] ^ da, 36)
- self.B[9] = self.rotate(A[16] ^ dd, 55)
-
- self.B[10] = self.rotate(A[12] ^ dc, 43)
- self.B[11] = self.rotate(A[2] ^ da, 3)
- self.B[12] = self.rotate(A[17] ^ dd, 25)
- self.B[13] = self.rotate(A[7] ^ db, 10)
- self.B[14] = self.rotate(A[22] ^ de, 39)
-
- self.B[15] = self.rotate(A[18] ^ dd, 21)
- self.B[16] = self.rotate(A[8] ^ db, 45)
- self.B[17] = self.rotate(A[23] ^ de, 8)
- self.B[18] = self.rotate(A[13] ^ dc, 15)
- self.B[19] = self.rotate(A[3] ^ da, 41)
-
- self.B[20] = self.rotate(A[24] ^ de, 14)
- self.B[21] = self.rotate(A[14] ^ dc, 61)
- self.B[22] = self.rotate(A[4] ^ da, 18)
- self.B[23] = self.rotate(A[19] ^ dd, 56)
- self.B[24] = self.rotate(A[9] ^ db, 2)
-
- # ξ step
- A[0] = self.B[0] ^ ((~(self.B[5])) & self.B[10])
- A[1] = self.B[1] ^ ((~(self.B[6])) & self.B[11])
- A[2] = self.B[2] ^ ((~(self.B[7])) & self.B[12])
- A[3] = self.B[3] ^ ((~(self.B[8])) & self.B[13])
- A[4] = self.B[4] ^ ((~(self.B[9])) & self.B[14])
-
- A[5] = self.B[5] ^ ((~(self.B[10])) & self.B[15])
- A[6] = self.B[6] ^ ((~(self.B[11])) & self.B[16])
- A[7] = self.B[7] ^ ((~(self.B[12])) & self.B[17])
- A[8] = self.B[8] ^ ((~(self.B[13])) & self.B[18])
- A[9] = self.B[9] ^ ((~(self.B[14])) & self.B[19])
-
- A[10] = self.B[10] ^ ((~(self.B[15])) & self.B[20])
- A[11] = self.B[11] ^ ((~(self.B[16])) & self.B[21])
- A[12] = self.B[12] ^ ((~(self.B[17])) & self.B[22])
- A[13] = self.B[13] ^ ((~(self.B[18])) & self.B[23])
- A[14] = self.B[14] ^ ((~(self.B[19])) & self.B[24])
-
- A[15] = self.B[15] ^ ((~(self.B[20])) & self.B[0])
- A[16] = self.B[16] ^ ((~(self.B[21])) & self.B[1])
- A[17] = self.B[17] ^ ((~(self.B[22])) & self.B[2])
- A[18] = self.B[18] ^ ((~(self.B[23])) & self.B[3])
- A[19] = self.B[19] ^ ((~(self.B[24])) & self.B[4])
-
- A[20] = self.B[20] ^ ((~(self.B[0])) & self.B[5])
- A[21] = self.B[21] ^ ((~(self.B[1])) & self.B[6])
- A[22] = self.B[22] ^ ((~(self.B[2])) & self.B[7])
- A[23] = self.B[23] ^ ((~(self.B[3])) & self.B[8])
- A[24] = self.B[24] ^ ((~(self.B[4])) & self.B[9])
-
- # ι step
- A[0] ^= rc
-
-
- def keccakF(self, A):
- '''
- Perform Keccak-f function
-
- @param A:list<int> The current state
- '''
- if (self.nr == 24):
- self.keccakFRound(A, 0x0000000000000001)
- self.keccakFRound(A, 0x0000000000008082)
- self.keccakFRound(A, 0x800000000000808A)
- self.keccakFRound(A, 0x8000000080008000)
- self.keccakFRound(A, 0x000000000000808B)
- self.keccakFRound(A, 0x0000000080000001)
- self.keccakFRound(A, 0x8000000080008081)
- self.keccakFRound(A, 0x8000000000008009)
- self.keccakFRound(A, 0x000000000000008A)
- self.keccakFRound(A, 0x0000000000000088)
- self.keccakFRound(A, 0x0000000080008009)
- self.keccakFRound(A, 0x000000008000000A)
- self.keccakFRound(A, 0x000000008000808B)
- self.keccakFRound(A, 0x800000000000008B)
- self.keccakFRound(A, 0x8000000000008089)
- self.keccakFRound(A, 0x8000000000008003)
- self.keccakFRound(A, 0x8000000000008002)
- self.keccakFRound(A, 0x8000000000000080)
- self.keccakFRound(A, 0x000000000000800A)
- self.keccakFRound(A, 0x800000008000000A)
- self.keccakFRound(A, 0x8000000080008081)
- self.keccakFRound(A, 0x8000000000008080)
- self.keccakFRound(A, 0x0000000080000001)
- self.keccakFRound(A, 0x8000000080008008)
- else:
- for i in range(self.nr):
- self.keccakFRound(A, self.RC[i] & self.wmod)
-
-
- def toLane(self, message, n, ww, off):
- '''
- Convert a chunk of byte:s to a word
-
- @param message:bytes The message
- @param n:int `min(len(message), rr)`
- rr:int Bitrate in bytes
- @param ww:int Word size in bytes
- @param off:int The offset in the message
- @return :int Lane
- '''
- rc = 0
- i = off + ww - 1
- while i >= off:
- rc = (rc << 8) | (message[i] if (i < n) else 0)
- i -= 1
- return rc
-
-
- def toLane64(self, message, n, off):
- '''
- Convert a chunk of byte:s to a 64-bit word
-
- @param message:bytes The message
- @param n:int `min(len(message), rr)`
- rr:int Bitrate in bytes
- @param off:int The offset in the message
- @return :int Lane
- '''
- return ((message[off + 7] << 56) if (off + 7 < n) else 0) | ((message[off + 6] << 48) if (off + 6 < n) else 0) | ((message[off + 5] << 40) if (off + 5 < n) else 0) | ((message[off + 4] << 32) if (off + 4 < n) else 0) | ((message[off + 3] << 24) if (off + 3 < n) else 0) | ((message[off + 2] << 16) if (off + 2 < n) else 0) | ((message[off + 1] << 8) if (off + 1 < n) else 0) | ((message[off]) if (off < n) else 0)
-
-
- def pad10star1(self, msg, r, bits):
- '''
- pad 10*1
-
- @param msg:bytes The message to pad
- @param r:int The bitrate
- @param bits:int The number of bits in the end of the message that does not make a whole byte
- @return :bytes The message padded
- '''
- nnn = ((len(msg) - (bits + 7) // 8) << 3) + bits
-
- nrf = nnn >> 3
- nbrf = nnn & 7
- ll = nnn % r
-
- bbbb = 1 if nbrf == 0 else (msg[nrf] | (1 << nbrf))
-
- message = None
- if ((r - 8 <= ll) and (ll <= r - 2)):
- message = [bbbb ^ 128]
- else:
- nnn = (nrf + 1) << 3
- nnn = ((nnn - (nnn % r) + (r - 8)) >> 3) + 1
- message = [0] * (nnn - nrf)
- message[0] = bbbb
- nnn -= nrf
- message[nnn - 1] = 0x80
-
- return msg[:nrf] + bytes(message)
-
-
- def initialise(self, r, c, n):
- '''
- Initialise Keccak sponge
-
- @param r:int The bitrate
- @param c:int The capacity
- @param n:int The output size
- '''
- self.r = r
- self.c = c
- self.n = n
- self.b = r + c
- self.w = self.b // 25
- self.l = self.lb(self.w)
- self.nr = 12 + (self.l << 1)
- self.wmod = (1 << self.w) - 1
- self.S = [0] * 25
- self.M = bytes([])
-
-
- def update(self, msg, msglen = None):
- '''
- Absorb the more of the message message to the Keccak sponge
-
- @param msg:bytes The partial message
- @param msglen:int The length of the partial message in whole bytes
- '''
- if msglen is not None:
- msg = msg[:msglen]
-
- rr = self.r >> 3
- ww = self.w >> 3
-
- self.M += msg
- nnn = len(self.M)
- nnn -= nnn % ((self.r * self.b) >> 3)
- message = self.M[:nnn]
- self.M = self.M[nnn:]
-
- # Absorbing phase
- if ww == 8:
- for i in range(0, nnn, rr):
- n = min(len(message), rr)
- self.S[ 0] ^= self.toLane64(message, n, 0)
- self.S[ 5] ^= self.toLane64(message, n, 8)
- self.S[10] ^= self.toLane64(message, n, 16)
- self.S[15] ^= self.toLane64(message, n, 24)
- self.S[20] ^= self.toLane64(message, n, 32)
- self.S[ 1] ^= self.toLane64(message, n, 40)
- self.S[ 6] ^= self.toLane64(message, n, 48)
- self.S[11] ^= self.toLane64(message, n, 56)
- self.S[16] ^= self.toLane64(message, n, 64)
- self.S[21] ^= self.toLane64(message, n, 72)
- self.S[ 2] ^= self.toLane64(message, n, 80)
- self.S[ 7] ^= self.toLane64(message, n, 88)
- self.S[12] ^= self.toLane64(message, n, 96)
- self.S[17] ^= self.toLane64(message, n, 104)
- self.S[22] ^= self.toLane64(message, n, 112)
- self.S[ 3] ^= self.toLane64(message, n, 120)
- self.S[ 8] ^= self.toLane64(message, n, 128)
- self.S[13] ^= self.toLane64(message, n, 136)
- self.S[18] ^= self.toLane64(message, n, 144)
- self.S[23] ^= self.toLane64(message, n, 152)
- self.S[ 4] ^= self.toLane64(message, n, 160)
- self.S[ 9] ^= self.toLane64(message, n, 168)
- self.S[14] ^= self.toLane64(message, n, 176)
- self.S[19] ^= self.toLane64(message, n, 184)
- self.S[24] ^= self.toLane64(message, n, 192)
- self.keccakF(self.S)
- message = message[rr:]
- else:
- for i in range(0, nnn, rr):
- n = min(len(message), rr)
- self.S[ 0] ^= self.toLane(message, n, ww, 0)
- self.S[ 5] ^= self.toLane(message, n, ww, ww)
- self.S[10] ^= self.toLane(message, n, ww, 2 * ww)
- self.S[15] ^= self.toLane(message, n, ww, 3 * ww)
- self.S[20] ^= self.toLane(message, n, ww, 4 * ww)
- self.S[ 1] ^= self.toLane(message, n, ww, 5 * ww)
- self.S[ 6] ^= self.toLane(message, n, ww, 6 * ww)
- self.S[11] ^= self.toLane(message, n, ww, 7 * ww)
- self.S[16] ^= self.toLane(message, n, ww, 8 * ww)
- self.S[21] ^= self.toLane(message, n, ww, 9 * ww)
- self.S[ 2] ^= self.toLane(message, n, ww, 10 * ww)
- self.S[ 7] ^= self.toLane(message, n, ww, 11 * ww)
- self.S[12] ^= self.toLane(message, n, ww, 12 * ww)
- self.S[17] ^= self.toLane(message, n, ww, 13 * ww)
- self.S[22] ^= self.toLane(message, n, ww, 14 * ww)
- self.S[ 3] ^= self.toLane(message, n, ww, 15 * ww)
- self.S[ 8] ^= self.toLane(message, n, ww, 16 * ww)
- self.S[13] ^= self.toLane(message, n, ww, 17 * ww)
- self.S[18] ^= self.toLane(message, n, ww, 18 * ww)
- self.S[23] ^= self.toLane(message, n, ww, 19 * ww)
- self.S[ 4] ^= self.toLane(message, n, ww, 20 * ww)
- self.S[ 9] ^= self.toLane(message, n, ww, 21 * ww)
- self.S[14] ^= self.toLane(message, n, ww, 22 * ww)
- self.S[19] ^= self.toLane(message, n, ww, 23 * ww)
- self.S[24] ^= self.toLane(message, n, ww, 24 * ww)
- self.keccakF(self.S)
- message = message[rr:]
-
-
- def digest(self, msg = None, msglen = None, bits = 0, suffix = SHA3_SUFFIX, withReturn = False):
- '''
- Absorb the last part of the message and squeeze the Keccak sponge
-
- @param msg:bytes? The rest of the message
- @param msglen:int The length of the partial message in whole bytes
- @param bits:int The number of bits at the end of the message not covered by `msglen`
- @param suffix:str The suffix concatenate to the message
- @param withReturn:bool Whether to return the hash instead of just do a quick squeeze phrase and return `None`
- @return :bytes? The hash sum, or `None` if `withReturn` is `False`
- '''
- if msg is None:
- msg, last_byte = bytes([]), 0
- bits = 0
- else:
- msg, last_byte = msg[:msglen + bits // 8], (0 if bits % 8 == 0 else msg[msglen])
- bits %= 8
- last_byte &= (1 << bits) - 1
- msg_end = []
- for bit in suffix:
- last_byte |= int(bit) << bits
- bits += 1
- if bits == 8:
- msg_end.append(last_byte)
- last_byte = 0
- bits = 0
- if not bits == 0:
- msg_end.append(last_byte)
- msg += bytes(msg_end)
- message = self.pad10star1(self.M + msg, self.r, bits)
- self.M = None
- nnn = len(message)
-
- rr = self.r >> 3
- nn = (self.n + 7) >> 3
- ww = self.w >> 3
-
- # Absorbing phase
- if ww == 8:
- for i in range(0, nnn, rr):
- n = min(len(message), rr)
- self.S[ 0] ^= self.toLane64(message, n, 0)
- self.S[ 5] ^= self.toLane64(message, n, 8)
- self.S[10] ^= self.toLane64(message, n, 16)
- self.S[15] ^= self.toLane64(message, n, 24)
- self.S[20] ^= self.toLane64(message, n, 32)
- self.S[ 1] ^= self.toLane64(message, n, 40)
- self.S[ 6] ^= self.toLane64(message, n, 48)
- self.S[11] ^= self.toLane64(message, n, 56)
- self.S[16] ^= self.toLane64(message, n, 64)
- self.S[21] ^= self.toLane64(message, n, 72)
- self.S[ 2] ^= self.toLane64(message, n, 80)
- self.S[ 7] ^= self.toLane64(message, n, 88)
- self.S[12] ^= self.toLane64(message, n, 96)
- self.S[17] ^= self.toLane64(message, n, 104)
- self.S[22] ^= self.toLane64(message, n, 112)
- self.S[ 3] ^= self.toLane64(message, n, 120)
- self.S[ 8] ^= self.toLane64(message, n, 128)
- self.S[13] ^= self.toLane64(message, n, 136)
- self.S[18] ^= self.toLane64(message, n, 144)
- self.S[23] ^= self.toLane64(message, n, 152)
- self.S[ 4] ^= self.toLane64(message, n, 160)
- self.S[ 9] ^= self.toLane64(message, n, 168)
- self.S[14] ^= self.toLane64(message, n, 176)
- self.S[19] ^= self.toLane64(message, n, 184)
- self.S[24] ^= self.toLane64(message, n, 192)
- self.keccakF(self.S)
- message = message[rr:]
- else:
- for i in range(0, nnn, rr):
- n = min(len(message), rr)
- self.S[ 0] ^= self.toLane(message, n, ww, 0)
- self.S[ 5] ^= self.toLane(message, n, ww, ww)
- self.S[10] ^= self.toLane(message, n, ww, 2 * ww)
- self.S[15] ^= self.toLane(message, n, ww, 3 * ww)
- self.S[20] ^= self.toLane(message, n, ww, 4 * ww)
- self.S[ 1] ^= self.toLane(message, n, ww, 5 * ww)
- self.S[ 6] ^= self.toLane(message, n, ww, 6 * ww)
- self.S[11] ^= self.toLane(message, n, ww, 7 * ww)
- self.S[16] ^= self.toLane(message, n, ww, 8 * ww)
- self.S[21] ^= self.toLane(message, n, ww, 9 * ww)
- self.S[ 2] ^= self.toLane(message, n, ww, 10 * ww)
- self.S[ 7] ^= self.toLane(message, n, ww, 11 * ww)
- self.S[12] ^= self.toLane(message, n, ww, 12 * ww)
- self.S[17] ^= self.toLane(message, n, ww, 13 * ww)
- self.S[22] ^= self.toLane(message, n, ww, 14 * ww)
- self.S[ 3] ^= self.toLane(message, n, ww, 15 * ww)
- self.S[ 8] ^= self.toLane(message, n, ww, 16 * ww)
- self.S[13] ^= self.toLane(message, n, ww, 17 * ww)
- self.S[18] ^= self.toLane(message, n, ww, 18 * ww)
- self.S[23] ^= self.toLane(message, n, ww, 19 * ww)
- self.S[ 4] ^= self.toLane(message, n, ww, 20 * ww)
- self.S[ 9] ^= self.toLane(message, n, ww, 21 * ww)
- self.S[14] ^= self.toLane(message, n, ww, 22 * ww)
- self.S[19] ^= self.toLane(message, n, ww, 23 * ww)
- self.S[24] ^= self.toLane(message, n, ww, 24 * ww)
- self.keccakF(self.S)
- message = message[rr:]
-
- # Squeezing phase
- if withReturn:
- rc = [0] * ((self.n + 7) >> 3)
- ptr = 0
-
- olen = self.n
- j = 0
- ni = rr // ww
- while olen > 0:
- i = 0
- while (i < ni) and (j < nn):
- v = self.S[(i % 5) * 5 + i // 5]
- for _ in range(ww):
- if j < nn:
- rc[ptr] = v & 255
- ptr += 1
- v >>= 8
- j += 1
- i += 1
- olen -= self.r
- if olen > 0:
- self.keccakF(self.S)
- if (self.n & 7) != 0:
- rc[len(rc) - 1] &= (1 << (self.n & 7)) - 1
-
- return bytes(rc)
-
- olen = self.n
- while olen > self.r:
- olen -= self.r
- self.keccakF(self.S)
- return None
-
-
- def simpleSqueeze(self, times = 1):
- '''
- Force some rounds of Keccak-f
-
- @param times:int The number of rounds
- '''
- for i in range(times):
- self.keccakF(self.S)
-
-
- def fastSqueeze(self, times = 1):
- '''
- Squeeze as much as is needed to get a digest a number of times
-
- @param times:int The number of digests
- '''
- for i in range(times):
- self.keccakF(self.S) # Last squeeze did not do a ending squeeze
- olen = self.n
- while olen > self.r:
- olen -= self.r
- self.keccakF(self.S)
-
-
- def squeeze(self):
- '''
- Squeeze out another digest
-
- @return :bytes The hash sum
- '''
- self.keccakF(self.S) # Last squeeze did not do a ending squeeze
-
- nn = (self.n + 7) >> 3
- ww = self.w >> 3
- rc = [0] * nn
- olen = self.n
- j = 0
- ptr = 0
- ni = (self.r >> 3) // ww
-
- while olen > 0:
- i = 0
- while (i < ni) and (j < nn):
- v = self.S[(i % 5) * 5 + i // 5]
- for _ in range(ww):
- if j < nn:
- rc[ptr] = v
- ptr += 1
- v >>= 8
- j += 1
- i += 1
- olen -= self.r
- if olen > 0:
- self.keccakF(self.S)
-
- if (self.n & 7) != 0:
- rc[len(rc) - 1] &= (1 << (self.n & 7)) - 1
-
- return bytes(rc)
-
diff --git a/python3/sha3sum.py b/python3/sha3sum.py
deleted file mode 100755
index 93d3e72..0000000
--- a/python3/sha3sum.py
+++ /dev/null
@@ -1,386 +0,0 @@
-#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
-'''
-sha3sum – SHA-3 (Keccak) checksum calculator
-
-Copyright © 2013, 2014 Mattias Andrée (maandree@member.fsf.org)
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU Affero General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Affero General Public License for more details.
-
-You should have received a copy of the GNU Affero General Public License
-along with this program. If not, see <http://www.gnu.org/licenses/>.
-'''
-
-import sys
-import os
-
-from sha3 import SHA3
-
-
-def printerr(text, end = '\n'):
- sys.stderr.buffer.write((text + end).encode('utf-8'))
- sys.stderr.buffer.flush()
-
-
-if __name__ == '__main__':
- cmd = sys.argv[0]
- args = sys.argv[1:]
- if '/' in cmd:
- cmd = cmd[cmd.rfind('/') + 1:]
- if cmd.endswith('.py'):
- cmd = cmd[:-3]
-
- (O, S, R, C, W, I, J) = (None, None, None, None, None, None, None)
- (o, s, r, c, w, i, j) = (0, 0, 0, 0, 0, 0, 0)
- _o = 512 # --outputsize
- if cmd == 'sha3-224sum': _o = 224
- elif cmd == 'sha3-256sum': _o = 256
- elif cmd == 'sha3-384sum': _o = 384
- elif cmd == 'sha3-512sum': _o = 512
- _s = 1600 # --statesize
- _c = _s - (_o << 1) # --capacity
- _r = _s - _c # --bitrate
- _w = _s / 25 # --wordsize
- _i = 1 # --iterations
- _j = 1 # --squeezes
- (binary, hex, multi) = (False, False, 0)
-
- files = []
- dashed = False
- linger = None
-
- for arg in args + [None]:
- if linger is not None:
- if linger[0] in ('-h', '--help'):
- sys.stderr.buffer.write(('''
-SHA-3/Keccak checksum calculator
-
-USAGE: sha3sum [option...] < file
- sha3sum [option...] file...
-
-
-OPTIONS:
- -r BITRATE
- --bitrate The bitrate to use for checksum. (default: %d)
-
- -c CAPACITY
- --capacity The capacity to use for checksum. (default: %d)
-
- -w WORDSIZE
- --wordsize The word size to use for checksum. (default: %d)
-
- -o OUTPUTSIZE
- --outputsize The output size to use for checksum. (default: %d)
-
- -s STATESIZE
- --statesize The state size to use for checksum. (default: %d)
-
- -i ITERATIONS
- --iterations The number of hash iterations to run. (default: %d)
-
- -j SQUEEZES
- --squeezes The number of hash squeezes to run. (default: %d)
-
- -x
- --hex Read the input in hexadecimal, rather than binary.
-
- -b
- --binary Print the checksum in binary, rather than hexadecimal.
-
- -m
- --multi Print the checksum at all iterations.
-
-
-COPYRIGHT:
-
-Copyright © 2013, 2014 Mattias Andrée (maandree@member.fsf.org)
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU Affero General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Affero General Public License for more details.
-
-You should have received a copy of the GNU Affero General Public License
-along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-''' % (_r, _c, _w, _o, _s, _i, _j)).encode('utf-8'))
- sys.stderr.buffer.flush()
- exit(0)
- else:
- if linger[1] is None:
- linger[1] = arg
- arg = None
- if linger[0] in ('-r', '--bitrate'):
- R = int(linger[1])
- elif linger[0] in ('-c', '--capacity'):
- C = int(linger[1])
- elif linger[0] in ('-w', '--wordsize'):
- W = int(linger[1])
- elif linger[0] in ('-o', '--outputsize'):
- O = int(linger[1])
- elif linger[0] in ('-s', '--statesize'):
- S = int(linger[1])
- elif linger[0] in ('-i', '--iterations'):
- I = int(linger[1])
- elif linger[0] in ('-j', '--squeezes'):
- J = int(linger[1])
- else:
- printerr(sys.argv[0] + ': unrecognised option: ' + linger[0])
- sys.exit(1)
- linger = None
- if arg is None:
- continue
- if arg is None:
- continue
- if dashed:
- files.append(None if arg == '-' else arg)
- elif arg == '--':
- dashed = True
- elif arg == '-':
- files.append(None)
- elif arg.startswith('--'):
- if '=' in arg:
- linger = (arg[:arg.find('=')], arg[arg.find('=') + 1:])
- else:
- if arg == '--binary':
- binary = True
- elif arg == '--multi':
- multi += 1
- elif arg == '--hex':
- hex = True
- else:
- linger = [arg, None]
- elif arg.startswith('-'):
- arg = arg[1:]
- if arg[0] == 'b':
- binary = True
- arg = arg[1:]
- elif arg[0] == 'b':
- multi += 1
- arg = arg[1:]
- elif arg[0] == 'x':
- hex = True
- arg = arg[1:]
- elif len(arg) == 1:
- linger = ['-' + arg, None]
- else:
- linger = ['-' + arg[0], arg[1:]]
- else:
- files.append(arg)
-
-
- i = _i if I is None else I
- j = _j if J is None else J
-
-
- if S is not None:
- s = S
- if ((s <= 0) or (s > 1600) or (s % 25 != 0)):
- printerr(cmd + ': the state size must be a positive multiple of 25 and is limited to 1600.')
- sys.exit(6)
-
- if W is not None:
- w = W
- if (w <= 0) or (w > 64):
- printerr(cmd + ': the word size must be positive and is limited to 64.')
- sys.exit(6)
- if (S is not None) and (s != w * 25):
- printerr(cmd + ': the state size must be 25 times of the word size.')
- sys.exit(6)
- elif S is None:
- S = w * 25
-
- if C is not None:
- c = C
- if (c <= 0) or ((c & 7) != 0):
- printerr(cmd + ': the capacity must be a positive multiple of 8.')
- sys.exit(6)
-
- if R is not None:
- r = R
- if (r <= 0) or ((r & 7) != 0):
- printerr(cmd + ': the bitrate must be a positive multiple of 8.')
- sys.exit(6)
-
- if O is not None:
- o = O
- if o <= 0:
- printerr(cmd + ': the output size must be positive.')
- sys.exit(6)
-
-
- if (R is None) and (C is None) and (O is None): ## s?
- s = _s if S is None else s
- o = (((s << 5) // 100 + 7) >> 3) << 3
- r = o << 1
- c = s - r
- o = 8 if o < 8 else o
- elif (R is None) and (C is None): ## !o s?
- r = _r
- c = _c
- s = (r + c) if S is None else s
- elif R is None: ## !c o? s?
- s = _s if S is None else s
- r = s - c
- o = (8 if c == 8 else (c << 1)) if O is None else o
- elif C is None: ## !r o? s?
- s = _s if S is None else s
- c = s - r
- o = (8 if c == 8 else (c << 1)) if O is None else o
- else: ## !r !c o? s?
- s = (r + c) if S is None else s
- o = (8 if c == 8 else (c << 1)) if O is None else o
-
-
- printerr('Bitrate: %d' % r)
- printerr('Capacity: %d' % c)
- printerr('Word size: %d' % w)
- printerr('State size: %d' % s)
- printerr('Output size: %d' % o)
- printerr('Iterations: %d' % i)
- printerr('Squeezes: %d' % j)
-
-
- if r > s:
- printerr(cmd + ': the bitrate must not be higher than the state size.')
- sys.exit(6)
- if c > s:
- printerr(cmd + ': the capacity must not be higher than the state size.')
- sys.exit(6)
- if r + c != s:
- printerr(cmd + ': the sum of the bitrate and the capacity must equal the state size.')
- sys.exit(6)
-
-
- if len(files) == 0:
- files.append(None)
- if i < 1:
- printerr(cmd + ': sorry, I will only do at least one hash iteration!\n')
- sys.exit(3)
- if j < 1:
- printerr(cmd + ': sorry, I will only do at least one squeeze iteration!\n')
- sys.exit(3)
- stdin = None
- fail = False
- sha = SHA3()
- for filename in files:
- rc = ''
- fn = '/dev/stdin' if filename is None else filename
- with open(fn, 'rb') as file:
- try:
- if (filename is not None) or (stdin is None):
- sha.initialise(r, c, o)
- blksize = 4096
- try:
- blksize = os.stat(os.path.realpath(fn)).st_blksize
- if blksize <= 0:
- blksize = 4096
- except:
- pass
- while True:
- chunk = file.read(blksize)
- if len(chunk) == 0:
- break
- if not hex:
- sha.update(chunk)
- else:
- chunk = list(chunk)
- n = len(chunk) >> 1
- for _ in range(n):
- (a, b) = (chunk[_ << 1], chunk[(_ << 1 | 1)])
- a = ((a & 15) + (0 if a <= '9' else 9)) << 4
- b = (b & 15) + (0 if b <= '9' else 0)
- chunk[_] = a | b
- sha.update(bytes(chunk), n)
- bs = sha.digest(withReturn = j == 1)
- if j > 2:
- sha.fastSqueeze(j - 2)
- if j > 1:
- bs = sha.squeeze();
- if filename is None:
- stdin = bs
- else:
- bs = stdin
- if multi == 0:
- for _ in range(i - 1):
- sha.initialise(r, c, o)
- bs = sha.digest(bs, withReturn = j == 1)
- if j > 2:
- sha.fastSqueeze(j - 2)
- if j > 1:
- bs = sha.squeeze();
- if binary:
- sys.stdout.buffer.write(bs)
- else:
- for b in bs:
- rc += "0123456789ABCDEF"[b >> 4]
- rc += "0123456789ABCDEF"[b & 15]
- rc += ' ' + ('-' if filename is None else filename) + '\n'
- sys.stdout.buffer.write(rc.encode('utf-8'))
- elif multi == 1:
- if binary:
- sys.stdout.buffer.write(bs)
- else:
- for b in bs:
- rc += "0123456789ABCDEF"[b >> 4]
- rc += "0123456789ABCDEF"[b & 15]
- rc += '\n'
- sys.stdout.buffer.write(rc.encode('UTF-8'))
- for _ in range(i - 1):
- sha.initialise(r, c, o)
- bs = sha.digest(bs, j == 1)
- if j > 2:
- sha.fastSqueeze(j - 2)
- if j > 1:
- bs = sha.squeeze();
- if binary:
- sys.stdout.buffer.write(bs);
- else:
- rc = ''
- for b in bs:
- rc += "0123456789ABCDEF"[b >> 4]
- rc += "0123456789ABCDEF"[b & 15]
- rc += '\n'
- sys.stdout.buffer.write(rc.encode('UTF-8'))
- else:
- got = set()
- loop = None
- for _ in range(i):
- if _ > 0:
- pass
- rc = ''
- for b in bs:
- rc += "0123456789ABCDEF"[b >> 4]
- rc += "0123456789ABCDEF"[b & 15]
- if loop is None:
- if rc in got:
- loop = rc
- else:
- got.add(rc)
- if loop == rc:
- rc = '\033[31m%s\033[00m' % rc;
- sys.stdout.buffer.write(rc.encode('utf-8'))
- sys.stdout.buffer.flush()
- if loop is not None:
- printerr('\033[01;31mLoop found\033[00m')
- sys.stdout.buffer.flush()
- except Exception as err:
- printerr(cmd + ': cannot read file: ' + fn + ': ' + str(err))
- fail = True
- sys.stdout.buffer.flush()
- if fail:
- sys.exit(5)
-
diff --git a/java/sha3_224sum.java b/src/sha3sum.c
index d6717d5..ca06c1d 100644
--- a/java/sha3_224sum.java
+++ b/src/sha3sum.c
@@ -16,27 +16,3 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-
-import java.io.*;
-import java.util.*;
-
-
-/**
- * SHA-3/Keccak checksum calculator with 224 bit output
- *
- * @author Mattias Andrée <a href="mailto:maandree@member.fsf.org">maandree@member.fsf.org</a>
- */
-public class sha3_224sum
-{
- /**
- * This is the main entry point of the program
- *
- * @param args Command line arguments
- * @throws IOException On I/O error (such as broken pipes)
- */
- public static void main(String[] args) throws IOException
- {
- sha3sum.run("sha3-224sum", args);
- }
-}
-
diff --git a/test-cases b/test-cases
deleted file mode 100644
index 045feb9..0000000
--- a/test-cases
+++ /dev/null
@@ -1 +0,0 @@
-493411C4AE0C731998D8D46EF70938F71AF826E024545020628A995B074BA8FA1CFE704C5BB891C0303685A7A6C20E10FB48C8F14F7A5F1959CAF4C664DE4EF5 LICENSE