/* 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 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; }