-
-
Save schierlm/91f6cd3a855a82bdc5328ba6fe90bd2a to your computer and use it in GitHub Desktop.
sha3sum for M2-Planet
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh -e | |
ARCH="${ARCH:-x86}" | |
M2_PLANET="${M2_PLANET:-../M2-Planet}" | |
MESCC_TOOLS="${MESCC_TOOLS:-../mescc-tools/bin}" | |
gcc -Wall $M2_PLANET/M2libc/bootstrappable.c sha3sum.c -iquote $M2_PLANET -o sha3sum_gcc | |
$M2_PLANET/bin/M2-Planet --architecture ${ARCH} \ | |
-f $M2_PLANET/M2libc/${ARCH}/Linux/unistd.h \ | |
-f $M2_PLANET/M2libc/stdlib.c \ | |
-f $M2_PLANET/M2libc/${ARCH}/Linux/fcntl.h \ | |
-f $M2_PLANET/M2libc/stdio.c \ | |
-f $M2_PLANET/M2libc/bootstrappable.c \ | |
-f sha3sum.c --debug -o sha3sum.M1 | |
$MESCC_TOOLS/blood-elf -f sha3sum.M1 --entry _start -o sha3sum-footer.M1 | |
$MESCC_TOOLS/M1 \ | |
-f $M2_PLANET/M2libc/${ARCH}/${ARCH}_defs.M1 \ | |
-f $M2_PLANET/M2libc/${ARCH}/libc-full.M1 \ | |
-f sha3sum.M1 \ | |
-f sha3sum-footer.M1 \ | |
--little-endian \ | |
--architecture ${ARCH} \ | |
-o sha3sum.hex2 | |
$MESCC_TOOLS/hex2 \ | |
-f $M2_PLANET/M2libc/${ARCH}/ELF-${ARCH}-debug.hex2 \ | |
-f sha3sum.hex2 \ | |
--little-endian \ | |
--architecture ${ARCH} \ | |
--base-address 0x08048000 \ | |
-o sha3sum | |
rm *.hex2 *.M1 | |
/usr/bin/printf "">tmp | |
./sha3sum_gcc -a 224 --verify 6b4e03423667dbb73b6e15454f0eb1abd4597f9a1b078e3f5b5a6bc7 tmp | |
./sha3sum -a 224 --verify 6b4e03423667dbb73b6e15454f0eb1abd4597f9a1b078e3f5b5a6bc7 tmp | |
/usr/bin/printf "\x9F\x2F\xCC\x7C\x90\xDE\x09\x0D\x6B\x87\xCD\x7E\x97\x18\xC1\xEA\x6C\xB2\x11\x18\xFC\x2D\x5D\xE9\xF9\x7E\x5D\xB6\xAC\x1E\x9C\x10" > tmp | |
./sha3sum_gcc -a 256 --verify 2f1a5f7159e34ea19cddc70ebf9b81f1a66db40615d7ead3cc1f1b954d82a3af tmp | |
./sha3sum -a 256 --verify 2f1a5f7159e34ea19cddc70ebf9b81f1a66db40615d7ead3cc1f1b954d82a3af tmp | |
/usr/bin/printf "\xE3\x57\x80\xEB\x97\x99\xAD\x4C\x77\x53\x5D\x4D\xDB\x68\x3C\xF3\x3E\xF3\x67\x71\x53\x27\xCF\x4C\x4A\x58\xED\x9C\xBD\xCD\xD4\x86\xF6\x69\xF8\x01\x89\xD5\x49\xA9\x36\x4F\xA8\x2A\x51\xA5\x26\x54\xEC\x72\x1B\xB3\xAA\xB9\x5D\xCE\xB4\xA8\x6A\x6A\xFA\x93\x82\x6D\xB9\x23\x51\x7E\x92\x8F\x33\xE3\xFB\xA8\x50\xD4\x56\x60\xEF\x83\xB9\x87\x6A\xCC\xAF\xA2\xA9\x98\x7A\x25\x4B\x13\x7C\x6E\x14\x0A\x21\x69\x1E\x10\x69\x41\x38\x48" >tmp | |
./sha3sum_gcc -a 384 --verify d1c0fa85c8d183beff99ad9d752b263e286b477f79f0710b010317017397813344b99daf3bb7b1bc5e8d722bac85943a tmp | |
./sha3sum -a 384 --verify d1c0fa85c8d183beff99ad9d752b263e286b477f79f0710b010317017397813344b99daf3bb7b1bc5e8d722bac85943a tmp | |
/usr/bin/printf "\x3A\x3A\x81\x9C\x48\xEF\xDE\x2A\xD9\x14\xFB\xF0\x0E\x18\xAB\x6B\xC4\xF1\x45\x13\xAB\x27\xD0\xC1\x78\xA1\x88\xB6\x14\x31\xE7\xF5\x62\x3C\xB6\x6B\x23\x34\x67\x75\xD3\x86\xB5\x0E\x98\x2C\x49\x3A\xDB\xBF\xC5\x4B\x9A\x3C\xD3\x83\x38\x23\x36\xA1\xA0\xB2\x15\x0A\x15\x35\x8F\x33\x6D\x03\xAE\x18\xF6\x66\xC7\x57\x3D\x55\xC4\xFD\x18\x1C\x29\xE6\xCC\xFD\xE6\x3E\xA3\x5F\x0A\xDF\x58\x85\xCF\xC0\xA3\xD8\x4A\x2B\x2E\x4D\xD2\x44\x96\xDB\x78\x9E\x66\x31\x70\xCE\xF7\x47\x98\xAA\x1B\xBC\xD4\x57\x4E\xA0\xBB\xA4\x04\x89\xD7\x64\xB2\xF8\x3A\xAD\xC6\x6B\x14\x8B\x4A\x0C\xD9\x52\x46\xC1\x27\xD5\x87\x1C\x4F\x11\x41\x86\x90\xA5\xDD\xF0\x12\x46\xA0\xC8\x0A\x43\xC7\x00\x88\xB6\x18\x36\x39\xDC\xFD\xA4\x12\x5B\xD1\x13\xA8\xF4\x9E\xE2\x3E\xD3\x06\xFA\xAC\x57\x6C\x3F\xB0\xC1\xE2\x56\x67\x1D\x81\x7F\xC2\x53\x4A\x52\xF5\xB4\x39\xF7\x2E\x42\x4D\xE3\x76\xF4\xC5\x65\xCC\xA8\x23\x07\xDD\x9E\xF7\x6D\xA5\xB7\xC4\xEB\x7E\x08\x51\x72\xE3\x28\x80\x7C\x02\xD0\x11\xFF\xBF\x33\x78\x53\x78\xD7\x9D\xC2\x66\xF6\xA5\xBE\x6B\xB0\xE4\xA9\x2E\xCE\xEB\xAE\xB1" >tmp | |
./sha3sum_gcc -a 512 --verify 6e8b8bd195bdd560689af2348bdc74ab7cd05ed8b9a57711e9be71e9726fda4591fee12205edacaf82ffbbaf16dff9e702a708862080166c2ff6ba379bc7ffc2 tmp | |
./sha3sum -a 512 --verify 6e8b8bd195bdd560689af2348bdc74ab7cd05ed8b9a57711e9be71e9726fda4591fee12205edacaf82ffbbaf16dff9e702a708862080166c2ff6ba379bc7ffc2 tmp | |
echo Trying randomly... | |
dd if=/dev/urandom of=tmp bs=1 count=`bash -c 'echo $RANDOM'` | |
(./sha3sum -a 224 tmp ; ./sha3sum -a 256 tmp ; ./sha3sum -a 384 tmp ; ./sha3sum -a 512 tmp ) | tee tmp1 | |
(sha3sum -a 224 tmp ; sha3sum -a 256 tmp ; sha3sum -a 384 tmp ; sha3sum -a 512 tmp ) | tee tmp2 | |
diff -u tmp1 tmp2 | |
rm tmp tmp1 tmp2 | |
echo OK |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Based on https://github.com/mjosaarinen/tiny_sha3/ | |
* Copyright (c) 2015 Markku-Juhani O. Saarinen <mjos@iki.fi> | |
* Copyright (c) 2021 Michael Schierl <schierlm@gmx.de> | |
* MIT Licensed | |
*/ | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <stddef.h> | |
#include <stdint.h> | |
#include "M2libc/bootstrappable.h" | |
#define KECCAKF_ROUNDS 24 | |
#if defined(__M2__) | |
#define uint32_t unsigned | |
#define uint8_t char | |
#endif | |
struct keccakf_const { | |
uint32_t rndc1[24]; | |
uint32_t rndc2[24]; | |
int rotc[24]; | |
int piln[24]; | |
}; | |
/* init constants */ | |
void keccakf_init(struct keccakf_const *kc) | |
{ | |
kc->rndc1[0] = 0x00000001; kc->rndc2[0] = 0x00000000; kc->rotc[0] = 1; kc->piln[0] = 10; | |
kc->rndc1[1] = 0x00008082; kc->rndc2[1] = 0x00000000; kc->rotc[1] = 3; kc->piln[1] = 7; | |
kc->rndc1[2] = 0x0000808a; kc->rndc2[2] = 0x80000000; kc->rotc[2] = 6; kc->piln[2] = 11; | |
kc->rndc1[3] = 0x80008000; kc->rndc2[3] = 0x80000000; kc->rotc[3] = 10; kc->piln[3] = 17; | |
kc->rndc1[4] = 0x0000808b; kc->rndc2[4] = 0x00000000; kc->rotc[4] = 15; kc->piln[4] = 18; | |
kc->rndc1[5] = 0x80000001; kc->rndc2[5] = 0x00000000; kc->rotc[5] = 21; kc->piln[5] = 3; | |
kc->rndc1[6] = 0x80008081; kc->rndc2[6] = 0x80000000; kc->rotc[6] = 28; kc->piln[6] = 5; | |
kc->rndc1[7] = 0x00008009; kc->rndc2[7] = 0x80000000; kc->rotc[7] = 36; kc->piln[7] = 16; | |
kc->rndc1[8] = 0x0000008a; kc->rndc2[8] = 0x00000000; kc->rotc[8] = 45; kc->piln[8] = 8; | |
kc->rndc1[9] = 0x00000088; kc->rndc2[9] = 0x00000000; kc->rotc[9] = 55; kc->piln[9] = 21; | |
kc->rndc1[10] = 0x80008009; kc->rndc2[10] = 0x00000000; kc->rotc[10] = 2; kc->piln[10] = 24; | |
kc->rndc1[11] = 0x8000000a; kc->rndc2[11] = 0x00000000; kc->rotc[11] = 14; kc->piln[11] = 4; | |
kc->rndc1[12] = 0x8000808b; kc->rndc2[12] = 0x00000000; kc->rotc[12] = 27; kc->piln[12] = 15; | |
kc->rndc1[13] = 0x0000008b; kc->rndc2[13] = 0x80000000; kc->rotc[13] = 41; kc->piln[13] = 23; | |
kc->rndc1[14] = 0x00008089; kc->rndc2[14] = 0x80000000; kc->rotc[14] = 56; kc->piln[14] = 19; | |
kc->rndc1[15] = 0x00008003; kc->rndc2[15] = 0x80000000; kc->rotc[15] = 8; kc->piln[15] = 13; | |
kc->rndc1[16] = 0x00008002; kc->rndc2[16] = 0x80000000; kc->rotc[16] = 25; kc->piln[16] = 12; | |
kc->rndc1[17] = 0x00000080; kc->rndc2[17] = 0x80000000; kc->rotc[17] = 43; kc->piln[17] = 2; | |
kc->rndc1[18] = 0x0000800a; kc->rndc2[18] = 0x00000000; kc->rotc[18] = 62; kc->piln[18] = 20; | |
kc->rndc1[19] = 0x8000000a; kc->rndc2[19] = 0x80000000; kc->rotc[19] = 18; kc->piln[19] = 14; | |
kc->rndc1[20] = 0x80008081; kc->rndc2[20] = 0x80000000; kc->rotc[20] = 39; kc->piln[20] = 22; | |
kc->rndc1[21] = 0x00008080; kc->rndc2[21] = 0x80000000; kc->rotc[21] = 61; kc->piln[21] = 9; | |
kc->rndc1[22] = 0x80000001; kc->rndc2[22] = 0x00000000; kc->rotc[22] = 20; kc->piln[22] = 6; | |
kc->rndc1[23] = 0x80008008; kc->rndc2[23] = 0x80000000; kc->rotc[23] = 44; kc->piln[23] = 1; | |
} | |
/* rotate val1 | (val2 << 32) left by howfar bits and return the least significant uint32_t */ | |
uint32_t keccak_rotl64_0(uint32_t val1, uint32_t val2, int howfar) | |
{ | |
if (howfar < 32) { | |
return (val1 << howfar) | (val2 >> (32 - howfar)); | |
} else { | |
return (val2 << (howfar - 32)) | (val1 >> (64 - howfar)); | |
} | |
} | |
/* rotate val1 | (val2 << 32) left by howfar bits and return the most significant uint32_t */ | |
uint32_t keccak_rotl64_1(uint32_t val1, uint32_t val2, int howfar) | |
{ | |
if (howfar < 32) { | |
return (val1 >> (32 - howfar)) | (val2 << howfar); | |
} else { | |
return (val1 << (howfar - 32)) | (val2 >> (64 - howfar)); | |
} | |
} | |
uint32_t cast_uint32_t(uint8_t v) | |
{ | |
uint32_t r = v & 0xff; | |
return r; | |
} | |
uint8_t cast_uint8_t(uint32_t v) | |
{ | |
uint8_t r = v & 0xff; | |
return r; | |
} | |
uint8_t* cast_uint8_t_p(uint32_t* v) | |
{ | |
#if defined(__M2__) | |
uint8_t* r = v; | |
return r; | |
#else | |
return (uint8_t*) v; | |
#endif | |
} | |
/* Compression function */ | |
void sha3_keccakf(struct keccakf_const* kc, uint32_t* st, uint32_t* bc) | |
{ | |
/* variables */ | |
int i; | |
int j; | |
int r; | |
uint32_t hold; | |
uint32_t t0; | |
uint32_t t1; | |
uint8_t* v; | |
/* endianess conversion. this is redundant on little-endian targets */ | |
for (i = 0; i < 50; i = i + 1) { | |
hold = st[i]; | |
v = cast_uint8_t_p(&hold); | |
st[i] = cast_uint32_t(v[0]) | (cast_uint32_t(v[1]) << 8) | | |
(cast_uint32_t(v[2]) << 16) | (cast_uint32_t(v[3]) << 24); | |
} | |
/* actual iteration */ | |
for (r = 0; r < KECCAKF_ROUNDS; r = r + 1) { | |
/* Theta */ | |
for (i = 0; i < 10; i = i + 1) | |
bc[i] = st[i] ^ st[i + 10] ^ st[i + 20] ^ st[i + 30] ^ st[i + 40]; | |
for (i = 0; i < 5; i = i + 1) { | |
t0 = bc[(((i + 4) % 5) * 2)] ^ keccak_rotl64_0(bc[(((i + 1) % 5) * 2)], bc[((((i + 1) % 5) * 2) + 1)], 1); | |
t1 = bc[((((i + 4) % 5) * 2) + 1)] ^ keccak_rotl64_1(bc[(((i + 1) % 5) * 2)], bc[((((i + 1) % 5) * 2) + 1)], 1); | |
for (j = 0; j < 25; j = j + 5) { | |
st[((j + i) * 2)] = st[((j + i) * 2)] ^ t0; | |
st[(((j + i) * 2) + 1)] = st[(((j + i) * 2) + 1)] ^ t1; | |
} | |
} | |
/* Rho Pi */ | |
t0 = st[2]; | |
t1 = st[3]; | |
for (i = 0; i < 24; i = i + 1) { | |
j = kc->piln[i]; | |
bc[0] = st[j*2]; | |
bc[1] = st[j*2+1]; | |
st[j*2] = keccak_rotl64_0(t0, t1, kc->rotc[i]); | |
st[j*2+1] = keccak_rotl64_1(t0, t1, kc->rotc[i]); | |
t0 = bc[0]; | |
t1 = bc[1]; | |
} | |
/* Chi */ | |
for (j = 0; j < 25; j = j + 5) { | |
for (i = 0; i < 10; i = i + 1) | |
bc[i] = st[j * 2 + i]; | |
for (i = 0; i < 10; i = i + 1) | |
st[j*2 + i] = st[j*2 + i] ^ ((~bc[(i + 2) % 10]) & bc[(i + 4) % 10]); | |
} | |
/* Iota */ | |
st[0] = st[0] ^ kc->rndc1[r]; | |
st[1] = st[1] ^ kc->rndc2[r]; | |
} | |
/* endianess conversion. this is redundant on little-endian targets */ | |
for (i = 0; i < 50; i = i + 1) { | |
hold = st[i]; | |
v = cast_uint8_t_p(&hold); | |
t1 = st[i]; | |
v[0] = t1 & 0xFF; | |
v[1] = (t1 >> 8) & 0xFF; | |
v[2] = (t1 >> 16) & 0xFF; | |
v[3] = (t1 >> 24) & 0xFF; | |
st[i] = hold; | |
} | |
} | |
/* main function */ | |
int main(int argc, char **argv) | |
{ | |
int algorithm = 256; | |
char* verify_hash = NULL; | |
char* output_file = ""; | |
FILE* output = stdout; | |
int option_index = 1; | |
uint32_t* state = calloc(50, sizeof(uint32_t)); | |
uint8_t* st8 = cast_uint8_t_p(state); | |
struct keccakf_const* kc = calloc(1, sizeof(struct keccakf_const)); | |
uint32_t* bc = calloc(10, sizeof(uint32_t)); | |
char* filename; | |
FILE* ff; | |
char* mdhex = calloc(1, 512 / 4 + 1); | |
char* hextable = "0123456789abcdef"; | |
int c; | |
int rsiz; | |
int pt; | |
int i; | |
uint8_t v; | |
keccakf_init(kc); | |
while(option_index <= argc) { | |
if (NULL == argv[option_index]) { | |
option_index = option_index + 1; | |
} else if (match(argv[option_index], "-a") || match(argv[option_index], "--algorithm")) { | |
algorithm = strtoint(argv[option_index + 1]); | |
option_index = option_index + 2; | |
require(algorithm == 224 || algorithm == 256 || algorithm == 384 || algorithm == 512, "invalid bit length\n"); | |
} else if (match(argv[option_index], "-o") || match(argv[option_index], "--output")) { | |
output_file = argv[option_index + 1]; | |
option_index = option_index + 2; | |
if (output != stdout) { | |
fclose(output); | |
} | |
output = fopen(output_file, "w"); | |
require(output != NULL, "Output file cannot be opened!\n"); | |
} else if (match(argv[option_index], "--verify")) { | |
verify_hash = argv[option_index + 1]; | |
option_index = option_index + 2; | |
} else if (match(argv[option_index], "-h") || match(argv[option_index], "--help")) { | |
fputs("Usage: ", stderr); | |
fputs(argv[0], stderr); | |
fputs(" [--verify <hash>] [-a 224|256|384|512] [-o <outfile>] <file> ...\n", stderr); | |
return 0; | |
} else if (match(argv[option_index], "-V") || match(argv[option_index], "--version")) { | |
fputs("sha3sum 1.0\n", stdout); | |
return 0; | |
} else { | |
for (i = 0; i < 50; i = i + 1) { | |
state[i] = 0; | |
} | |
rsiz = 200 - (algorithm / 4); | |
filename = argv[option_index]; | |
option_index = option_index + 1; | |
ff = fopen(filename, "rb"); | |
require(ff != NULL, "Input file cannot be opened!\n"); | |
pt = 0; | |
while((c = fgetc(ff)) != EOF) { | |
st8[pt] = ((st8[pt] & 0xff) ^ c) & 0xff; | |
pt = pt + 1; | |
if (pt >= rsiz) { | |
sha3_keccakf(kc, state, bc); | |
pt = 0; | |
} | |
} | |
fclose(ff); | |
st8[pt] = ((st8[pt] & 0xff)^ 0x06) & 0xff; | |
st8[rsiz - 1] = ((st8[rsiz - 1]& 0xff) ^ 0x80) & 0xff; | |
sha3_keccakf(kc, state, bc); | |
for(i = 0; i < algorithm >> 3; i = i + 1) { | |
v = st8[i] & 0xff; | |
mdhex[i * 2] = hextable[v >> 4]; | |
mdhex[i * 2 + 1] = hextable[v & 0x0F]; | |
} | |
mdhex[algorithm>>2] = '\0'; | |
fputs(mdhex, output); | |
fputs(" ", output); | |
fputs(filename, output); | |
fputs("\n", output); | |
if (verify_hash != NULL) { | |
require(match(verify_hash, mdhex), "hashes do not match!\n"); | |
} | |
} | |
} | |
if (output != stdout) { | |
fclose(output); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment