Skip to content

Instantly share code, notes, and snippets.

@schierlm
Last active March 18, 2021 22:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save schierlm/91f6cd3a855a82bdc5328ba6fe90bd2a to your computer and use it in GitHub Desktop.
Save schierlm/91f6cd3a855a82bdc5328ba6fe90bd2a to your computer and use it in GitHub Desktop.
sha3sum for M2-Planet

sha3sum for M2-Planet

#!/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
/*
* 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