253 lines
6.2 KiB
C
253 lines
6.2 KiB
C
/* ethash: C/C++ implementation of Ethash, the Ethereum Proof of Work algorithm.
|
|
* Copyright 2018-2019 Pawel Bylica.
|
|
* Licensed under the Apache License, Version 2.0.
|
|
*/
|
|
|
|
#include <stdint.h>
|
|
|
|
static uint32_t rol(uint32_t x, unsigned s)
|
|
{
|
|
return (x << s) | (x >> (32 - s));
|
|
}
|
|
|
|
static const uint32_t round_constants[22] = {
|
|
0x00000001,
|
|
0x00008082,
|
|
0x0000808A,
|
|
0x80008000,
|
|
0x0000808B,
|
|
0x80000001,
|
|
0x80008081,
|
|
0x00008009,
|
|
0x0000008A,
|
|
0x00000088,
|
|
0x80008009,
|
|
0x8000000A,
|
|
0x8000808B,
|
|
0x0000008B,
|
|
0x00008089,
|
|
0x00008003,
|
|
0x00008002,
|
|
0x00000080,
|
|
0x0000800A,
|
|
0x8000000A,
|
|
0x80008081,
|
|
0x00008080,
|
|
};
|
|
|
|
void ethash_keccakf800(uint32_t state[25])
|
|
{
|
|
/* The implementation directly translated from ethash_keccakf1600. */
|
|
|
|
int round;
|
|
|
|
uint32_t Aba, Abe, Abi, Abo, Abu;
|
|
uint32_t Aga, Age, Agi, Ago, Agu;
|
|
uint32_t Aka, Ake, Aki, Ako, Aku;
|
|
uint32_t Ama, Ame, Ami, Amo, Amu;
|
|
uint32_t Asa, Ase, Asi, Aso, Asu;
|
|
|
|
uint32_t Eba, Ebe, Ebi, Ebo, Ebu;
|
|
uint32_t Ega, Ege, Egi, Ego, Egu;
|
|
uint32_t Eka, Eke, Eki, Eko, Eku;
|
|
uint32_t Ema, Eme, Emi, Emo, Emu;
|
|
uint32_t Esa, Ese, Esi, Eso, Esu;
|
|
|
|
uint32_t Ba, Be, Bi, Bo, Bu;
|
|
|
|
uint32_t Da, De, Di, Do, Du;
|
|
|
|
Aba = state[0];
|
|
Abe = state[1];
|
|
Abi = state[2];
|
|
Abo = state[3];
|
|
Abu = state[4];
|
|
Aga = state[5];
|
|
Age = state[6];
|
|
Agi = state[7];
|
|
Ago = state[8];
|
|
Agu = state[9];
|
|
Aka = state[10];
|
|
Ake = state[11];
|
|
Aki = state[12];
|
|
Ako = state[13];
|
|
Aku = state[14];
|
|
Ama = state[15];
|
|
Ame = state[16];
|
|
Ami = state[17];
|
|
Amo = state[18];
|
|
Amu = state[19];
|
|
Asa = state[20];
|
|
Ase = state[21];
|
|
Asi = state[22];
|
|
Aso = state[23];
|
|
Asu = state[24];
|
|
|
|
for (round = 0; round < 22; round += 2)
|
|
{
|
|
/* Round (round + 0): Axx -> Exx */
|
|
|
|
Ba = Aba ^ Aga ^ Aka ^ Ama ^ Asa;
|
|
Be = Abe ^ Age ^ Ake ^ Ame ^ Ase;
|
|
Bi = Abi ^ Agi ^ Aki ^ Ami ^ Asi;
|
|
Bo = Abo ^ Ago ^ Ako ^ Amo ^ Aso;
|
|
Bu = Abu ^ Agu ^ Aku ^ Amu ^ Asu;
|
|
|
|
Da = Bu ^ rol(Be, 1);
|
|
De = Ba ^ rol(Bi, 1);
|
|
Di = Be ^ rol(Bo, 1);
|
|
Do = Bi ^ rol(Bu, 1);
|
|
Du = Bo ^ rol(Ba, 1);
|
|
|
|
Ba = Aba ^ Da;
|
|
Be = rol(Age ^ De, 12);
|
|
Bi = rol(Aki ^ Di, 11);
|
|
Bo = rol(Amo ^ Do, 21);
|
|
Bu = rol(Asu ^ Du, 14);
|
|
Eba = Ba ^ (~Be & Bi) ^ round_constants[round];
|
|
Ebe = Be ^ (~Bi & Bo);
|
|
Ebi = Bi ^ (~Bo & Bu);
|
|
Ebo = Bo ^ (~Bu & Ba);
|
|
Ebu = Bu ^ (~Ba & Be);
|
|
|
|
Ba = rol(Abo ^ Do, 28);
|
|
Be = rol(Agu ^ Du, 20);
|
|
Bi = rol(Aka ^ Da, 3);
|
|
Bo = rol(Ame ^ De, 13);
|
|
Bu = rol(Asi ^ Di, 29);
|
|
Ega = Ba ^ (~Be & Bi);
|
|
Ege = Be ^ (~Bi & Bo);
|
|
Egi = Bi ^ (~Bo & Bu);
|
|
Ego = Bo ^ (~Bu & Ba);
|
|
Egu = Bu ^ (~Ba & Be);
|
|
|
|
Ba = rol(Abe ^ De, 1);
|
|
Be = rol(Agi ^ Di, 6);
|
|
Bi = rol(Ako ^ Do, 25);
|
|
Bo = rol(Amu ^ Du, 8);
|
|
Bu = rol(Asa ^ Da, 18);
|
|
Eka = Ba ^ (~Be & Bi);
|
|
Eke = Be ^ (~Bi & Bo);
|
|
Eki = Bi ^ (~Bo & Bu);
|
|
Eko = Bo ^ (~Bu & Ba);
|
|
Eku = Bu ^ (~Ba & Be);
|
|
|
|
Ba = rol(Abu ^ Du, 27);
|
|
Be = rol(Aga ^ Da, 4);
|
|
Bi = rol(Ake ^ De, 10);
|
|
Bo = rol(Ami ^ Di, 15);
|
|
Bu = rol(Aso ^ Do, 24);
|
|
Ema = Ba ^ (~Be & Bi);
|
|
Eme = Be ^ (~Bi & Bo);
|
|
Emi = Bi ^ (~Bo & Bu);
|
|
Emo = Bo ^ (~Bu & Ba);
|
|
Emu = Bu ^ (~Ba & Be);
|
|
|
|
Ba = rol(Abi ^ Di, 30);
|
|
Be = rol(Ago ^ Do, 23);
|
|
Bi = rol(Aku ^ Du, 7);
|
|
Bo = rol(Ama ^ Da, 9);
|
|
Bu = rol(Ase ^ De, 2);
|
|
Esa = Ba ^ (~Be & Bi);
|
|
Ese = Be ^ (~Bi & Bo);
|
|
Esi = Bi ^ (~Bo & Bu);
|
|
Eso = Bo ^ (~Bu & Ba);
|
|
Esu = Bu ^ (~Ba & Be);
|
|
|
|
|
|
/* Round (round + 1): Exx -> Axx */
|
|
|
|
Ba = Eba ^ Ega ^ Eka ^ Ema ^ Esa;
|
|
Be = Ebe ^ Ege ^ Eke ^ Eme ^ Ese;
|
|
Bi = Ebi ^ Egi ^ Eki ^ Emi ^ Esi;
|
|
Bo = Ebo ^ Ego ^ Eko ^ Emo ^ Eso;
|
|
Bu = Ebu ^ Egu ^ Eku ^ Emu ^ Esu;
|
|
|
|
Da = Bu ^ rol(Be, 1);
|
|
De = Ba ^ rol(Bi, 1);
|
|
Di = Be ^ rol(Bo, 1);
|
|
Do = Bi ^ rol(Bu, 1);
|
|
Du = Bo ^ rol(Ba, 1);
|
|
|
|
Ba = Eba ^ Da;
|
|
Be = rol(Ege ^ De, 12);
|
|
Bi = rol(Eki ^ Di, 11);
|
|
Bo = rol(Emo ^ Do, 21);
|
|
Bu = rol(Esu ^ Du, 14);
|
|
Aba = Ba ^ (~Be & Bi) ^ round_constants[round + 1];
|
|
Abe = Be ^ (~Bi & Bo);
|
|
Abi = Bi ^ (~Bo & Bu);
|
|
Abo = Bo ^ (~Bu & Ba);
|
|
Abu = Bu ^ (~Ba & Be);
|
|
|
|
Ba = rol(Ebo ^ Do, 28);
|
|
Be = rol(Egu ^ Du, 20);
|
|
Bi = rol(Eka ^ Da, 3);
|
|
Bo = rol(Eme ^ De, 13);
|
|
Bu = rol(Esi ^ Di, 29);
|
|
Aga = Ba ^ (~Be & Bi);
|
|
Age = Be ^ (~Bi & Bo);
|
|
Agi = Bi ^ (~Bo & Bu);
|
|
Ago = Bo ^ (~Bu & Ba);
|
|
Agu = Bu ^ (~Ba & Be);
|
|
|
|
Ba = rol(Ebe ^ De, 1);
|
|
Be = rol(Egi ^ Di, 6);
|
|
Bi = rol(Eko ^ Do, 25);
|
|
Bo = rol(Emu ^ Du, 8);
|
|
Bu = rol(Esa ^ Da, 18);
|
|
Aka = Ba ^ (~Be & Bi);
|
|
Ake = Be ^ (~Bi & Bo);
|
|
Aki = Bi ^ (~Bo & Bu);
|
|
Ako = Bo ^ (~Bu & Ba);
|
|
Aku = Bu ^ (~Ba & Be);
|
|
|
|
Ba = rol(Ebu ^ Du, 27);
|
|
Be = rol(Ega ^ Da, 4);
|
|
Bi = rol(Eke ^ De, 10);
|
|
Bo = rol(Emi ^ Di, 15);
|
|
Bu = rol(Eso ^ Do, 24);
|
|
Ama = Ba ^ (~Be & Bi);
|
|
Ame = Be ^ (~Bi & Bo);
|
|
Ami = Bi ^ (~Bo & Bu);
|
|
Amo = Bo ^ (~Bu & Ba);
|
|
Amu = Bu ^ (~Ba & Be);
|
|
|
|
Ba = rol(Ebi ^ Di, 30);
|
|
Be = rol(Ego ^ Do, 23);
|
|
Bi = rol(Eku ^ Du, 7);
|
|
Bo = rol(Ema ^ Da, 9);
|
|
Bu = rol(Ese ^ De, 2);
|
|
Asa = Ba ^ (~Be & Bi);
|
|
Ase = Be ^ (~Bi & Bo);
|
|
Asi = Bi ^ (~Bo & Bu);
|
|
Aso = Bo ^ (~Bu & Ba);
|
|
Asu = Bu ^ (~Ba & Be);
|
|
}
|
|
|
|
state[0] = Aba;
|
|
state[1] = Abe;
|
|
state[2] = Abi;
|
|
state[3] = Abo;
|
|
state[4] = Abu;
|
|
state[5] = Aga;
|
|
state[6] = Age;
|
|
state[7] = Agi;
|
|
state[8] = Ago;
|
|
state[9] = Agu;
|
|
state[10] = Aka;
|
|
state[11] = Ake;
|
|
state[12] = Aki;
|
|
state[13] = Ako;
|
|
state[14] = Aku;
|
|
state[15] = Ama;
|
|
state[16] = Ame;
|
|
state[17] = Ami;
|
|
state[18] = Amo;
|
|
state[19] = Amu;
|
|
state[20] = Asa;
|
|
state[21] = Ase;
|
|
state[22] = Asi;
|
|
state[23] = Aso;
|
|
state[24] = Asu;
|
|
}
|