keyhunt icon indicating copy to clipboard operation
keyhunt copied to clipboard

Accelerate core functions with SIMD intrinsics

Open chawyehsu opened this issue 3 years ago • 9 comments

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.

chawyehsu avatar Apr 10 '21 11:04 chawyehsu

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 avatar Apr 10 '21 13:04 albertobsd

ok, right know im checking for this change.

albertobsd avatar Oct 16 '21 02:10 albertobsd

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

albertobsd avatar Oct 25 '21 17:10 albertobsd

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

chawyehsu avatar Oct 26 '21 02:10 chawyehsu

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

Regards!

albertobsd avatar Oct 26 '21 03:10 albertobsd

@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 avatar Oct 29 '21 12:10 MajMcCloud

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

MajMcCloud avatar Oct 29 '21 12:10 MajMcCloud

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!

albertobsd avatar Oct 29 '21 17:10 albertobsd

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.

MajMcCloud avatar Oct 29 '21 19:10 MajMcCloud