├── .erlang ├── clean.sh ├── docs ├── todo.md └── suggestions.md ├── .gitignore ├── sha256.h ├── sha256_test.c ├── README.md ├── miner.erl ├── sha256.c └── amoveo_pow.c /.erlang: -------------------------------------------------------------------------------- 1 | application:start(inets). -------------------------------------------------------------------------------- /clean.sh: -------------------------------------------------------------------------------- 1 | #killall amoveo_c_miner 2 | pkill amoveo_c_miner 3 | -------------------------------------------------------------------------------- /docs/todo.md: -------------------------------------------------------------------------------- 1 | ability to run in the background. attach/detach 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .edts 3 | *.iml 4 | _build 5 | /rel/ 6 | *.db 7 | *~ 8 | .#* 9 | \#* 10 | .rebar 11 | erl_crash.dump 12 | keys_backup 13 | lib/ 14 | bin/ 15 | .Python 16 | include/ 17 | *.pyc 18 | nosetests.xml 19 | pip-selfcheck.json 20 | config/*/sys.config 21 | man 22 | compile_commands.json 23 | *.beam 24 | mining_input 25 | nonce.txt 26 | amoveo_c_miner -------------------------------------------------------------------------------- /sha256.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * Filename: sha256.h 3 | * Author: Brad Conte (brad AT bradconte.com) 4 | * Copyright: 5 | * Disclaimer: This code is presented "as is" without any guarantees. 6 | * Details: Defines the API for the corresponding SHA1 implementation. 7 | *********************************************************************/ 8 | 9 | #ifndef SHA256_H 10 | #define SHA256_H 11 | 12 | /*************************** HEADER FILES ***************************/ 13 | #include 14 | 15 | /****************************** MACROS ******************************/ 16 | #define SHA256_BLOCK_SIZE 32 // SHA256 outputs a 32 byte digest 17 | 18 | /**************************** DATA TYPES ****************************/ 19 | typedef unsigned char BYTE; // 8-bit byte 20 | typedef unsigned int WORD; // 32-bit word, change to "long" for 16-bit machines 21 | 22 | typedef struct { 23 | BYTE data[64]; 24 | WORD datalen; 25 | unsigned long long bitlen; 26 | WORD state[8]; 27 | } SHA256_CTX; 28 | 29 | /*********************** FUNCTION DECLARATIONS **********************/ 30 | void sha256_init(SHA256_CTX *ctx); 31 | void sha256_update(SHA256_CTX *ctx, const BYTE data[], size_t len); 32 | void sha256_final(SHA256_CTX *ctx, BYTE hash[]); 33 | 34 | #endif // SHA256_H 35 | -------------------------------------------------------------------------------- /sha256_test.c: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * Filename: sha256.c 3 | * Author: Brad Conte (brad AT bradconte.com) 4 | * Copyright: 5 | * Disclaimer: This code is presented "as is" without any guarantees. 6 | * Details: Performs known-answer tests on the corresponding SHA1 7 | implementation. These tests do not encompass the full 8 | range of available test vectors, however, if the tests 9 | pass it is very, very likely that the code is correct 10 | and was compiled properly. This code also serves as 11 | example usage of the functions. 12 | *********************************************************************/ 13 | 14 | /*************************** HEADER FILES ***************************/ 15 | #include 16 | #include 17 | #include 18 | #include "sha256.h" 19 | 20 | /*********************** FUNCTION DEFINITIONS ***********************/ 21 | int sha256_test() 22 | { 23 | BYTE text1[] = {"abc"}; 24 | BYTE text2[] = {"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"}; 25 | BYTE text3[] = {"aaaaaaaaaa"}; 26 | BYTE hash1[SHA256_BLOCK_SIZE] = {0xba,0x78,0x16,0xbf,0x8f,0x01,0xcf,0xea,0x41,0x41,0x40,0xde,0x5d,0xae,0x22,0x23, 27 | 0xb0,0x03,0x61,0xa3,0x96,0x17,0x7a,0x9c,0xb4,0x10,0xff,0x61,0xf2,0x00,0x15,0xad}; 28 | BYTE hash2[SHA256_BLOCK_SIZE] = {0x24,0x8d,0x6a,0x61,0xd2,0x06,0x38,0xb8,0xe5,0xc0,0x26,0x93,0x0c,0x3e,0x60,0x39, 29 | 0xa3,0x3c,0xe4,0x59,0x64,0xff,0x21,0x67,0xf6,0xec,0xed,0xd4,0x19,0xdb,0x06,0xc1}; 30 | BYTE hash3[SHA256_BLOCK_SIZE] = {0xcd,0xc7,0x6e,0x5c,0x99,0x14,0xfb,0x92,0x81,0xa1,0xc7,0xe2,0x84,0xd7,0x3e,0x67, 31 | 0xf1,0x80,0x9a,0x48,0xa4,0x97,0x20,0x0e,0x04,0x6d,0x39,0xcc,0xc7,0x11,0x2c,0xd0}; 32 | BYTE buf[SHA256_BLOCK_SIZE]; 33 | SHA256_CTX ctx; 34 | int idx; 35 | int pass = 1; 36 | 37 | sha256_init(&ctx); 38 | sha256_update(&ctx, text1, strlen(text1)); 39 | sha256_final(&ctx, buf); 40 | pass = pass && !memcmp(hash1, buf, SHA256_BLOCK_SIZE); 41 | 42 | sha256_init(&ctx); 43 | sha256_update(&ctx, text2, strlen(text2)); 44 | sha256_final(&ctx, buf); 45 | pass = pass && !memcmp(hash2, buf, SHA256_BLOCK_SIZE); 46 | 47 | sha256_init(&ctx); 48 | for (idx = 0; idx < 100000; ++idx) 49 | sha256_update(&ctx, text3, strlen(text3)); 50 | sha256_final(&ctx, buf); 51 | pass = pass && !memcmp(hash3, buf, SHA256_BLOCK_SIZE); 52 | 53 | return(pass); 54 | } 55 | 56 | int main() 57 | { 58 | printf("SHA-256 tests: %s\n", sha256_test() ? "SUCCEEDED" : "FAILED"); 59 | 60 | return(0); 61 | } 62 | -------------------------------------------------------------------------------- /docs/suggestions.md: -------------------------------------------------------------------------------- 1 | Calculating hash2integer on every loop of the mining cycle is a terrible design. 2 | Instead we should use the difficulty to calculate the highest hash we would accept, and then compare everything against this hash. 3 | 4 | 5 | 6 | I suspect hash2integer() could be rewritten as one or two lines of code, but I don't fully understand what is supposed to do, or why the loop is short by one. It wouldn't kill you to write some comments... 7 | 8 | From a performance perspective, there is a lot of duplicated work here — buffers that are reinitialized to the same value for every hash attempt, etc. If you were serious about this, you would inline the sha256 implementation and strip it down to the bare minimum you need, removing all loops and conditionals. You can prefill a 128-byte buffer with the data, difficulty, length and padding and only change the nonce. Even better, you can place the data in the first half and the nonce and difficulty in the second and save the sha256 state after the first half instead of re-hashing the same data every time, and you can integrate the logic of hash2integer() into sha256_final(). 9 | 10 | Hash2int could be written in about three lines of code, especially if you use a lookup table. 11 | 12 | 13 | 14 | 15 | f(h[i]) { 16 | int j = 7; 17 | for(; h[i] >> j; --j); 18 | x += j; 19 | y[1] = (h[i] * 1 << j) + (h[i+1] >> j); 20 | } else { 21 | x += 8; 22 | y[1] = h[i+1]; 23 | } 24 | 25 | 26 | 27 | For hahs2integer you should be able to drastically simplify the long chain of ifs. Basically all you're doing is checking what the highest set bit in h[i] is, and then doing some shifts on h[i] based on that value. So you should write a function that returns the position of the highest set bit (Which would be a value between 0 and 7, along with an error value like -1 to indicate the value has no set bits), and then do all your math based on that value. 28 | 29 | 30 | https://docs.oracle.com/cd/E19455-01/806-3773/instructionset-89/index.html 31 | 32 | https://docs.oracle.com/cd/E19455-01/806-3773/instructionset-90/index.html 33 | 34 | 35 | 36 | I haven't read you code, but sounds like you're doing something like bitscan. Check out the x86 bsf and bsr assembly instructions. 37 | 38 | If those don't apply, maybe also look at using a De Bruin sequences for a potential speedup. 39 | 40 | >Great suggestions, thanks a lot. 41 | 42 | De Bruin is a great idea for mining because I would only have to change 1 bit between nonces instead of adding 1 to a 32-byte value. 43 | 44 | I had never heard of bsf and bsr instructions, but it looks like they might be doing exactly what I need. 45 | 46 | https://en.wikipedia.org/wiki/De_Bruijn_sequence 47 | 48 | Report back with performance difference. I'm curious. 49 | 50 | The only time I've ever used the instruction was in C#. To call it I allocated unmanaged memory and assigned x86 OP Codes to it, then assigned that memory to a delegate. 51 | 52 | The overhead of calling a delegate plus the transition from unmanaged to managed code ended up causing it to be 3x slower than a C# De Bruijn function but only 20 percent slower than using a naive for loop 53 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Amoveo C miner 2 | ============= 3 | 4 | 5 | ## Dependencies 6 | ``` 7 | sudo apt-get install erlang libncurses5-dev libssl-dev unixodbc-dev g++ git 8 | ``` 9 | You might need less than what is listed above ^ 10 | [If you still have trouble with dependencies, look at dependencies from Amoveo: ](https://github.com/zack-bitcoin/amoveo/blob/master/docs/getting-started/dependencies.md) 11 | 12 | 13 | ## installation 14 | ``` 15 | git clone https://github.com/zack-bitcoin/amoveo-c-miner.git 16 | ``` 17 | 18 | 19 | ## configure 20 | 21 | You can connect it to a full node. Change the url at the top of miner.erl to point to your full node. It is named `Peer`. This gives all your money to whoever runs that full node. 22 | 23 | You can also connect to a mining pool. If you connect to a mining pool, you get paid by the person running the pool. 24 | This way you don't have to run Amoveo. 25 | set `Peer` to be the url for the mining pool. 26 | 27 | By default `Peer` is set up to connect to a public mining pool. 28 | 29 | Put your pubkey into the `Pubkey` definition at the top of miner.erl so that you can get paid. 30 | 31 | By default it uses 2 threads for mining. To change this, change the line near the top of `miner.erl` 32 | It says `-define(CORES, 2).` 33 | 34 | Change the 2 to the number of threads that you want to mine with. Usually, this should be the same as, or one less than the number of CPU cores on your computer. 35 | 36 | You can tell it to sleep in between mining periods so that you consume less CPU for mining. 37 | 38 | 39 | 40 | ## mining 41 | 42 | On ubuntu, the miner in C language can be compiled and turned on like this: 43 | ``` 44 | sh build.sh 45 | ``` 46 | Then you start mining like this: 47 | ``` 48 | miner:start(). 49 | ``` 50 | To turn it off, first use `Control + C`, `a`, `enter` to exit the erlang interface. 51 | Then to kill the miner processes, do: 52 | ``` 53 | sh clean.sh 54 | ``` 55 | 56 | On windows, you'll need [Visual Studio Community 2017](https://www.visualstudio.com/downloads/). To compile the miner, you have to run the Visual Studio and open `Tools > Visual Studio Command Prompt`. Then within the command prompt: 57 | ``` 58 | cd 59 | build.bat 60 | ``` 61 | Then, just like on ubuntu, start miner by: 62 | ``` 63 | miner:start(). 64 | ``` 65 | 66 | 67 | 68 | ## Check how fast you can mine in megahashes per second. 69 | 70 | You can do a speed test to measure how fast your computer is able to mine. First build the software normally 71 | ``` 72 | sh build.sh 73 | ``` 74 | Then change the settings to be in speed-test mode. 75 | ``` 76 | miner:speed_test(). 77 | ``` 78 | then quit from erlang 79 | ``` 80 | halt(). 81 | ``` 82 | now run the c program alone 83 | ``` 84 | ./amoveo_c_miner 85 | ``` 86 | 87 | ## other notes 88 | 89 | [The build.sh install script works for ubuntu linux and Mac OSX](build.sh). If you are using a different system, you will have to make some simple changes. 90 | 91 | By writing a miner for Amoveo in C, it becomes easier to write miners for the GPU and FPGAs. 92 | This simple C miner is a template for making miners in other languages. 93 | 94 | [Here is a link to where the same mining is implemented in erlang. The 'pow' function is the one to look at](https://github.com/BumblebeeBat/pink_crypto) 95 | 96 | [Here is a link to the main Amoveo repo.](https://github.com/zack-bitcoin/amoveo). If you want to solo mine without a mining pool, you will need this. Solo miners make more profit. 97 | -------------------------------------------------------------------------------- /miner.erl: -------------------------------------------------------------------------------- 1 | -module(miner) 2 | . 3 | -export([start/0, unpack_mining_data/1, speed_test/0, 4 | initialize/0]). 5 | %-define(Peer, "http://localhost:3011/").%for a test node on same computer. 6 | %-define(Peer, "http://localhost:8081/").%for a full node on same computer. 7 | -define(Peer, "http://localhost:8085/").%for a mining pool on the same computer. 8 | %-define(Peer, "http://159.89.106.253:8085/").%for a mining pool on the server. 9 | -define(CORES, 1). 10 | -define(Pubkey, <<"BCjdlkTKyFh7BBx4grLUGFJCedmzo4e0XT1KJtbSwq5vCJHrPltHATB+maZ+Pncjnfvt9CsCcI9Rn1vO+fPLIV4=">>). %If you are using a full node on the same computer, then it does not use this pubkey. Instead it uses the pubkey stored in the full node. 11 | -define(period, 50).%10000).%how long to wait in miliseconds before checking if new mining data is available. 12 | -define(pool_sleep_period, 1000).%How long to wait in miliseconds if we cannot connect to the mining pool. 13 | -define(miner_sleep, 0). %This is how you reduce the load on CPU. It sleeps this long in miliseconds between mining cycles. 14 | 15 | 16 | initialize() -> 17 | application:start(inets). 18 | 19 | start_many(N, _) when N < 1-> []; 20 | start_many(N, Me) -> 21 | Pid = spawn(fun() -> Me ! os:cmd("./amoveo_c_miner " ++ integer_to_list(N)) end), 22 | [Pid|start_many(N-1, Me)]. 23 | kill_os_mains() -> os:cmd("pkill amoveo_c_miner"). 24 | unpack_mining_data(R) -> 25 | <<_:(8*11), R2/binary>> = list_to_binary(R), 26 | {First, R3} = slice(R2, hd("\"")), 27 | <<_:(8*2), R4/binary>> = R3, 28 | {Second, R5} = slice(R4, hd("\"")), 29 | <<_:8, R6/binary>> = R5, 30 | {Third, _} = slice(R6, hd("]")), 31 | F = base64:decode(First), 32 | S = base64:decode(Second), 33 | {F, S, Third}. 34 | start() -> 35 | io:fwrite("Started mining.\n"), 36 | start2(). 37 | start2() -> 38 | kill_os_mains(), 39 | flush(), 40 | Data = <<"[\"mining_data\"]">>, 41 | R = talk_helper(Data, ?Peer, 1000), 42 | if 43 | is_list(R) -> 44 | start_c_miners(R); 45 | is_atom(R) -> 46 | timer:sleep(1000), 47 | start() 48 | end. 49 | read_nonce(0) -> 0; 50 | read_nonce(N) -> 51 | %io:fwrite("read nonce n is "), 52 | %io:fwrite(integer_to_list(N)), 53 | %io:fwrite("\n"), 54 | case file:read_file("nonce.txt") of 55 | {ok, <>} -> Nonce; 56 | {ok, <<>>} -> 57 | io:fwrite("nonce failed "), 58 | io:fwrite(integer_to_list(N)), 59 | io:fwrite("\n"), 60 | timer:sleep(100), 61 | read_nonce(N-1) 62 | end. 63 | 64 | 65 | speed_test() -> 66 | Third = <<0>>, 67 | F = <<0:256>>, 68 | RS = F, 69 | file:write_file("mining_input", <>). 70 | 71 | start_c_miners(R) -> 72 | {F, _, Third} = unpack_mining_data(R), %S is the nonce 73 | RS = crypto:strong_rand_bytes(23), 74 | ok = file:write_file("nonce.txt", <<"">>), 75 | file:write_file("mining_input", <>),%32 byte hash, 32 byte nonce, integer 76 | %we write these bytes into a file, and then call the c program, and expect the c program to read the file. 77 | % when the c program terminates, we read the response from a different file. 78 | flush(), 79 | start_many(?CORES, self()), 80 | receive _ -> 81 | kill_os_mains(), 82 | io:fwrite("Found a block. 1\n"), 83 | Nonce = read_nonce(2), 84 | case Nonce of 85 | 0 -> io:fwrite("nonce 0 error\n"); 86 | _ -> 87 | BinNonce = base64:encode(<>), 88 | Data = << <<"[\"work\",\"">>/binary, BinNonce/binary, <<"\",\"">>/binary, ?Pubkey/binary, <<"\"]">>/binary>>, 89 | talk_helper(Data, ?Peer, 5), 90 | io:fwrite("Found a block. 2\n"), 91 | timer:sleep(200) 92 | end 93 | after (?period) -> 94 | kill_os_mains(), 95 | io:fwrite("did not find a block in that period \n"), 96 | ok 97 | end, 98 | timer:sleep(?miner_sleep), 99 | start2(). 100 | talk_helper2(Data, Peer) -> 101 | %io:fwrite("talk helper 2\n"), 102 | httpc:request(post, {Peer, [], "application/octet-stream", iolist_to_binary(Data)}, [{timeout, 3000}], []). 103 | talk_helper(_Data, _Peer, 0) -> throw("talk helper failed"); 104 | talk_helper(Data, Peer, N) -> 105 | case talk_helper2(Data, Peer) of 106 | {ok, {Status, Headers, []}} -> 107 | io:fwrite("server gave confusing response\n"), 108 | io:fwrite({Status, Headers, Data, Peer}), 109 | timer:sleep(?pool_sleep_period), 110 | talk_helper(Data, Peer, N-1); 111 | {ok, {_, _, R}} -> 112 | %io:fwrite("talk helper 2 worked\n"), 113 | R; 114 | %{error, _} -> 115 | E -> 116 | io:fwrite("\nIf you are running a solo-mining node, then this error may have happened because you need to turn on and sync your Amoveo node before you can mine. You can get it here: https://github.com/zack-bitcoin/amoveo \n If this error happens while connected to the public mining node, then it can probably be safely ignored."), 117 | timer:sleep(?pool_sleep_period), 118 | talk_helper(Data, Peer, N-1) 119 | end. 120 | slice(Bin, Char) -> 121 | slice(Bin, Char, 0). 122 | slice(Bin, Char, N) -> 123 | NN = N*8, 124 | <> = Bin, 125 | if 126 | N > size(Bin) -> 1=2; 127 | (Char == Char2) -> 128 | {<>, Second}; 129 | true -> 130 | slice(Bin, Char, N+1) 131 | end. 132 | flush() -> 133 | receive 134 | _ -> flush() 135 | after 136 | 0 -> ok 137 | end. 138 | -------------------------------------------------------------------------------- /sha256.c: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * Filename: sha256.c 3 | * Author: Brad Conte (brad AT bradconte.com) 4 | * Copyright: 5 | * Disclaimer: This code is presented "as is" without any guarantees. 6 | * Details: Implementation of the SHA-256 hashing algorithm. 7 | SHA-256 is one of the three algorithms in the SHA2 8 | specification. The others, SHA-384 and SHA-512, are not 9 | offered in this implementation. 10 | Algorithm specification can be found here: 11 | * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2withchangenotice.pdf 12 | This implementation uses little endian byte order. 13 | *********************************************************************/ 14 | 15 | /*************************** HEADER FILES ***************************/ 16 | #include 17 | #include 18 | #include "sha256.h" 19 | 20 | /****************************** MACROS ******************************/ 21 | #define ROTLEFT(a,b) (((a) << (b)) | ((a) >> (32-(b)))) 22 | #define ROTRIGHT(a,b) (((a) >> (b)) | ((a) << (32-(b)))) 23 | 24 | #define CH(x,y,z) (((x) & (y)) ^ (~(x) & (z))) 25 | #define MAJ(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) 26 | #define EP0(x) (ROTRIGHT(x,2) ^ ROTRIGHT(x,13) ^ ROTRIGHT(x,22)) 27 | #define EP1(x) (ROTRIGHT(x,6) ^ ROTRIGHT(x,11) ^ ROTRIGHT(x,25)) 28 | #define SIG0(x) (ROTRIGHT(x,7) ^ ROTRIGHT(x,18) ^ ((x) >> 3)) 29 | #define SIG1(x) (ROTRIGHT(x,17) ^ ROTRIGHT(x,19) ^ ((x) >> 10)) 30 | 31 | /**************************** VARIABLES *****************************/ 32 | static const WORD k[64] = { 33 | 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5, 34 | 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174, 35 | 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da, 36 | 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967, 37 | 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85, 38 | 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070, 39 | 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3, 40 | 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 41 | }; 42 | 43 | /*********************** FUNCTION DEFINITIONS ***********************/ 44 | void sha256_transform(SHA256_CTX *ctx, const BYTE data[]) 45 | { 46 | WORD a, b, c, d, e, f, g, h, i, j, t1, t2, m[64]; 47 | 48 | for (i = 0, j = 0; i < 16; ++i, j += 4) 49 | m[i] = (data[j] << 24) | (data[j + 1] << 16) | (data[j + 2] << 8) | (data[j + 3]); 50 | for ( ; i < 64; ++i) 51 | m[i] = SIG1(m[i - 2]) + m[i - 7] + SIG0(m[i - 15]) + m[i - 16]; 52 | 53 | a = ctx->state[0]; 54 | b = ctx->state[1]; 55 | c = ctx->state[2]; 56 | d = ctx->state[3]; 57 | e = ctx->state[4]; 58 | f = ctx->state[5]; 59 | g = ctx->state[6]; 60 | h = ctx->state[7]; 61 | 62 | for (i = 0; i < 64; ++i) { 63 | t1 = h + EP1(e) + CH(e,f,g) + k[i] + m[i]; 64 | t2 = EP0(a) + MAJ(a,b,c); 65 | h = g; 66 | g = f; 67 | f = e; 68 | e = d + t1; 69 | d = c; 70 | c = b; 71 | b = a; 72 | a = t1 + t2; 73 | } 74 | 75 | ctx->state[0] += a; 76 | ctx->state[1] += b; 77 | ctx->state[2] += c; 78 | ctx->state[3] += d; 79 | ctx->state[4] += e; 80 | ctx->state[5] += f; 81 | ctx->state[6] += g; 82 | ctx->state[7] += h; 83 | } 84 | 85 | void sha256_init(SHA256_CTX *ctx) 86 | { 87 | ctx->datalen = 0; 88 | ctx->bitlen = 0; 89 | ctx->state[0] = 0x6a09e667; 90 | ctx->state[1] = 0xbb67ae85; 91 | ctx->state[2] = 0x3c6ef372; 92 | ctx->state[3] = 0xa54ff53a; 93 | ctx->state[4] = 0x510e527f; 94 | ctx->state[5] = 0x9b05688c; 95 | ctx->state[6] = 0x1f83d9ab; 96 | ctx->state[7] = 0x5be0cd19; 97 | } 98 | 99 | void sha256_update(SHA256_CTX *ctx, const BYTE data[], size_t len) 100 | { 101 | WORD i; 102 | 103 | for (i = 0; i < len; ++i) { 104 | ctx->data[ctx->datalen] = data[i]; 105 | ctx->datalen++; 106 | if (ctx->datalen == 64) { 107 | sha256_transform(ctx, ctx->data); 108 | ctx->bitlen += 512; 109 | ctx->datalen = 0; 110 | } 111 | } 112 | } 113 | 114 | void sha256_final(SHA256_CTX *ctx, BYTE hash[]) 115 | { 116 | WORD i; 117 | 118 | i = ctx->datalen; 119 | 120 | // Pad whatever data is left in the buffer. 121 | if (ctx->datalen < 56) { 122 | ctx->data[i++] = 0x80; 123 | while (i < 56) 124 | ctx->data[i++] = 0x00; 125 | } 126 | else { 127 | ctx->data[i++] = 0x80; 128 | while (i < 64) 129 | ctx->data[i++] = 0x00; 130 | sha256_transform(ctx, ctx->data); 131 | memset(ctx->data, 0, 56); 132 | } 133 | 134 | // Append to the padding the total message's length in bits and transform. 135 | ctx->bitlen += ctx->datalen * 8; 136 | ctx->data[63] = ctx->bitlen; 137 | ctx->data[62] = ctx->bitlen >> 8; 138 | ctx->data[61] = ctx->bitlen >> 16; 139 | ctx->data[60] = ctx->bitlen >> 24; 140 | ctx->data[59] = ctx->bitlen >> 32; 141 | ctx->data[58] = ctx->bitlen >> 40; 142 | ctx->data[57] = ctx->bitlen >> 48; 143 | ctx->data[56] = ctx->bitlen >> 56; 144 | sha256_transform(ctx, ctx->data); 145 | 146 | // Since this implementation uses little endian byte ordering and SHA uses big endian, 147 | // reverse all the bytes when copying the final state to the output hash. 148 | for (i = 0; i < 4; ++i) { 149 | hash[i] = (ctx->state[0] >> (24 - i * 8)) & 0x000000ff; 150 | hash[i + 4] = (ctx->state[1] >> (24 - i * 8)) & 0x000000ff; 151 | hash[i + 8] = (ctx->state[2] >> (24 - i * 8)) & 0x000000ff; 152 | hash[i + 12] = (ctx->state[3] >> (24 - i * 8)) & 0x000000ff; 153 | hash[i + 16] = (ctx->state[4] >> (24 - i * 8)) & 0x000000ff; 154 | hash[i + 20] = (ctx->state[5] >> (24 - i * 8)) & 0x000000ff; 155 | hash[i + 24] = (ctx->state[6] >> (24 - i * 8)) & 0x000000ff; 156 | hash[i + 28] = (ctx->state[7] >> (24 - i * 8)) & 0x000000ff; 157 | } 158 | } 159 | -------------------------------------------------------------------------------- /amoveo_pow.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "sha256.h" 6 | 7 | //maybe use 8 | 9 | WORD hash2integer(BYTE h[32]); 10 | static WORD pair2sci(WORD l[2]); 11 | static BYTE* next_nonce(BYTE nonce[32]); 12 | int check_pow(BYTE nonce[32], int, BYTE data[32]); 13 | BYTE* mine(BYTE nonce[32], int, BYTE data[32]); 14 | void test_hash(); 15 | void test_hash2integer(); 16 | void test_check_pow(); 17 | 18 | WORD hash2integer(BYTE h[32]) { 19 | WORD x = 0; 20 | WORD z = 0; 21 | for (int i = 0; i < 31; i++) { 22 | if (h[i] == 0) { 23 | x += 8; 24 | continue; 25 | } else if (h[i] < 2) { 26 | x += 7; 27 | z = h[i+1]; 28 | } else if (h[i] < 4) { 29 | x += 6; 30 | z = (h[i+1] / 2) + ((h[i] % 2) * 128); 31 | } else if (h[i] < 8) { 32 | x += 5; 33 | z = (h[i+1] / 4) + ((h[i] % 4) * 64); 34 | } else if (h[i] < 16) { 35 | x += 4; 36 | z = (h[i+1] / 8) + ((h[i] % 8) * 32); 37 | } else if (h[i] < 32) { 38 | x += 3; 39 | z = (h[i+1] / 16) + ((h[i] % 16) * 16); 40 | } else if (h[i] < 64) { 41 | x += 2; 42 | z = (h[i+1] / 32) + ((h[i] % 32) * 8); 43 | } else if (h[i] < 128) { 44 | x += 1; 45 | z = (h[i+1] / 64) + ((h[i] % 64) * 4); 46 | } else { 47 | z = (h[i+1] / 128) + ((h[i] % 128) * 2); 48 | } 49 | break; 50 | } 51 | WORD y[2]; 52 | y[0] = x; 53 | y[1] = z; 54 | return(pair2sci(y)); 55 | } 56 | static WORD pair2sci(WORD l[2]) { 57 | return((256*l[0]) + l[1]); 58 | } 59 | int check_pow(BYTE nonce[32], int difficulty, BYTE data[32]) { 60 | BYTE text[55];//32+23 61 | for (int i = 0; i < 32; i++) 62 | text[i] = data[i]; 63 | for (int i = 0; i < 23; i++) 64 | text[i+32] = nonce[i]; 65 | SHA256_CTX ctx; 66 | sha256_init(&ctx); 67 | sha256_update(&ctx, text, 55); 68 | BYTE buf[32]; 69 | sha256_final(&ctx, buf); 70 | int i = hash2integer(buf); 71 | //printf("pow did this much work %d \n", i); 72 | return(i > difficulty); 73 | } 74 | static BYTE* next_nonce(BYTE nonce[23]){ 75 | //we should use 32 bit or 64 bit integer 76 | for (int i = 0; i < 23; i++) { 77 | if (nonce[i] == 255) { 78 | nonce[i] = 0; 79 | } else { 80 | nonce[i] += 1; 81 | return nonce; 82 | } 83 | } 84 | return(0); 85 | } 86 | BYTE* mine(BYTE nonce[23], int difficulty, BYTE data[32]) { 87 | while (1) { 88 | if (check_pow(nonce, difficulty, data)) 89 | return nonce; 90 | nonce = next_nonce(nonce); 91 | } 92 | } 93 | void mine_test(BYTE nonce[23], int difficulty, BYTE data[32]) { 94 | for (int i = 0; i < 1000000; i++) { 95 | check_pow(nonce, 10000, data); 96 | nonce = next_nonce(nonce); 97 | } 98 | } 99 | void write_nonce(BYTE x[23]) { 100 | FILE *f = fopen("nonce.txt", "w"); 101 | if (f == NULL) { 102 | printf("Error opening file!\n"); 103 | //exit(1); 104 | } 105 | rewind(f);//unnecessary line? 106 | fwrite(x, 1, 23, f); 107 | fclose(f); 108 | return; 109 | } 110 | int read_input(BYTE B[32], BYTE N[23], WORD id) { 111 | FILE *fileptr; 112 | fileptr = fopen("mining_input", "rb"); 113 | fseek(fileptr, 0, SEEK_END); // Jump to the end of the file 114 | int filelen = ftell(fileptr); // Get the current byte offset in the file 115 | //ftell returns a long, maybe we shouldn't truncate it. 116 | rewind(fileptr); 117 | fread(B, 32, 1, fileptr); 118 | fread(N, 23, 1, fileptr); 119 | BYTE buffer[10] = { 0 }; 120 | fread(buffer, filelen-55, 1, fileptr); 121 | int diff = 0; 122 | BYTE c = 1; 123 | for (int i = 0; i < 10; i++) { 124 | c = buffer[i]; 125 | if (c == 0) { 126 | break; 127 | } 128 | diff *= 10; 129 | diff += (c - '0'); 130 | } 131 | fclose(fileptr); // Close the file 132 | return diff; 133 | } 134 | int main(int argc, char *argv[]) 135 | { 136 | BYTE bhash[32]; 137 | BYTE nonce[23]; 138 | WORD id; 139 | if (argc > 1) { 140 | id = atoi(argv[1]); 141 | } else { 142 | id = 0; 143 | } 144 | //printf("argc is %i\n", argc); 145 | //printf("id is %i\n", id); 146 | int diff = read_input(bhash, nonce, id); 147 | if (diff < 10) { 148 | printf("speed test starting\n"); 149 | clock_t begin = clock(); 150 | mine_test(nonce, diff, bhash);/* here, do your time-consuming job */ 151 | clock_t end = clock(); 152 | double time_spent = (double)(end - begin) / CLOCKS_PER_SEC; 153 | double speed = 1 / time_spent; 154 | printf("speed result: %f megahashes per second per CPU\n", speed); 155 | return(0); 156 | } 157 | printf("difficulty is %i\n", diff); 158 | mine(nonce, diff, bhash); //nonce, difficulty, data 159 | write_nonce(nonce); 160 | //test_check_pow(); 161 | //test_hash(); 162 | //test_hash2integer(); 163 | return(0); 164 | } 165 | void test_check_pow() { 166 | //["pow","2w1EW/I07ZnVg8hK4TzPEUA2XXyh2MpdyLgntn/42dI=",6452,995842502870377667814772] 167 | static BYTE data[32] = { 168 | 70,131,192,39,4,93,79,150,232,178,119,91,87,183,101,245, 169 | 48,56,180,196,47,44,184,68,130,255,91,39,44,98,51,216 170 | }; 171 | static BYTE nonce[23] = { 172 | 0,0,0,0,0,0,0,0,0,0,0,210,224,186, 173 | 241,224,230,139,188,229,116 174 | }; 175 | int out = check_pow(nonce, 6452, data); 176 | printf("check pow gave %i\n", out); 177 | //should be a 1. 178 | return; 179 | } 180 | void test_hash() { 181 | BYTE bhash[55] = {0}; 182 | SHA256_CTX ctx; 183 | for (int i = 0; i < 66; i++) { 184 | bhash[i] = 0; 185 | } 186 | sha256_init(&ctx); 187 | sha256_update(&ctx, bhash, 66); 188 | BYTE buf[32]; 189 | sha256_final(&ctx, buf); 190 | printf("%i, %i, %i, %i, %i, %i, %i, %i, \n", 191 | buf[0], buf[1], buf[2], buf[3], 192 | buf[4], buf[5], buf[6], buf[7]); 193 | // should be 239, 187, 3, 183, 167, 246, 253, 60, 194 | return; 195 | } 196 | 197 | void test_hash2integer() { 198 | BYTE buf[32] = { 199 | 0,0,0,0,0,0,0,0, 200 | 0,0,0,0,0,0,0,0, 201 | 200,200,0,0,0,0,0,0, 202 | 0,0,0,0,0,0,0,0 203 | }; 204 | printf("%i\n", hash2integer(buf)); 205 | // should be 32968 206 | return; 207 | } 208 | --------------------------------------------------------------------------------