├── target ├── clean.sh ├── nonce.txt ├── miner.beam ├── amoveo_miner ├── mining_input ├── todo.md ├── .gitignore ├── compile.sh ├── notes.md ├── README.md ├── miner.erl ├── amoveo_miner.c └── amoveo_miner.cl /target: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /clean.sh: -------------------------------------------------------------------------------- 1 | pkill amoveo_miner 2 | -------------------------------------------------------------------------------- /nonce.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zack-bitcoin/amoveo-opencl-miner/master/nonce.txt -------------------------------------------------------------------------------- /miner.beam: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zack-bitcoin/amoveo-opencl-miner/master/miner.beam -------------------------------------------------------------------------------- /amoveo_miner: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zack-bitcoin/amoveo-opencl-miner/master/amoveo_miner -------------------------------------------------------------------------------- /mining_input: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zack-bitcoin/amoveo-opencl-miner/master/mining_input -------------------------------------------------------------------------------- /todo.md: -------------------------------------------------------------------------------- 1 | We don't need so many dependencies as it says in the README. we should do a test to find out which dependencies we actually need. -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /compile.sh: -------------------------------------------------------------------------------- 1 | #For development purposes, it is convenient to recompile your code every time you run it. This way if anything changed, the changes will be included. 2 | # Since the things being compiled are so small, they can be compiled instantly, and there is no cost to recompiling every time we run the software. 3 | 4 | gcc amoveo_miner.c -Wall -o amoveo_miner -framework OpenCL 5 | 6 | # next recompile the erlang. 7 | erlc miner.erl 8 | 9 | # finally start an erlang interpreter so you can call the program. 10 | erl 11 | -------------------------------------------------------------------------------- /notes.md: -------------------------------------------------------------------------------- 1 | 2 | Looking at cgMiner, which is a popular bitcoin miner, it uses between 2*5 and 2*29 threads. So this is the range we should test for. 3 | 4 | from Scott, about installing and configuring opencl in linux: 5 | ok so I fixed an issue where /user/include/ didn't have CL/cl.h link.. by installing apt-get install opencl-headers so now CL/cl.h has a valid path to /user/include/ but it didn't fix the issue but was an issue 6 | 7 | 8 | from Greg, about installing and configuring in Windows: 9 | I compiled with the Nvidia CUDA Toolkit OpenCL with Visual Studio 2017 community. For Erlang, I just installed with the Erlang binary installer and compiled with erlc then moved the .beam in my release folder and started it 10 | 11 | Greg ran into this trouble: but that is messy because we need multiple tools, Erlang shell doesn't start with the right permissions and the default root is C:/Program Files/erl9.2/bin so I moved the miner.erl here to compile it 12 | I think there is some erlang args / env vars to change the default root, I didn't know any Erlang before -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | OpenCL Amoveo miner 2 | ========== 3 | 4 | This is the best miner for Amoveo currently available. It is a CPU miner. 5 | 6 | ## OpenCL dependency 7 | 8 | You will need openCL software that is compatible with your graphics card. 9 | I think this might come default with Mac, since I didn't have to install anything on my laptop for this. 10 | 11 | Linux: 12 | AMD driver / SDK link https://developer.amd.com/amd-accelerated-parallel-processing-app-sdk/ 13 | Nvidia driver / SDK link https://developer.nvidia.com/cuda-downloads 14 | 15 | Windows: 16 | OpenCL SDK can be downloaded by link https://developer.amd.com/amd-accelerated-parallel-processing-app-sdk/. Also you can try another OpenCL SDK vendors. Path to intalled SDK should be written to a new environment variable OPENCL_SDK. 17 | 18 | 19 | ## other dependencies 20 | 21 | for ubuntu 22 | ``` 23 | sudo apt-get install erlang libncurses5-dev libssl-dev unixodbc-dev g++ git 24 | ``` 25 | This list probably includes more dependencies than you actually need. 26 | 27 | for mac: 28 | 29 | install erlang version 18 or higher. 30 | You can use [Homebrew](https://brew.sh): 31 | ``` 32 | brew install erlang 33 | ``` 34 | There might be other dependencies too. 35 | 36 | for windows: 37 | I don't have a windows machine to find out. 38 | 39 | 40 | 41 | ## installation 42 | you need git to install this way. 43 | ``` 44 | git clone https://github.com/zack-bitcoin/amoveo-opencl-miner.git 45 | ``` 46 | or you can use your browser to download it [by clicking here](https://github.com/zack-bitcoin/amoveo-opencl-miner/archive/master.zip) 47 | 48 | 49 | ## configure 50 | 51 | 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. 52 | 53 | You can also connect to a mining pool. If you connect to a mining pool, you get paid by the person running the pool. 54 | This way you don't have to run Amoveo. 55 | set `Peer` to be the url for the mining pool. 56 | 57 | By default `Peer` is set up to connect to a public mining pool. 58 | 59 | Put your pubkey into the `Pubkey` definition at the top of miner.erl so that you can get paid. 60 | 61 | 62 | 63 | ## mining 64 | 65 | On ubuntu and Mac OSX, it can be compiled and turned on like this: 66 | ``` 67 | sh compile.sh 68 | ``` 69 | Then you start mining like this: 70 | ``` 71 | miner:start(). 72 | ``` 73 | To turn it off, first use `Control + C`, `a`, `enter` to exit the erlang interface. 74 | Then to kill the miner processes, do: 75 | ``` 76 | sh clean.sh 77 | ``` 78 | 79 | 80 | ## speed test 81 | 82 | first build the software 83 | ``` sh compile.sh``` 84 | then exit from erlang 85 | ```halt().``` 86 | then run the executable 87 | ```./amoveo_miner``` 88 | It takes about 6 seconds on my computer. 89 | 90 | 91 | ## other notes 92 | 93 | [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) 94 | 95 | [Here it is implemented in C language](https://github.com/zack-bitcoin/amoveo-c-miner) 96 | 97 | [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. -------------------------------------------------------------------------------- /miner.erl: -------------------------------------------------------------------------------- 1 | -module(miner) 2 | . 3 | -export([start/0, unpack_mining_data/1, speed_test/0, read_nonce/1]). 4 | -define(Peer, "http://localhost:3011/").%for a test-node 5 | %-define(Peer, "http://localhost:8081/").%for a full node on same computer. 6 | %-define(Peer, "http://localhost:8085/").%for a mining pool on the same computer. 7 | %-define(Peer, "http://159.89.106.253:8085/").%for a mining pool on the server. 8 | -define(CORES, 1). 9 | -define(Pubkey, <<"BMjV7rAAssU+DGd8w+6XsyDSdgoichddlSipZT3U+jehHSD68UwPdF9TO3HQ0g4hCh2rgUQyqPnP7vP0i/l8Ijw=">>). 10 | -define(period, 10).%how long to wait in seconds before checking if new mining data is available. 11 | -define(pool_sleep_period, 1000).%How long to wait in miliseconds if we cannot connect to the mining pool. 12 | %This should probably be around 1/20th of the blocktime. 13 | 14 | 15 | start_many(N, _) when N < 1-> []; 16 | start_many(N, Me) -> 17 | Pid = spawn(fun() -> Me ! os:cmd("./amoveo_miner " ++ integer_to_list(N)) end), 18 | [Pid|start_many(N-1, Me)]. 19 | kill_os_mains() -> os:cmd("killall amoveo_miner"). 20 | unpack_mining_data(R) -> 21 | <<_:(8*11), R2/binary>> = list_to_binary(R), 22 | {First, R3} = slice(R2, hd("\"")), 23 | <<_:(8*2), R4/binary>> = R3, 24 | {Second, R5} = slice(R4, hd("\"")), 25 | <<_:8, R6/binary>> = R5, 26 | {Third, _} = slice(R6, hd("]")), 27 | F = base64:decode(First), 28 | S = base64:decode(Second), 29 | {F, S, Third}. 30 | start() -> 31 | inets:start(), 32 | %file:delete("nonce.txt"), 33 | io:fwrite("Started mining.\n"), 34 | start2(). 35 | start2() -> 36 | kill_os_mains(), 37 | flush(), 38 | Data = <<"[\"mining_data\"]">>, 39 | R = talk_helper(Data, ?Peer, 1000), 40 | start_c_miners(R). 41 | read_nonce(0) -> 0; 42 | read_nonce(N) -> 43 | %io:fwrite("read nonce n is "), 44 | %io:fwrite(integer_to_list(N)), 45 | %io:fwrite("\n"), 46 | case file:read_file("nonce.txt") of 47 | {ok, <>} -> 48 | io:fwrite("found work \n"), 49 | %io:fwrite([<>]), 50 | io:fwrite(integer_to_list(Nonce)), 51 | io:fwrite("\n"), 52 | Nonce; 53 | {ok, <<>>} -> 54 | %io:fwrite("nonce failed "), 55 | %io:fwrite(integer_to_list(N)), 56 | %io:fwrite("\n"), 57 | timer:sleep(100), 58 | read_nonce(N-1) 59 | end. 60 | 61 | 62 | speed_test() -> 63 | Third = <<0>>, 64 | F = <<0:256>>, 65 | RS = F, 66 | file:write_file("mining_input", <>). 67 | 68 | start_c_miners(R) -> 69 | {F, _, Third} = unpack_mining_data(R), %S is the nonce 70 | RS = crypto:strong_rand_bytes(32), 71 | ok = file:write_file("nonce.txt", <<"">>), 72 | file:write_file("mining_input", <>), 73 | %we write these bytes into a file, and then call the c program, and expect the c program to read the file. 74 | % when the c program terminates, we read the response from a different file. 75 | flush(), 76 | start_many(?CORES, self()), 77 | receive _ -> 78 | kill_os_mains(), 79 | %io:fwrite("Found a block. 1\n"), 80 | Nonce = read_nonce(2), 81 | case Nonce of 82 | 0 -> io:fwrite("did not find a block in that period\n"); 83 | _ -> 84 | BinNonce = base64:encode(<>), 85 | Data = << <<"[\"work\",\"">>/binary, BinNonce/binary, <<"\",\"">>/binary, ?Pubkey/binary, <<"\"]">>/binary>>, 86 | talk_helper(Data, ?Peer, 2), 87 | io:fwrite("Found a block. 2\n"), 88 | file:delete("nonce.txt"), 89 | timer:sleep(200) 90 | end, 91 | start2() 92 | end. 93 | talk_helper2(Data, Peer) -> 94 | httpc:request(post, {Peer, [], "application/octet-stream", iolist_to_binary(Data)}, [{timeout, 3000}], []). 95 | talk_helper(_Data, _Peer, 0) -> ok; 96 | talk_helper(Data, Peer, N) -> 97 | case talk_helper2(Data, Peer) of 98 | {ok, {_Status, _Headers, []}} -> 99 | io:fwrite("server gave confusing response\n"), 100 | timer:sleep(?pool_sleep_period), 101 | talk_helper(Data, Peer, N-1); 102 | {ok, {_, _, R}} -> R; 103 | %{error, _} -> 104 | E -> 105 | 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."), 106 | timer:sleep(?pool_sleep_period), 107 | talk_helper(Data, Peer, N-1) 108 | end. 109 | slice(Bin, Char) -> 110 | slice(Bin, Char, 0). 111 | slice(Bin, Char, N) -> 112 | NN = N*8, 113 | <> = Bin, 114 | if 115 | N > size(Bin) -> 1=2; 116 | (Char == Char2) -> 117 | {<>, Second}; 118 | true -> 119 | slice(Bin, Char, N+1) 120 | end. 121 | flush() -> 122 | receive 123 | _ -> flush() 124 | after 125 | 0 -> ok 126 | end. 127 | -------------------------------------------------------------------------------- /amoveo_miner.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include //for testing only 4 | 5 | #ifdef __APPLE__ 6 | #include 7 | #else 8 | #include 9 | #endif 10 | 11 | #define MAX_SOURCE_SIZE (0x100000) 12 | 13 | /* 14 | int read_input(unsigned char B[32], unsigned char N[32]) { 15 | FILE *fileptr; 16 | fileptr = fopen("mining_input", "rb"); 17 | fseek(fileptr, 0, SEEK_END); // Jump to the end of the file 18 | int filelen = ftell(fileptr); // Get the current byte offset in the file 19 | //ftell returns a long, maybe we shouldn't truncate it. 20 | rewind(fileptr); 21 | fread(B, 32, 1, fileptr); 22 | fread(N, 32, 1, fileptr); 23 | //N[28] = id % 256; 24 | //N[29] = (id / 256) % 256; 25 | //N[30] = ((id / 256) / 256) % 256; 26 | //N[31] = (((id / 256) / 256) / 256) % 256; 27 | unsigned char buffer[10] = { 0 }; 28 | fread(buffer, filelen-64, 1, fileptr); 29 | unsigned int diff = 0; 30 | unsigned char c = 1; 31 | for (int i = 0; i < 10; i++) { 32 | c = buffer[i]; 33 | if (c == 0) { 34 | break; 35 | } 36 | diff *= 10; 37 | diff += (c - '0'); 38 | } 39 | fclose(fileptr); // Close the file 40 | return diff; 41 | } 42 | */ 43 | int read_input(unsigned char B[32], unsigned char N[32], unsigned int id) { 44 | FILE *fileptr; 45 | fileptr = fopen("mining_input", "rb"); 46 | fseek(fileptr, 0, SEEK_END); // Jump to the end of the file 47 | int filelen = ftell(fileptr); // Get the current byte offset in the file 48 | //ftell returns a long, maybe we shouldn't truncate it. 49 | rewind(fileptr); 50 | fread(B, 32, 1, fileptr); 51 | fread(N, 32, 1, fileptr); 52 | //N[28] = id % 256; 53 | //N[29] = (id / 256) % 256; 54 | //N[30] = ((id / 256) / 256) % 256; 55 | //N[31] = (((id / 256) / 256) / 256) % 256; 56 | unsigned char buffer[10] = { 0 }; 57 | fread(buffer, filelen-64, 1, fileptr); 58 | int diff = 0; 59 | unsigned char c = 1; 60 | for (int i = 0; i < 10; i++) { 61 | c = buffer[i]; 62 | if (c == 0) { 63 | break; 64 | } 65 | diff *= 10; 66 | diff += (c - '0'); 67 | } 68 | fclose(fileptr); // Close the file 69 | return diff; 70 | } 71 | void write_nonce(unsigned char x[32]) { 72 | FILE *f = fopen("nonce.txt", "w"); 73 | if (f == NULL) { 74 | printf("Error opening file!\n"); 75 | //exit(1); 76 | } 77 | rewind(f);//unnecessary line? 78 | fwrite(x, 1, 32, f); 79 | fclose(f); 80 | return; 81 | } 82 | 83 | int main(void) { 84 | //create the input vector 85 | //66 = 32 byts of bhash + 32 bytes of nonce + 2 bytes of difficulty 86 | unsigned int i; 87 | unsigned char bhash[32]; 88 | unsigned char nonce[32]; 89 | /* 90 | char bhash[32] = { 91 | 5,5,5,5,5,5,5,5, 92 | 5,5,5,5,5,5,5,5, 93 | 5,5,5,5,5,5,5,5, 94 | 5,5,5,5,5,5,5,5 95 | }; 96 | //char diff[2] = { 1, 200 }; 97 | char nonce[32] = { 98 | 4,4,4,4,4,4,4,4, 99 | 4,4,4,4,4,4,4,4, 100 | 4,4,4,4,4,4,4,4, 101 | 4,4,4,4,4,4,4,4 102 | }; 103 | int difficulty = 300; 104 | */ 105 | unsigned int id = 0; 106 | unsigned int difficulty = read_input(bhash, nonce, id); 107 | printf("difficulty %u\n", difficulty); 108 | const int INPUT_SIZE = 1024; 109 | unsigned char *A = (unsigned char*)malloc(sizeof(char)*INPUT_SIZE);//maybe we should make a different nonce for each kernel. 110 | for(i = 0; i < 32; i++) { 111 | A[i] = bhash[i]; 112 | A[i+34] = nonce[i]; 113 | A[i+68] = 0; 114 | } 115 | A[32] = difficulty / 256; 116 | A[33] = difficulty % 256; 117 | //A[66] = 0; 118 | //A[67] = 0; 119 | FILE *fp; 120 | char *source_str; 121 | size_t source_size; 122 | 123 | fp = fopen("amoveo_miner.cl", "r"); 124 | if (!fp) { 125 | fprintf(stderr, "Failed to load kernel.\n"); 126 | exit(1); 127 | } 128 | source_str = (char*)malloc(MAX_SOURCE_SIZE); 129 | source_size = fread( source_str, 1, MAX_SOURCE_SIZE, fp); 130 | fclose( fp ); 131 | 132 | // Get platform and device information 133 | cl_platform_id platform_id = NULL; 134 | cl_device_id device_id = NULL; 135 | cl_uint ret_num_devices; 136 | cl_uint ret_num_platforms; 137 | cl_int ret = clGetPlatformIDs(1, &platform_id, &ret_num_platforms); 138 | ret = clGetDeviceIDs( platform_id, CL_DEVICE_TYPE_ALL, 1, 139 | &device_id, &ret_num_devices); 140 | 141 | // Create an OpenCL context 142 | cl_context context = clCreateContext( NULL, 1, &device_id, NULL, NULL, &ret); 143 | 144 | // Create a command queue 145 | cl_command_queue command_queue = clCreateCommandQueue(context, device_id, 0, &ret); 146 | 147 | // Create memory buffers on the device for each vector 148 | cl_mem a_mem_obj = clCreateBuffer(context, CL_MEM_READ_ONLY, INPUT_SIZE * sizeof(char), NULL, &ret); 149 | 150 | // Copy the lists A and B to it's memory buffers 151 | ret = clEnqueueWriteBuffer(command_queue, a_mem_obj, CL_TRUE, 0, INPUT_SIZE * sizeof(char), A, 0, NULL, NULL); 152 | 153 | // Create a program from the kernel source 154 | cl_program program = clCreateProgramWithSource(context, 1, 155 | (const char **)&source_str, (const size_t *)&source_size, &ret); 156 | 157 | // Build the program 158 | ret = clBuildProgram(program, 1, &device_id, NULL, NULL, NULL); 159 | 160 | // Create the OpenCL kernel 161 | cl_kernel kernel = clCreateKernel(program, "amoveo_mine", &ret); 162 | 163 | // Set the arguments of the kernel 164 | ret = clSetKernelArg(kernel, 0, sizeof(cl_mem), (void *)&a_mem_obj); 165 | 166 | // Execute the OpenCL kernel on the list 167 | //size_t global_item_size = 1000000; // How many times we run the kernel in total 168 | size_t global_item_size = 10000000; // How many times we run the kernel in total 169 | //size_t global_item_size = 1; // How many times we run the kernel in total 170 | size_t local_item_size = 1; // Process in groups of 1 171 | clock_t begin = clock();//for testing only. 172 | ret = clEnqueueNDRangeKernel(command_queue, kernel, 1, NULL, 173 | &global_item_size, &local_item_size, 0, NULL, NULL); 174 | 175 | // Read the memory buffer C on the device to the local variable C 176 | unsigned char *C = (unsigned char*)malloc(sizeof(char)*INPUT_SIZE); 177 | ret = clEnqueueReadBuffer(command_queue, a_mem_obj, CL_TRUE, 0, 178 | INPUT_SIZE * sizeof(char), C, 0, NULL, NULL); 179 | clock_t end = clock();//for testing only. 180 | double time_spent = (double)(end - begin) / CLOCKS_PER_SEC;//for testing only 181 | double speed = 10 / time_spent;//for testing only 182 | printf("speed result: %f megahashes per second per CPU\n", speed);//for testing only 183 | 184 | // Display the result to the screen 185 | for(i = 0; i < 100; i++) { 186 | //<<202,151,129,18,202,27,189,202,250,194,49,179,154,35,220, 187 | if ((i % 4) == 0) { 188 | printf("\n"); 189 | } 190 | printf("%u ", C[i]); 191 | } 192 | unsigned char work[32]; 193 | for(i = 0; i < 32; i++) { 194 | work[i] = C[i + 68]; 195 | } 196 | //unsigned char work[32]; 197 | //for(i = 0; i < 8; i++) { 198 | //work[(i*4) + 3] = work0[(i*4) + 0]; 199 | //work[(i*4) + 2] = work0[(i*4) + 1]; 200 | //work[(i*4) + 1] = work0[(i*4) + 2]; 201 | //work[(i*4) + 0] = work0[(i*4) + 3]; 202 | //} 203 | if ((work[0] == 0) && (work[1] == 0) && (work[2] == 0) && (work[3] == 0)) { 204 | printf("no block found this time\n"); 205 | } else { 206 | printf("found a block %u %u\n", work[0], work[31]); 207 | write_nonce(work); 208 | } 209 | 210 | // Clean up 211 | ret = clFlush(command_queue); 212 | ret = clFinish(command_queue); 213 | ret = clReleaseKernel(kernel); 214 | ret = clReleaseProgram(program); 215 | ret = clReleaseMemObject(a_mem_obj); 216 | //ret = clReleaseMemObject(b_mem_obj); 217 | //ret = clReleaseMemObject(c_mem_obj); 218 | ret = clReleaseCommandQueue(command_queue); 219 | ret = clReleaseContext(context); 220 | free(A); 221 | //free(B); 222 | free(C); 223 | return 0; 224 | } 225 | -------------------------------------------------------------------------------- /amoveo_miner.cl: -------------------------------------------------------------------------------- 1 | #ifndef uint32_t 2 | #define uint32_t unsigned int 3 | #endif 4 | 5 | #define H0 0x6a09e667 6 | #define H1 0xbb67ae85 7 | #define H2 0x3c6ef372 8 | #define H3 0xa54ff53a 9 | #define H4 0x510e527f 10 | #define H5 0x9b05688c 11 | #define H6 0x1f83d9ab 12 | #define H7 0x5be0cd19 13 | 14 | 15 | uint rotr(uint x, int n) { 16 | if (n < 32) return (x >> n) | (x << (32 - n)); 17 | return x; 18 | } 19 | 20 | uint ch(uint x, uint y, uint z) { 21 | return (x & y) ^ (~x & z); 22 | } 23 | 24 | uint maj(uint x, uint y, uint z) { 25 | return (x & y) ^ (x & z) ^ (y & z); 26 | } 27 | 28 | uint sigma0(uint x) { 29 | return rotr(x, 2) ^ rotr(x, 13) ^ rotr(x, 22); 30 | } 31 | 32 | uint sigma1(uint x) { 33 | return rotr(x, 6) ^ rotr(x, 11) ^ rotr(x, 25); 34 | } 35 | 36 | uint gamma0(uint x) { 37 | return rotr(x, 7) ^ rotr(x, 18) ^ (x >> 3); 38 | } 39 | 40 | uint gamma1(uint x) { 41 | return rotr(x, 17) ^ rotr(x, 19) ^ (x >> 10); 42 | } 43 | 44 | 45 | __kernel void amoveo_mine(__global uchar *Z) { 46 | //Z[32] = 20; 47 | 48 | //increment the nonce. 49 | uchar carry_flag = 1; 50 | for (uint i = 0; i < 32; i++) { 51 | if (carry_flag == 1) { 52 | if (Z[34 + i] == 255) { 53 | Z[34 + i] = 0; 54 | } else { 55 | Z[34 + i] ++; 56 | carry_flag = 0; 57 | } 58 | } 59 | } 60 | 61 | //preparing for sha256 62 | uint data_info[3]; 63 | //uchar plain_key[66] = "a"; 64 | uchar plain_key[66];// = "a"; 65 | for (uint i = 0; i < 66; i++) { 66 | plain_key[i] = Z[i]; 67 | //plain_key[i] = 0; 68 | } 69 | /* 70 | uchar plain_key[4]; 71 | for(uint i = 0; i < 4; i++) { 72 | plain_key[i] = 0; 73 | } 74 | plain_key[1] = 1; 75 | */ 76 | data_info[0] = 64; 77 | data_info[1] = 1;//global work size 78 | //data_info[2] = strlen(plain_key); 79 | // printf("plainkey length %u\n", strlen(plain_key)); 80 | data_info[2] = 66; 81 | //data_info[2] = 4; 82 | //printf("%d\n", data_info[2]); 83 | uint digest[8]; 84 | for (uint i = 0; i < 8; i++) { 85 | digest[i] = 0; 86 | } 87 | 88 | //SHA256 starts. 89 | 90 | //} 91 | ////# __kernel void sha256_crypt_kernel(__global uint *data_info,__global char *plain_key, __global uint *digest){ 92 | //void hash(uint* data_info, uint* plain_key, uint* digest){ 93 | //void hash(){ 94 | int t, gid, msg_pad; 95 | int stop, mmod; 96 | uint i, ulen, item, total; 97 | uint W[80], temp, A,B,C,D,E,F,G,H,T1,T2; 98 | uint num_keys = data_info[1]; 99 | int current_pad; 100 | 101 | uint K[64]={ 102 | 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 103 | 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 104 | 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 105 | 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 106 | 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 107 | 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 108 | 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 109 | 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 110 | }; 111 | 112 | msg_pad=0; 113 | 114 | ulen = data_info[2]; 115 | total = ulen%64>=56?2:1 + ulen/64; 116 | //total = 1; 117 | 118 | // printf("ulen: %u total:%u\n", ulen, total); 119 | 120 | digest[0] = H0; 121 | digest[1] = H1; 122 | digest[2] = H2; 123 | digest[3] = H3; 124 | digest[4] = H4; 125 | digest[5] = H5; 126 | digest[6] = H6; 127 | digest[7] = H7; 128 | for(item=0; item msg_pad) 146 | { 147 | current_pad = (ulen-msg_pad)>64?64:(ulen-msg_pad); 148 | } 149 | else 150 | { 151 | current_pad =-1; 152 | } 153 | 154 | // printf("current_pad: %d\n",current_pad); 155 | if(current_pad>0) 156 | { 157 | i=current_pad; 158 | 159 | stop = i/4; 160 | // printf("i:%d, stop: %d msg_pad:%d\n",i,stop, msg_pad); 161 | for (t = 0 ; t < stop ; t++){ 162 | W[t] = ((uchar) plain_key[msg_pad + t * 4]) << 24; 163 | W[t] |= ((uchar) plain_key[msg_pad + t * 4 + 1]) << 16; 164 | W[t] |= ((uchar) plain_key[msg_pad + t * 4 + 2]) << 8; 165 | W[t] |= (uchar) plain_key[msg_pad + t * 4 + 3]; 166 | //printf("W[%u]: %u\n",t,W[t]); 167 | } 168 | mmod = i % 4; 169 | if ( mmod == 3){ 170 | W[t] = ((uchar) plain_key[msg_pad + t * 4]) << 24; 171 | W[t] |= ((uchar) plain_key[msg_pad + t * 4 + 1]) << 16; 172 | W[t] |= ((uchar) plain_key[msg_pad + t * 4 + 2]) << 8; 173 | W[t] |= ((uchar) 0x80) ; 174 | } else if (mmod == 2) { 175 | W[t] = ((uchar) plain_key[msg_pad + t * 4]) << 24; 176 | W[t] |= ((uchar) plain_key[msg_pad + t * 4 + 1]) << 16; 177 | W[t] |= 0x8000 ; 178 | } else if (mmod == 1) { 179 | W[t] = ((uchar) plain_key[msg_pad + t * 4]) << 24; 180 | W[t] |= 0x800000 ; 181 | } else { //if (mmod == 0) 182 | W[t] = 0x80000000 ; 183 | } 184 | 185 | if (current_pad<56) 186 | { 187 | W[15] = ulen*8 ; 188 | //printf("ulen avlue 2 :w[15] :%u\n", W[15]); 189 | } 190 | } 191 | else if(current_pad <0) 192 | { 193 | if( ulen%64==0) 194 | W[0]=0x80000000; 195 | W[15]=ulen*8; 196 | //printf("ulen avlue 3 :w[15] :%u\n", W[15]); 197 | } 198 | 199 | for (t = 0; t < 64; t++) { 200 | if (t >= 16) 201 | W[t] = gamma1(W[t - 2]) + W[t - 7] + gamma0(W[t - 15]) + W[t - 16]; 202 | T1 = H + sigma1(E) + ch(E, F, G) + K[t] + W[t]; 203 | T2 = sigma0(A) + maj(A, B, C); 204 | H = G; G = F; F = E; E = D + T1; D = C; C = B; B = A; A = T1 + T2; 205 | } 206 | digest[0] += A; 207 | digest[1] += B; 208 | digest[2] += C; 209 | digest[3] += D; 210 | digest[4] += E; 211 | digest[5] += F; 212 | digest[6] += G; 213 | digest[7] += H; 214 | 215 | //SHA256 ends. 216 | //hash2integer 217 | //(256*number of leading 0 bits) + byte starting with 1. 218 | } 219 | uchar digest_bytes[32]; 220 | for (uint i = 0; i < 8; i++) { 221 | digest_bytes[(i*4)+ 3] = digest[i] % 256; 222 | digest_bytes[(i*4)+ 2] = (digest[i] / 256) % 256; 223 | digest_bytes[(i*4)+ 1] = ((digest[i] / 256)/256) % 256; 224 | digest_bytes[(i*4)+ 0] = (((digest[i] / 256)/256)/256); 225 | } 226 | uint our_diff = 0; 227 | uchar diff_flag = 1; 228 | uchar hash_int; 229 | uchar hash_bit; 230 | uchar hash_bit2; 231 | 232 | //Hash2integer 233 | for(uint i = 0; i < 256; i++) { 234 | if (diff_flag == 1) { 235 | hash_int = i / 8; 236 | hash_bit = (7 - (i % 8)); 237 | hash_bit2 = ((digest_bytes[hash_int]) >> hash_bit) & 1; 238 | if (hash_bit2 == 1) { 239 | diff_flag = 0; 240 | our_diff *= 256; 241 | our_diff += ((digest_bytes[hash_int] << (i % 8)) + (digest_bytes[hash_int+1] >> (hash_bit + 1))); 242 | } else { 243 | our_diff++; 244 | } 245 | } 246 | } 247 | //printf("z 32 %u\n", Z[32]); 248 | //printf("our diff %u\n", our_diff); 249 | //check if our_diff > difficulty 250 | //if it is, then save the nonce. 251 | uint difficulty = (256 * Z[32]) + Z[33]; 252 | if (our_diff > difficulty) { 253 | printf("ourdiff %d > target %d\n", our_diff, difficulty); 254 | for (uint i = 0; i < 32; i++) { 255 | Z[68+i] = Z[34+i]; 256 | } 257 | } 258 | /* 259 | printf("digest bytes\n"); 260 | for (uint i = 0; i < 32; i++) { 261 | if ((i % 8) == 0) { 262 | printf("\n"); 263 | } 264 | printf("%u ", digest_bytes[i]); 265 | } 266 | printf("\ndigest bytes end\n"); 267 | 268 | */ 269 | 270 | 271 | 272 | //for testing purposes 273 | //for (uint i = 0; i < 32; i++) { 274 | // Z[i] = digest_bytes[i]; 275 | //} 276 | 277 | // for (t = 0; t < 80; t++) 278 | // { 279 | // printf("W[%d]: %u\n",t,W[t]); 280 | // } 281 | } 282 | 283 | 284 | --------------------------------------------------------------------------------