albertobsd / keyhunt

privkey hunt for crypto currencies that use secp256k1 elliptic curve
MIT License
632 stars 344 forks source link

Accelerate core functions with SIMD intrinsics #36

Open chawyehsu opened 3 years ago

chawyehsu commented 3 years ago

Some core computation functions like sha256, bloom (and some others maybe) are implemented as per standards.

To gain more computation speed, SIMD instructions accelerated implementations of these functions could help. For instance, we know a SIMD accelerated version of sha256 is used by the bitcoin-core client. And for reference, some accelerated versions like sha256-simd have obtained up to 8x improvement compared to a standard implementation.

We Need to Go Deeper.

albertobsd commented 3 years ago

We Need to Go Deeper.

Yes you are right, just now im implementing the Jean Luc Pons SECP256K1 library, that work in very similar way than the libgmp, but it use some group Modulo Operations with SSE2 Operations to boost his speed to create publickeys up to 5 times faster. This will boost all the speed from all modes from address to bsgs mode.

Once that i finish that part i will try to implement your suggestion with that version of sha256.

Best regards

albertobsd commented 2 years ago

ok, right know im checking for this change.

albertobsd commented 2 years ago

I just add some of this code, it help to speed up x2 the RMD160 mode

chawyehsu commented 2 years ago

I just add some of this code, it help to speed up x2 the RMD160 mode

Great, but I can't build the latest commit with mingw. here is the error report:

g++ -m64 -mssse3 -Wno-write-strings -O2 -o hash/ripemd160_sse.o -c hash/ripemd160_sse.cpp
hash/ripemd160_sse.cpp:47:9: error: "not" cannot be used as a macro name as it is an operator in C++
   47 | #define not(x) _mm_andnot_si128(x, _mm_cmpeq_epi32(_mm_setzero_si128(), _mm_setzero_si128()))
      |         ^~~
hash/ripemd160_sse.cpp:26:53: warning: 'align' attribute directive ignored [-Wattributes]
   26 |   static const __declspec(align(16)) uint32_t _init[] = {
      |                                                     ^
hash/ripemd160_sse.cpp: In function 'void ripemd160sse_32(unsigned char*, unsigned char*, unsigned char*, unsigned char*, unsigned char*, unsigned char*, unsigned char*, unsigned char*)':
hash/ripemd160_sse.cpp:303:27: error: request for member 'm128i_u32' in 's[0]', which is of non-class type '__m128i'
  303 | ((uint32_t *)d)[0] = s[0].m128i_u32[i]; \
      |                           ^~~~~~~~~
hash/ripemd160_sse.cpp:356:3: note: in expansion of macro 'DEPACK'
  356 |   DEPACK(d0,3);
      |   ^~~~~~
hash/ripemd160_sse.cpp:304:27: error: request for member 'm128i_u32' in 's[1]', which is of non-class type '__m128i'
  304 | ((uint32_t *)d)[1] = s[1].m128i_u32[i]; \
      |                           ^~~~~~~~~
hash/ripemd160_sse.cpp:356:3: note: in expansion of macro 'DEPACK'
  356 |   DEPACK(d0,3);
      |   ^~~~~~
hash/ripemd160_sse.cpp:305:27: error: request for member 'm128i_u32' in 's[2]', which is of non-class type '__m128i'
  305 | ((uint32_t *)d)[2] = s[2].m128i_u32[i]; \
      |                           ^~~~~~~~~
hash/ripemd160_sse.cpp:356:3: note: in expansion of macro 'DEPACK'
  356 |   DEPACK(d0,3);
      |   ^~~~~~
hash/ripemd160_sse.cpp:306:27: error: request for member 'm128i_u32' in 's[3]', which is of non-class type '__m128i'
  306 | ((uint32_t *)d)[3] = s[3].m128i_u32[i]; \
      |                           ^~~~~~~~~
hash/ripemd160_sse.cpp:356:3: note: in expansion of macro 'DEPACK'
  356 |   DEPACK(d0,3);
      |   ^~~~~~
hash/ripemd160_sse.cpp:307:27: error: request for member 'm128i_u32' in 's[4]', which is of non-class type '__m128i'
  307 | ((uint32_t *)d)[4] = s[4].m128i_u32[i];
      |                           ^~~~~~~~~
hash/ripemd160_sse.cpp:356:3: note: in expansion of macro 'DEPACK'
  356 |   DEPACK(d0,3);
      |   ^~~~~~
hash/ripemd160_sse.cpp:303:27: error: request for member 'm128i_u32' in 's[0]', which is of non-class type '__m128i'
  303 | ((uint32_t *)d)[0] = s[0].m128i_u32[i]; \
      |                           ^~~~~~~~~
hash/ripemd160_sse.cpp:357:3: note: in expansion of macro 'DEPACK'
  357 |   DEPACK(d1,2);
      |   ^~~~~~
hash/ripemd160_sse.cpp:304:27: error: request for member 'm128i_u32' in 's[1]', which is of non-class type '__m128i'
  304 | ((uint32_t *)d)[1] = s[1].m128i_u32[i]; \
      |                           ^~~~~~~~~
hash/ripemd160_sse.cpp:357:3: note: in expansion of macro 'DEPACK'
  357 |   DEPACK(d1,2);
      |   ^~~~~~
hash/ripemd160_sse.cpp:305:27: error: request for member 'm128i_u32' in 's[2]', which is of non-class type '__m128i'
  305 | ((uint32_t *)d)[2] = s[2].m128i_u32[i]; \
      |                           ^~~~~~~~~
hash/ripemd160_sse.cpp:357:3: note: in expansion of macro 'DEPACK'
  357 |   DEPACK(d1,2);
      |   ^~~~~~
hash/ripemd160_sse.cpp:306:27: error: request for member 'm128i_u32' in 's[3]', which is of non-class type '__m128i'
  306 | ((uint32_t *)d)[3] = s[3].m128i_u32[i]; \
      |                           ^~~~~~~~~
hash/ripemd160_sse.cpp:357:3: note: in expansion of macro 'DEPACK'
  357 |   DEPACK(d1,2);
      |   ^~~~~~
hash/ripemd160_sse.cpp:307:27: error: request for member 'm128i_u32' in 's[4]', which is of non-class type '__m128i'
  307 | ((uint32_t *)d)[4] = s[4].m128i_u32[i];
      |                           ^~~~~~~~~
hash/ripemd160_sse.cpp:357:3: note: in expansion of macro 'DEPACK'
  357 |   DEPACK(d1,2);
      |   ^~~~~~
hash/ripemd160_sse.cpp:303:27: error: request for member 'm128i_u32' in 's[0]', which is of non-class type '__m128i'
  303 | ((uint32_t *)d)[0] = s[0].m128i_u32[i]; \
      |                           ^~~~~~~~~
hash/ripemd160_sse.cpp:358:3: note: in expansion of macro 'DEPACK'
  358 |   DEPACK(d2,1);
      |   ^~~~~~
hash/ripemd160_sse.cpp:304:27: error: request for member 'm128i_u32' in 's[1]', which is of non-class type '__m128i'
  304 | ((uint32_t *)d)[1] = s[1].m128i_u32[i]; \
      |                           ^~~~~~~~~
hash/ripemd160_sse.cpp:358:3: note: in expansion of macro 'DEPACK'
  358 |   DEPACK(d2,1);
      |   ^~~~~~
hash/ripemd160_sse.cpp:305:27: error: request for member 'm128i_u32' in 's[2]', which is of non-class type '__m128i'
  305 | ((uint32_t *)d)[2] = s[2].m128i_u32[i]; \
      |                           ^~~~~~~~~
hash/ripemd160_sse.cpp:358:3: note: in expansion of macro 'DEPACK'
  358 |   DEPACK(d2,1);
      |   ^~~~~~
hash/ripemd160_sse.cpp:306:27: error: request for member 'm128i_u32' in 's[3]', which is of non-class type '__m128i'
  306 | ((uint32_t *)d)[3] = s[3].m128i_u32[i]; \
      |                           ^~~~~~~~~
hash/ripemd160_sse.cpp:358:3: note: in expansion of macro 'DEPACK'
  358 |   DEPACK(d2,1);
      |   ^~~~~~
hash/ripemd160_sse.cpp:307:27: error: request for member 'm128i_u32' in 's[4]', which is of non-class type '__m128i'
  307 | ((uint32_t *)d)[4] = s[4].m128i_u32[i];
      |                           ^~~~~~~~~
hash/ripemd160_sse.cpp:358:3: note: in expansion of macro 'DEPACK'
  358 |   DEPACK(d2,1);
      |   ^~~~~~
hash/ripemd160_sse.cpp:303:27: error: request for member 'm128i_u32' in 's[0]', which is of non-class type '__m128i'
  303 | ((uint32_t *)d)[0] = s[0].m128i_u32[i]; \
      |                           ^~~~~~~~~
hash/ripemd160_sse.cpp:359:3: note: in expansion of macro 'DEPACK'
  359 |   DEPACK(d3,0);
      |   ^~~~~~
hash/ripemd160_sse.cpp:304:27: error: request for member 'm128i_u32' in 's[1]', which is of non-class type '__m128i'
  304 | ((uint32_t *)d)[1] = s[1].m128i_u32[i]; \
      |                           ^~~~~~~~~
hash/ripemd160_sse.cpp:359:3: note: in expansion of macro 'DEPACK'
  359 |   DEPACK(d3,0);
      |   ^~~~~~
hash/ripemd160_sse.cpp:305:27: error: request for member 'm128i_u32' in 's[2]', which is of non-class type '__m128i'
  305 | ((uint32_t *)d)[2] = s[2].m128i_u32[i]; \
      |                           ^~~~~~~~~
hash/ripemd160_sse.cpp:359:3: note: in expansion of macro 'DEPACK'
  359 |   DEPACK(d3,0);
      |   ^~~~~~
hash/ripemd160_sse.cpp:306:27: error: request for member 'm128i_u32' in 's[3]', which is of non-class type '__m128i'
  306 | ((uint32_t *)d)[3] = s[3].m128i_u32[i]; \
      |                           ^~~~~~~~~
hash/ripemd160_sse.cpp:359:3: note: in expansion of macro 'DEPACK'
  359 |   DEPACK(d3,0);
      |   ^~~~~~
hash/ripemd160_sse.cpp:307:27: error: request for member 'm128i_u32' in 's[4]', which is of non-class type '__m128i'
  307 | ((uint32_t *)d)[4] = s[4].m128i_u32[i];
      |                           ^~~~~~~~~
hash/ripemd160_sse.cpp:359:3: note: in expansion of macro 'DEPACK'
  359 |   DEPACK(d3,0);
      |   ^~~~~~
mingw32-make: *** [Makefile:18: default] Error 1
albertobsd commented 2 years ago

I need to check this closely, there are others users that actually report this.

Regards!

MajMcCloud commented 2 years ago

@albertobsd Having the same issue sadly. Using Msys2 on Windows10 which worked with mingw32/64 before fine. But the latest didn't. I also added some fixes for Windows. In some files you have to add the line:

define __STDC_FORMAT_MACROS 1

When I can help you with anything, let me know.

For me it happens only in that hash/ripemd160_sse.cpp file

MajMcCloud commented 2 years ago

I made it an double array like here, and it compiles correctly. Mabe we had to try if it works correctly as well:

image

to:

image

albertobsd commented 2 years ago

Excellent, thanks for sharing, to check if it is working welll you can run this test:

./keyhunt -m rmd160 -f tests/1to32.rmd -r 1:FFFFFFFF -l compress

The will check if the rmd output is OK or not, is in the readme https://github.com/albertobsd/keyhunt#rmd160-mode

Regards!

MajMcCloud commented 2 years ago

Excellent, thanks for sharing, to check if it is working welll you can run this test:

./keyhunt -m rmd160 -f tests/1to32.rmd -r 1:FFFFFFFF -l compress

The will check if the rmd output is OK or not, is in the readme https://github.com/albertobsd/keyhunt#rmd160-mode

Regards!

Sadly i can't test it, cause it seems there are other issues as well. So after changing what I have stated above, there are rising multiple different errors from other files, so no easy way for now to fix them.