void keccak(const uint8_t *_in, const size_t _len, uint8_t *const _hash, const size_t _hashlen){ uint64_t state[25]; uint8_t tmp[144]; register int i, rsize, rsizew; register size_t j = _len; rsize = 200 - 2 * _hashlen; rsizew = rsize / 8; //Clear the state memset(state, 0, sizeof(state)); //First few blocks (i.e. not last block) for(; j >= rsize; j -= rsize, _in += rsize){ for(i = 0; i < rsizew; i++) state[i] ^= ((uint64_t *)_in)[i]; keccakf(state, KECCAK_ROUNDS); } //Last block + padding memcpy(tmp, _in, j); tmp[j++] = 1; memset(tmp + j, 0, rsize - j); tmp[rsize - 1] |= 0x80; for(i = 0; i < rsizew; i++) state[i] ^= ((uint64_t *)tmp)[i]; keccakf(state, KECCAK_ROUNDS); memcpy(_hash, state, _hashlen); }
void keccak(const uint8_t *in, int inlen, uint8_t *md, int mdlen) { state_t st; uint8_t temp[144]; int i, rsiz, rsizw; rsiz = sizeof(state_t) == mdlen ? HASH_DATA_AREA : 200 - 2 * mdlen; rsizw = rsiz / 8; memset(st, 0, sizeof(st)); for ( ; inlen >= rsiz; inlen -= rsiz, in += rsiz) { for (i = 0; i < rsizw; i++) st[i] ^= ((uint64_t *) in)[i]; keccakf(st, KECCAK_ROUNDS); } // last block and padding memcpy(temp, in, inlen); temp[inlen++] = 1; memset(temp + inlen, 0, rsiz - inlen); temp[rsiz - 1] |= 0x80; for (i = 0; i < rsizw; i++) st[i] ^= ((uint64_t *) temp)[i]; keccakf(st, KECCAK_ROUNDS); memcpy(md, st, mdlen); }
void hash_permutation(union hash_state *state) { #if BYTE_ORDER == LITTLE_ENDIAN keccakf((uint64_t*)state, 24); #else uint64_t le_state[25]; memcpy_swap64le(le_state, state, 25); keccakf(le_state, 24); memcpy_swap64le(state, le_state, 25); #endif }
void printsum(const char *_fname, FILE *_f, size_t size){ uint64_t state[25]; uint8_t *hash = malloc(size * sizeof(uint8_t)); uint8_t buf[200]; uint8_t tmp[144]; register int i; register size_t rsize, rsizew, j; rsize = 200 - 2 * size; rsizew = rsize / 8; //Clear the state memset(state, 0, sizeof(state)); while(1) { //read up to rsize bytes, then do work j = fread(buf, 1, rsize, _f); //check some stuff if(feof(_f)){ break; } else if(ferror(_f)){ fprintf(stderr, "Error when reading %s.\n", _fname); goto fin; } else { //First few blocks (i.e. not last block) for(i = 0; i < rsizew; i++) state[i] ^= ((uint64_t *)buf)[i]; keccakf(state, KECCAK_ROUNDS); } } //Last block + padding memcpy(tmp, buf, j); tmp[j++] = 1; memset(tmp + j, 0, rsize - j); tmp[rsize - 1] |= 0x80; for(i = 0; i < rsizew; i++) state[i] ^= ((uint64_t *)tmp)[i]; keccakf(state, KECCAK_ROUNDS); //copy hash memcpy(hash, state, size); //print for(i = 0; i < size; i++) printf("%02x", hash[i]); printf(" %s\n", _fname); fin: if(_f != stdin) fclose(_f); free(hash); }
void sha3_update(sha3_state *sctx, const uint8_t *data, unsigned int len) { unsigned int done; const uint8_t *src; done = 0; src = data; if ((sctx->partial + len) > (sctx->rsiz - 1)) { if (sctx->partial) { done = -sctx->partial; memcpy(sctx->buf + sctx->partial, data, done + sctx->rsiz); src = sctx->buf; } do { unsigned int i; for (i = 0; i < sctx->rsizw; i++) sctx->st[i] ^= ((uint64_t *) src)[i]; keccakf(sctx->st, KECCAK_ROUNDS); done += sctx->rsiz; src = data + done; } while (done + (sctx->rsiz - 1) < len); sctx->partial = 0; } memcpy(sctx->buf + sctx->partial, src, len - done); sctx->partial += (len - done); }
/* This is simply the 'update' with the padding block. * The padding block is 0x01 || 0x00* || 0x80. First 0x01 and last 0x80 * bytes are always present, but they can be the same byte. */ void sha3_finalize(void *priv, unsigned char *out) { sha3_context *ctx = (sha3_context *)priv; SHA3_TRACE("called with %d bytes in the buffer", ctx->byteIndex); /* Append 2-bit suffix 01, per SHA-3 spec. Instead of 1 for padding we * use 1<<2 below. The 0x02 below corresponds to the suffix 01. * Overall, we feed 0, then 1, and finally 1 to start padding. Without * M || 01, we would simply use 1 to start padding. */ #ifndef SHA3_USE_KECCAK /* SHA3 version */ ctx->s[ctx->wordIndex] ^= (ctx->saved ^ ((uint64_t)((uint64_t)(0x02 | (1 << 2)) << ((ctx->byteIndex) * 8)))); #else /* For testing the "pure" Keccak version */ ctx->s[ctx->wordIndex] ^= (ctx->saved ^ ((uint64_t)((uint64_t)1 << (ctx->byteIndex * 8)))); #endif ctx->s[SHA3_KECCAK_SPONGE_WORDS - ctx->capacityWords - 1] ^= SHA3_CONST(0x8000000000000000UL); keccakf(ctx->s); /* Return first bytes of the ctx->s. This conversion is not needed for * little-endian platforms e.g. wrap with #if !defined(__BYTE_ORDER__) * || !defined(__ORDER_LITTLE_ENDIAN__) || \ * __BYTE_ORDER__!=__ORDER_LITTLE_ENDIAN__ ... the conversion below ... * #endif */ { unsigned i; for (i = 0; i < SHA3_KECCAK_SPONGE_WORDS; i++) { const unsigned t1 = (uint32_t)ctx->s[i]; const unsigned t2 = (uint32_t)((ctx->s[i] >> 16) >> 16); ctx->sb[i * 8 + 0] = (uint8_t)(t1); ctx->sb[i * 8 + 1] = (uint8_t)(t1 >> 8); ctx->sb[i * 8 + 2] = (uint8_t)(t1 >> 16); ctx->sb[i * 8 + 3] = (uint8_t)(t1 >> 24); ctx->sb[i * 8 + 4] = (uint8_t)(t2); ctx->sb[i * 8 + 5] = (uint8_t)(t2 >> 8); ctx->sb[i * 8 + 6] = (uint8_t)(t2 >> 16); ctx->sb[i * 8 + 7] = (uint8_t)(t2 >> 24); } } unsigned i; for (i = 0; i < ctx->numOutputBytes; i++) { out[i] = ctx->sb[i]; } SHA3_TRACE_BUF("Hash: (first 32 bytes)", ctx->sb, 256 / 8); }
int keccak(const uint8_t *in, int inlen, uint8_t *md, int mdlen) { state_t st; uint8_t temp[144]; int i, rsiz, rsizw; /* for some reason the enum from hash-ops.h is not valid here when compiling - is this a C vs C++ thing? Anyhow, lets just redefine it for now. */ const int HASH_DATA_AREA = 136; rsiz = sizeof(state_t) == mdlen ? HASH_DATA_AREA : 200 - 2 * mdlen; rsizw = rsiz / 8; memset(st, 0, sizeof(st)); for ( ; inlen >= rsiz; inlen -= rsiz, in += rsiz) { for (i = 0; i < rsizw; i++) st[i] ^= ((uint64_t *) in)[i]; keccakf(st, KECCAK_ROUNDS); } // last block and padding memcpy(temp, in, inlen); temp[inlen++] = 1; memset(temp + inlen, 0, rsiz - inlen); temp[rsiz - 1] |= 0x80; for (i = 0; i < rsizw; i++) st[i] ^= ((uint64_t *) temp)[i]; keccakf(st, KECCAK_ROUNDS); memcpy(md, st, mdlen); return 0; }
void sha3_final(sha3_state *sctx, uint8_t *out) { unsigned int i, inlen = sctx->partial; sctx->buf[inlen++] = 1; memset(sctx->buf + inlen, 0, sctx->rsiz - inlen); sctx->buf[sctx->rsiz - 1] |= 0x80; for (i = 0; i < sctx->rsizw; i++) sctx->st[i] ^= ((uint64_t *) sctx->buf)[i]; keccakf(sctx->st, KECCAK_ROUNDS); // RBF - On big endian systems, we may need to reverse the bit order here // RBF - CONVERT FROM CPU TO LE64 /* for (i = 0; i < sctx->rsizw; i++) sctx->st[i] = cpu_to_le64(sctx->st[i]); */ memcpy(out, sctx->st, sctx->md_len); memset(sctx, 0, sizeof(*sctx)); }
void hash_permutation(union hash_state *state) { keccakf((uint64_t*)state, 24); }
void sha3_update(void *priv, void const *bufIn, size_t len) { sha3_context *ctx = (sha3_context *)priv; /* 0...7 -- how much is needed to have a word */ unsigned old_tail = (8 - ctx->byteIndex) & 7; size_t words; unsigned tail; size_t i; const uint8_t *buf = bufIn; SHA3_TRACE_BUF("called to update with:", buf, len); SHA3_ASSERT(ctx->byteIndex < 8); SHA3_ASSERT(ctx->wordIndex < sizeof(ctx->s) / sizeof(ctx->s[0])); if (len < old_tail) { /* have no complete word or haven't started * the word yet */ SHA3_TRACE("because %d<%d, store it and return", (unsigned)len, (unsigned)old_tail); /* endian-independent code follows: */ while (len--) ctx->saved |= (uint64_t)(*(buf++)) << ((ctx->byteIndex++) * 8); SHA3_ASSERT(ctx->byteIndex < 8); return; } if (old_tail) { /* will have one word to process */ SHA3_TRACE("completing one word with %d bytes", (unsigned)old_tail); /* endian-independent code follows: */ len -= old_tail; while (old_tail--) ctx->saved |= (uint64_t)(*(buf++)) << ((ctx->byteIndex++) * 8); /* now ready to add saved to the sponge */ ctx->s[ctx->wordIndex] ^= ctx->saved; SHA3_ASSERT(ctx->byteIndex == 8); ctx->byteIndex = 0; ctx->saved = 0; if (++ctx->wordIndex == (SHA3_KECCAK_SPONGE_WORDS - ctx->capacityWords)) { keccakf(ctx->s); ctx->wordIndex = 0; } } /* now work in full words directly from input */ SHA3_ASSERT(ctx->byteIndex == 0); words = len / sizeof(uint64_t); tail = len - words * sizeof(uint64_t); SHA3_TRACE("have %d full words to process", (unsigned)words); for (i = 0; i < words; i++, buf += sizeof(uint64_t)) { const uint64_t t = (uint64_t)(buf[0]) | ((uint64_t)(buf[1]) << 8 * 1) | ((uint64_t)(buf[2]) << 8 * 2) | ((uint64_t)(buf[3]) << 8 * 3) | ((uint64_t)(buf[4]) << 8 * 4) | ((uint64_t)(buf[5]) << 8 * 5) | ((uint64_t)(buf[6]) << 8 * 6) | ((uint64_t)(buf[7]) << 8 * 7); #if defined(__x86_64__ ) || defined(__i386__) SHA3_ASSERT(memcmp(&t, buf, 8) == 0); #endif ctx->s[ctx->wordIndex] ^= t; if (++ctx->wordIndex == (SHA3_KECCAK_SPONGE_WORDS - ctx->capacityWords)) { keccakf(ctx->s); ctx->wordIndex = 0; } } SHA3_TRACE("have %d bytes left to process, save them", (unsigned)tail); /* finally, save the partial word */ SHA3_ASSERT(ctx->byteIndex == 0 && tail < 8); while (tail--) { SHA3_TRACE("Store byte %02x '%c'", *buf, *buf); ctx->saved |= (uint64_t)(*(buf++)) << ((ctx->byteIndex++) * 8); } SHA3_ASSERT(ctx->byteIndex < 8); SHA3_TRACE("Have saved=0x%016" PRIx64 " at the end", ctx->saved); }
int keccak(char **in_e, int inlen, uint8_t **md, int rsiz) { __m128i aux[10]; int i; const ALIGN uint64_t RC[100] = { 0x0000000000000001,0x0000000000000001, 0x0000000000008082,0x0000000000008082, 0x800000000000808A,0x800000000000808A, 0x8000000080008000,0x8000000080008000, 0x000000000000808B,0x000000000000808B, 0x0000000080000001,0x0000000080000001, 0x8000000080008081,0x8000000080008081, 0x8000000000008009,0x8000000000008009, 0x000000000000008A,0x000000000000008A, 0x0000000000000088,0x0000000000000088, 0x0000000080008009,0x0000000080008009, 0x000000008000000A,0x000000008000000A, 0x000000008000808B,0x000000008000808B, 0x800000000000008B,0x800000000000008B, 0x8000000000008089,0x8000000000008089, 0x8000000000008003,0x8000000000008003, 0x8000000000008002,0x8000000000008002, 0x8000000000000080,0x8000000000000080, 0x000000000000800A,0x000000000000800A, 0x800000008000000A,0x800000008000000A, 0x8000000080008081,0x8000000080008081, 0x8000000000008080,0x8000000000008080, 0x0000000080000001,0x0000000080000001, 0x8000000080008008,0x8000000080008008 }; ALIGN uint8_t temp[2][144]; int j,l=0,it=0; __m128i s[28],ain[8]; __m128i auxl[5]; char* con[32]; char* in[2]; int t,g,gf; in[0]=in_e[0]; in[1]=in_e[1]; init_S_zeros(j); if(inlen >= rsiz ){ it = inlen / rsiz; } switch (rsiz){ case 136: t = 8; g = 128; gf = 144; break; case 104: t = 6; g = 96; gf = 112; break; case 72: t = 4; g = 64; gf = 80; break; } for(i=0;i<it/2;i++){ join1(in,j,t); keccakf(s,j); in[0] += g; in[1] += g; join2(in,j,t); keccakf(s,j); in[0] += gf; in[1] += gf; } if(it%2 != 0 ){ join1(in,j,t); keccakf(s,j); in[0] += rsiz; in[1] += rsiz; } inlen = inlen - it * rsiz; for(i=0;i<2;i++){ memset(temp[i], 0, 144*sizeof(uint8_t)); memcpy(temp[i], in[i], inlen); temp[i][inlen] = 0x06; inlen++; temp[i][rsiz - 1] |= 0x80; } join_last(j,t); keccakf(s,j); switch (rsiz){ case 136: back(j,1); store(md[0],0,s[0]); store(md[0],1,s[2]); store(md[1],0,s[1]); store(md[1],1,s[3]); break; case 104: back(j,2); store(md[0],0,s[0]); store(md[0],1,s[2]); store(md[1],0,s[1]); store(md[1],1,s[3]); store(md[0],2,s[4]); store(md[0],3,s[6]); store(md[1],2,s[5]); store(md[1],3,s[7]); break; case 72: back(j,2); store(md[0],0,s[0]); store(md[0],1,s[2]); store(md[1],0,s[1]); store(md[1],1,s[3]); store(md[0],2,s[4]); store(md[0],3,s[6]); store(md[1],2,s[5]); store(md[1],3,s[7]); break; } return 0; }