| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349 |
- /*
- * Copyright 2013-2014 Ronny Van Keer (released as CC0)
- * Copyright 2014 Luke Mitchell
- * Copyright 2014 Luke Dashjr
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 3 of the License, or (at your option)
- * any later version. See COPYING for more details.
- */
- #include "config.h"
- #include "miner.h"
- #include <stdlib.h>
- #include <stdint.h>
- #include <string.h>
- #include <stdio.h>
- #include <uthash.h>
- struct uint256 {
- unsigned char v[32];
- };
- typedef struct uint256 uint256;
- typedef unsigned long long UINT64;
- #define ROL(a, offset) ((a << offset) | (a >> (64-offset)))
- static const UINT64 KeccakF_RoundConstants[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
- };
- struct bin32 {
- UINT64 v0;
- UINT64 v1;
- UINT64 v2;
- UINT64 v3;
- };
- static
- void keccak1(unsigned char *out, const unsigned char *inraw, unsigned inrawlen)
- {
- unsigned char temp[136];
- unsigned round;
-
- UINT64 Aba, Abe, Abi, Abo, Abu;
- UINT64 Aga, Age, Agi, Ago, Agu;
- UINT64 Aka, Ake, Aki, Ako, Aku;
- UINT64 Ama, Ame, Ami, Amo, Amu;
- UINT64 Asa, Ase, Asi, Aso, Asu;
- UINT64 BCa, BCe, BCi, BCo, BCu;
- UINT64 Da, De, Di, Do, Du;
- UINT64 Eba, Ebe, Ebi, Ebo, Ebu;
- UINT64 Ega, Ege, Egi, Ego, Egu;
- UINT64 Eka, Eke, Eki, Eko, Eku;
- UINT64 Ema, Eme, Emi, Emo, Emu;
- UINT64 Esa, Ese, Esi, Eso, Esu;
-
- memcpy(temp, inraw, inrawlen);
- temp[inrawlen++] = 1;
- memset( temp+inrawlen, 0, 136 - inrawlen);
- temp[136-1] |= 0x80;
- const UINT64 *in = (const UINT64 *)temp;
-
- // copyFromState(A, state)
- Aba = in[ 0];
- Abe = in[ 1];
- Abi = in[ 2];
- Abo = in[ 3];
- Abu = in[ 4];
- Aga = in[ 5];
- Age = in[ 6];
- Agi = in[ 7];
- Ago = in[ 8];
- Agu = in[ 9];
- Aka = in[10];
- Ake = in[11];
- Aki = in[12];
- Ako = in[13];
- Aku = in[14];
- Ama = in[15];
- Ame = in[16];
- Ami = 0;
- Amo = 0;
- Amu = 0;
- Asa = 0;
- Ase = 0;
- Asi = 0;
- Aso = 0;
- Asu = 0;
-
- for (round = 0; round < 24; round += 2)
- {
- // prepareTheta
- BCa = Aba^Aga^Aka^Ama^Asa;
- BCe = Abe^Age^Ake^Ame^Ase;
- BCi = Abi^Agi^Aki^Ami^Asi;
- BCo = Abo^Ago^Ako^Amo^Aso;
- BCu = Abu^Agu^Aku^Amu^Asu;
-
- // thetaRhoPiChiIotaPrepareTheta(round, A, E)
- Da = BCu^ROL(BCe, 1);
- De = BCa^ROL(BCi, 1);
- Di = BCe^ROL(BCo, 1);
- Do = BCi^ROL(BCu, 1);
- Du = BCo^ROL(BCa, 1);
-
- Aba ^= Da;
- BCa = Aba;
- Age ^= De;
- BCe = ROL(Age, 44);
- Aki ^= Di;
- BCi = ROL(Aki, 43);
- Amo ^= Do;
- BCo = ROL(Amo, 21);
- Asu ^= Du;
- BCu = ROL(Asu, 14);
- Eba = BCa ^((~BCe) & BCi);
- Eba ^= KeccakF_RoundConstants[round];
- Ebe = BCe ^((~BCi) & BCo);
- Ebi = BCi ^((~BCo) & BCu);
- Ebo = BCo ^((~BCu) & BCa);
- Ebu = BCu ^((~BCa) & BCe);
-
- Abo ^= Do;
- BCa = ROL(Abo, 28);
- Agu ^= Du;
- BCe = ROL(Agu, 20);
- Aka ^= Da;
- BCi = ROL(Aka, 3);
- Ame ^= De;
- BCo = ROL(Ame, 45);
- Asi ^= Di;
- BCu = ROL(Asi, 61);
- Ega = BCa ^((~BCe) & BCi);
- Ege = BCe ^((~BCi) & BCo);
- Egi = BCi ^((~BCo) & BCu);
- Ego = BCo ^((~BCu) & BCa);
- Egu = BCu ^((~BCa) & BCe);
-
- Abe ^= De;
- BCa = ROL(Abe, 1);
- Agi ^= Di;
- BCe = ROL(Agi, 6);
- Ako ^= Do;
- BCi = ROL(Ako, 25);
- Amu ^= Du;
- BCo = ROL(Amu, 8);
- Asa ^= Da;
- BCu = ROL(Asa, 18);
- Eka = BCa ^((~BCe) & BCi);
- Eke = BCe ^((~BCi) & BCo);
- Eki = BCi ^((~BCo) & BCu);
- Eko = BCo ^((~BCu) & BCa);
- Eku = BCu ^((~BCa) & BCe);
-
- Abu ^= Du;
- BCa = ROL(Abu, 27);
- Aga ^= Da;
- BCe = ROL(Aga, 36);
- Ake ^= De;
- BCi = ROL(Ake, 10);
- Ami ^= Di;
- BCo = ROL(Ami, 15);
- Aso ^= Do;
- BCu = ROL(Aso, 56);
- Ema = BCa ^((~BCe) & BCi);
- Eme = BCe ^((~BCi) & BCo);
- Emi = BCi ^((~BCo) & BCu);
- Emo = BCo ^((~BCu) & BCa);
- Emu = BCu ^((~BCa) & BCe);
-
- Abi ^= Di;
- BCa = ROL(Abi, 62);
- Ago ^= Do;
- BCe = ROL(Ago, 55);
- Aku ^= Du;
- BCi = ROL(Aku, 39);
- Ama ^= Da;
- BCo = ROL(Ama, 41);
- Ase ^= De;
- BCu = ROL(Ase, 2);
- Esa = BCa ^((~BCe) & BCi);
- Ese = BCe ^((~BCi) & BCo);
- Esi = BCi ^((~BCo) & BCu);
- Eso = BCo ^((~BCu) & BCa);
- Esu = BCu ^((~BCa) & BCe);
-
- // prepareTheta
- BCa = Eba^Ega^Eka^Ema^Esa;
- BCe = Ebe^Ege^Eke^Eme^Ese;
- BCi = Ebi^Egi^Eki^Emi^Esi;
- BCo = Ebo^Ego^Eko^Emo^Eso;
- BCu = Ebu^Egu^Eku^Emu^Esu;
-
- // thetaRhoPiChiIotaPrepareTheta(round+1, E, A)
- Da = BCu^ROL(BCe, 1);
- De = BCa^ROL(BCi, 1);
- Di = BCe^ROL(BCo, 1);
- Do = BCi^ROL(BCu, 1);
- Du = BCo^ROL(BCa, 1);
-
- Eba ^= Da;
- BCa = Eba;
- Ege ^= De;
- BCe = ROL(Ege, 44);
- Eki ^= Di;
- BCi = ROL(Eki, 43);
- Emo ^= Do;
- BCo = ROL(Emo, 21);
- Esu ^= Du;
- BCu = ROL(Esu, 14);
- Aba = BCa ^((~BCe) & BCi);
- Aba ^= KeccakF_RoundConstants[round+1];
- Abe = BCe ^((~BCi) & BCo);
- Abi = BCi ^((~BCo) & BCu);
- Abo = BCo ^((~BCu) & BCa);
- Abu = BCu ^((~BCa) & BCe);
-
- Ebo ^= Do;
- BCa = ROL(Ebo, 28);
- Egu ^= Du;
- BCe = ROL(Egu, 20);
- Eka ^= Da;
- BCi = ROL(Eka, 3);
- Eme ^= De;
- BCo = ROL(Eme, 45);
- Esi ^= Di;
- BCu = ROL(Esi, 61);
- Aga = BCa ^((~BCe) & BCi);
- Age = BCe ^((~BCi) & BCo);
- Agi = BCi ^((~BCo) & BCu);
- Ago = BCo ^((~BCu) & BCa);
- Agu = BCu ^((~BCa) & BCe);
-
- Ebe ^= De;
- BCa = ROL(Ebe, 1);
- Egi ^= Di;
- BCe = ROL(Egi, 6);
- Eko ^= Do;
- BCi = ROL(Eko, 25);
- Emu ^= Du;
- BCo = ROL(Emu, 8);
- Esa ^= Da;
- BCu = ROL(Esa, 18);
- Aka = BCa ^((~BCe) & BCi);
- Ake = BCe ^((~BCi) & BCo);
- Aki = BCi ^((~BCo) & BCu);
- Ako = BCo ^((~BCu) & BCa);
- Aku = BCu ^((~BCa) & BCe);
-
- Ebu ^= Du;
- BCa = ROL(Ebu, 27);
- Ega ^= Da;
- BCe = ROL(Ega, 36);
- Eke ^= De;
- BCi = ROL(Eke, 10);
- Emi ^= Di;
- BCo = ROL(Emi, 15);
- Eso ^= Do;
- BCu = ROL(Eso, 56);
- Ama = BCa ^((~BCe) & BCi);
- Ame = BCe ^((~BCi) & BCo);
- Ami = BCi ^((~BCo) & BCu);
- Amo = BCo ^((~BCu) & BCa);
- Amu = BCu ^((~BCa) & BCe);
-
- Ebi ^= Di;
- BCa = ROL(Ebi, 62);
- Ego ^= Do;
- BCe = ROL(Ego, 55);
- Eku ^= Du;
- BCi = ROL(Eku, 39);
- Ema ^= Da;
- BCo = ROL(Ema, 41);
- Ese ^= De;
- BCu = ROL(Ese, 2);
- Asa = BCa ^((~BCe) & BCi);
- Ase = BCe ^((~BCi) & BCo);
- Asi = BCi ^((~BCo) & BCu);
- Aso = BCo ^((~BCu) & BCa);
- Asu = BCu ^((~BCa) & BCe);
- }
- {
- UINT64 *out64 = (UINT64 *)out;
- out64[ 0] = Aba;
- out64[ 1] = Abe;
- out64[ 2] = Abi;
- out64[ 3] = Abo;
- }
- }
- static
- void keccak_hash_data(void * const digest, const void * const pdata)
- {
- uint256 result;
-
- unsigned int data[20], datacopy[20]; // aligned for swap32yes
- memcpy(datacopy, pdata, 80);
- swap32yes(data, datacopy, 20);
- keccak1((unsigned char*)&result, (unsigned char*)data, 80);
-
- memcpy(digest, &result, 0x20);
- }
- static struct mining_algorithm malgo_keccak = {
- .name = "Keccak",
- .aliases = "Keccak",
-
- .algo = POW_KECCAK,
- .ui_skip_hash_bytes = 4,
- .worktime_skip_prevblk_u32 = 1,
- .reasonable_low_nonce_diff = 1.,
-
- .hash_data_f = keccak_hash_data,
- };
- static
- __attribute__((constructor))
- void init_keccak(void)
- {
- LL_APPEND(mining_algorithms, (&malgo_keccak));
- }
|