OhGodAPet icon

Wolf's Educational Ethash C Example

OhGodAPet | PRO | 12/28/19 03:38:22 AM UTC | 0 ⭐ | 480 👁️ | Never ⏰ | []
C |

4.33 KB

|

None

|

0 👍

/

0 👎

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
 
#define ROTL64(x, y)    (((x) << (y)) | ((x) >> (64ULL - (y))))
 
const uint64_t KeccakF1600RndConsts[24] =
{
    0x0000000000000001ULL, 0x0000000000008082ULL, 0x800000000000808AULL,
    0x8000000080008000ULL, 0x000000000000808BULL, 0x0000000080000001ULL,
    0x8000000080008081ULL, 0x8000000000008009ULL, 0x000000000000008AULL,
    0x0000000000000088ULL, 0x0000000080008009ULL, 0x000000008000000AULL,
    0x000000008000808BULL, 0x800000000000008BULL, 0x8000000000008089ULL,
    0x8000000000008003ULL, 0x8000000000008002ULL, 0x8000000000000080ULL,
    0x000000000000800AULL, 0x800000008000000AULL, 0x8000000080008081ULL,
    0x8000000000008080ULL, 0x0000000080000001ULL, 0x8000000080008008ULL
};
 
void keccakf(uint64_t *st)
{
    printf("State at beginning of Keccakf permutation:\n0x");
    for(int i = 0; i < 200; ++i) printf("%02X", ((uint8_t *)st)[i]);
    printf("\n\n");
    for(int i = 0; i < 24; ++i)
    {
        uint64_t bc[5], tmp;
 
        bc[0] = st[4] ^ st[9] ^ st[14] ^ st[19] ^ st[24] ^ ROTL64(st[1] ^ st[6] ^ st[11] ^ st[16] ^ st[21], 1);
        bc[1] = st[0] ^ st[5] ^ st[10] ^ st[15] ^ st[20] ^ ROTL64(st[2] ^ st[7] ^ st[12] ^ st[17] ^ st[22], 1);
        bc[2] = st[1] ^ st[6] ^ st[11] ^ st[16] ^ st[21] ^ ROTL64(st[3] ^ st[8] ^ st[13] ^ st[18] ^ st[23], 1);
        bc[3] = st[2] ^ st[7] ^ st[12] ^ st[17] ^ st[22] ^ ROTL64(st[4] ^ st[9] ^ st[14] ^ st[19] ^ st[24], 1);
        bc[4] = st[3] ^ st[8] ^ st[13] ^ st[18] ^ st[23] ^ ROTL64(st[0] ^ st[5] ^ st[10] ^ st[15] ^ st[20], 1);
        st[0] ^= bc[0];
 
        //st[0] ^= bc[0]; st[5] ^= bc[0]; st[10] ^= bc[0]; st[15] ^= bc[0]; st[20] ^= bc[0];
        //st[1] ^= bc[1]; st[6] ^= bc[1]; st[11] ^= bc[1]; st[16] ^= bc[1]; st[21] ^= bc[1];
        //st[2] ^= bc[2]; st[7] ^= bc[2]; st[12] ^= bc[2]; st[17] ^= bc[2]; st[22] ^= bc[2];
        //st[3] ^= bc[3]; st[8] ^= bc[3]; st[13] ^= bc[3]; st[18] ^= bc[3]; st[23] ^= bc[3];
        //st[4] ^= bc[4]; st[9] ^= bc[4]; st[14] ^= bc[4]; st[19] ^= bc[4]; st[24] ^= bc[4];
 
        tmp = st[ 1] ^ bc[1];
        st[ 1] = ROTL64(st[ 6] ^ bc[1], 44);
        st[ 6] = ROTL64(st[ 9] ^ bc[4], 20);
        st[ 9] = ROTL64(st[22] ^ bc[2], 61);
        st[22] = ROTL64(st[14] ^ bc[4], 39);
        st[14] = ROTL64(st[20] ^ bc[0], 18);
        st[20] = ROTL64(st[ 2] ^ bc[2], 62);
        st[ 2] = ROTL64(st[12] ^ bc[2], 43);
        st[12] = ROTL64(st[13] ^ bc[3], 25);
        st[13] = ROTL64(st[19] ^ bc[4],  8);
        st[19] = ROTL64(st[23] ^ bc[3], 56);
        st[23] = ROTL64(st[15] ^ bc[0], 41);
        st[15] = ROTL64(st[ 4] ^ bc[4], 27);
        st[ 4] = ROTL64(st[24] ^ bc[4], 14);
        st[24] = ROTL64(st[21] ^ bc[1],  2);
        st[21] = ROTL64(st[ 8] ^ bc[3], 55);
        st[ 8] = ROTL64(st[16] ^ bc[1], 45);
        st[16] = ROTL64(st[ 5] ^ bc[0], 36);
        st[ 5] = ROTL64(st[ 3] ^ bc[3], 28);
        st[ 3] = ROTL64(st[18] ^ bc[3], 21);
        st[18] = ROTL64(st[17] ^ bc[2], 15);
        st[17] = ROTL64(st[11] ^ bc[1], 10);
        st[11] = ROTL64(st[ 7] ^ bc[2],  6);
        st[ 7] = ROTL64(st[10] ^ bc[0],  3);
        st[10] = ROTL64(  tmp,  1);
 
        bc[0] = st[ 0]; bc[1] = st[ 1]; st[ 0] ^= (~bc[1]) & st[ 2]; st[ 1] ^= (~st[ 2]) & st[ 3]; st[ 2] ^= (~st[ 3]) & st[ 4]; st[ 3] ^= (~st[ 4]) & bc[0]; st[ 4] ^= (~bc[0]) & bc[1];
        bc[0] = st[ 5]; bc[1] = st[ 6]; st[ 5] ^= (~bc[1]) & st[ 7]; st[ 6] ^= (~st[ 7]) & st[ 8]; st[ 7] ^= (~st[ 8]) & st[ 9]; st[ 8] ^= (~st[ 9]) & bc[0]; st[ 9] ^= (~bc[0]) & bc[1];
        bc[0] = st[10]; bc[1] = st[11]; st[10] ^= (~bc[1]) & st[12]; st[11] ^= (~st[12]) & st[13]; st[12] ^= (~st[13]) & st[14]; st[13] ^= (~st[14]) & bc[0]; st[14] ^= (~bc[0]) & bc[1];
        bc[0] = st[15]; bc[1] = st[16]; st[15] ^= (~bc[1]) & st[17]; st[16] ^= (~st[17]) & st[18]; st[17] ^= (~st[18]) & st[19]; st[18] ^= (~st[19]) & bc[0]; st[19] ^= (~bc[0]) & bc[1];
        bc[0] = st[20]; bc[1] = st[21]; st[20] ^= (~bc[1]) & st[22]; st[21] ^= (~st[22]) & st[23]; st[22] ^= (~st[23]) & st[24]; st[23] ^= (~st[24]) & bc[0]; st[24] ^= (~bc[0]) & bc[1];
 
        st[0] ^= KeccakF1600RndConsts[i];
    }
}
 
int main(int argc, char **argv)
{
    uint64_t TestVector[25], State[25];
 
    for(int i = 0; i < 32; ++i) ((uint8_t *)TestVector)[i] = i;
 
    memcpy(State, TestVector, 32);
    // Nonce
    State[4] = 0xFEDCBA9876543210ULL;
    // Padding part 1
    State[5] = 0x0000000000000001ULL;
    State[6] = 0x00ULL;
    State[7] = 0x00ULL;
    // Padding part 2
    State[8] = 0x8000000000000000ULL;
 
    for(int i = 9; i < 25; ++i) State[i] = 0x00ULL;
    keccakf(State);
    
    return(0);
}

Comments