Created
April 5, 2024 15:19
-
-
Save gnremy/a3a6b1d95cbd583533d3076a36d25537 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// gcc -DTEST_MAIN -march=native -msse4.1 crack_intrin.c -o firecracker | |
#include <stdio.h> | |
#include <stdint.h> | |
#include <openssl/sha.h> | |
#include <string.h> | |
#include <pthread.h> | |
#include <stdlib.h> | |
#define NUM_THREADS 32 | |
static uint32_t target[2] = {0x7e071fd9, 0xb023ed8f}; // un-base64'd | |
// https://github.com/noloader/SHA-Intrinsics/blob/master/sha256-x86.c | |
/* Include the GCC super header */ | |
#if defined(__GNUC__) | |
# include <stdint.h> | |
# include <x86intrin.h> | |
#endif | |
/* Microsoft supports Intel SHA ACLE extensions as of Visual Studio 2015 */ | |
#if defined(_MSC_VER) | |
# include <immintrin.h> | |
# define WIN32_LEAN_AND_MEAN | |
# include <Windows.h> | |
typedef UINT32 uint32_t; | |
typedef UINT8 uint8_t; | |
#endif | |
/* Process multiple blocks. The caller is responsible for setting the initial */ | |
/* state, and the caller is responsible for padding the final block. */ | |
static void sha256_process_x86(uint32_t state[8], const uint8_t data[], uint32_t length) | |
{ | |
__m128i STATE0, STATE1; | |
__m128i MSG, TMP; | |
__m128i MSG0, MSG1, MSG2, MSG3; | |
__m128i ABEF_SAVE, CDGH_SAVE; | |
const __m128i MASK = _mm_set_epi64x(0x0c0d0e0f08090a0bULL, 0x0405060700010203ULL); | |
/* Load initial values */ | |
TMP = _mm_loadu_si128((const __m128i*) &state[0]); | |
STATE1 = _mm_loadu_si128((const __m128i*) &state[4]); | |
TMP = _mm_shuffle_epi32(TMP, 0xB1); /* CDAB */ | |
STATE1 = _mm_shuffle_epi32(STATE1, 0x1B); /* EFGH */ | |
STATE0 = _mm_alignr_epi8(TMP, STATE1, 8); /* ABEF */ | |
STATE1 = _mm_blend_epi16(STATE1, TMP, 0xF0); /* CDGH */ | |
while (length >= 64) | |
{ | |
/* Save current state */ | |
ABEF_SAVE = STATE0; | |
CDGH_SAVE = STATE1; | |
/* Rounds 0-3 */ | |
MSG = _mm_loadu_si128((const __m128i*) (data+0)); | |
MSG0 = _mm_shuffle_epi8(MSG, MASK); | |
MSG = _mm_add_epi32(MSG0, _mm_set_epi64x(0xE9B5DBA5B5C0FBCFULL, 0x71374491428A2F98ULL)); | |
STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG); | |
MSG = _mm_shuffle_epi32(MSG, 0x0E); | |
STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG); | |
/* Rounds 4-7 */ | |
MSG1 = _mm_loadu_si128((const __m128i*) (data+16)); | |
MSG1 = _mm_shuffle_epi8(MSG1, MASK); | |
MSG = _mm_add_epi32(MSG1, _mm_set_epi64x(0xAB1C5ED5923F82A4ULL, 0x59F111F13956C25BULL)); | |
STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG); | |
MSG = _mm_shuffle_epi32(MSG, 0x0E); | |
STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG); | |
MSG0 = _mm_sha256msg1_epu32(MSG0, MSG1); | |
/* Rounds 8-11 */ | |
MSG2 = _mm_loadu_si128((const __m128i*) (data+32)); | |
MSG2 = _mm_shuffle_epi8(MSG2, MASK); | |
MSG = _mm_add_epi32(MSG2, _mm_set_epi64x(0x550C7DC3243185BEULL, 0x12835B01D807AA98ULL)); | |
STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG); | |
MSG = _mm_shuffle_epi32(MSG, 0x0E); | |
STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG); | |
MSG1 = _mm_sha256msg1_epu32(MSG1, MSG2); | |
/* Rounds 12-15 */ | |
MSG3 = _mm_loadu_si128((const __m128i*) (data+48)); | |
MSG3 = _mm_shuffle_epi8(MSG3, MASK); | |
MSG = _mm_add_epi32(MSG3, _mm_set_epi64x(0xC19BF1749BDC06A7ULL, 0x80DEB1FE72BE5D74ULL)); | |
STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG); | |
TMP = _mm_alignr_epi8(MSG3, MSG2, 4); | |
MSG0 = _mm_add_epi32(MSG0, TMP); | |
MSG0 = _mm_sha256msg2_epu32(MSG0, MSG3); | |
MSG = _mm_shuffle_epi32(MSG, 0x0E); | |
STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG); | |
MSG2 = _mm_sha256msg1_epu32(MSG2, MSG3); | |
/* Rounds 16-19 */ | |
MSG = _mm_add_epi32(MSG0, _mm_set_epi64x(0x240CA1CC0FC19DC6ULL, 0xEFBE4786E49B69C1ULL)); | |
STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG); | |
TMP = _mm_alignr_epi8(MSG0, MSG3, 4); | |
MSG1 = _mm_add_epi32(MSG1, TMP); | |
MSG1 = _mm_sha256msg2_epu32(MSG1, MSG0); | |
MSG = _mm_shuffle_epi32(MSG, 0x0E); | |
STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG); | |
MSG3 = _mm_sha256msg1_epu32(MSG3, MSG0); | |
/* Rounds 20-23 */ | |
MSG = _mm_add_epi32(MSG1, _mm_set_epi64x(0x76F988DA5CB0A9DCULL, 0x4A7484AA2DE92C6FULL)); | |
STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG); | |
TMP = _mm_alignr_epi8(MSG1, MSG0, 4); | |
MSG2 = _mm_add_epi32(MSG2, TMP); | |
MSG2 = _mm_sha256msg2_epu32(MSG2, MSG1); | |
MSG = _mm_shuffle_epi32(MSG, 0x0E); | |
STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG); | |
MSG0 = _mm_sha256msg1_epu32(MSG0, MSG1); | |
/* Rounds 24-27 */ | |
MSG = _mm_add_epi32(MSG2, _mm_set_epi64x(0xBF597FC7B00327C8ULL, 0xA831C66D983E5152ULL)); | |
STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG); | |
TMP = _mm_alignr_epi8(MSG2, MSG1, 4); | |
MSG3 = _mm_add_epi32(MSG3, TMP); | |
MSG3 = _mm_sha256msg2_epu32(MSG3, MSG2); | |
MSG = _mm_shuffle_epi32(MSG, 0x0E); | |
STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG); | |
MSG1 = _mm_sha256msg1_epu32(MSG1, MSG2); | |
/* Rounds 28-31 */ | |
MSG = _mm_add_epi32(MSG3, _mm_set_epi64x(0x1429296706CA6351ULL, 0xD5A79147C6E00BF3ULL)); | |
STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG); | |
TMP = _mm_alignr_epi8(MSG3, MSG2, 4); | |
MSG0 = _mm_add_epi32(MSG0, TMP); | |
MSG0 = _mm_sha256msg2_epu32(MSG0, MSG3); | |
MSG = _mm_shuffle_epi32(MSG, 0x0E); | |
STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG); | |
MSG2 = _mm_sha256msg1_epu32(MSG2, MSG3); | |
/* Rounds 32-35 */ | |
MSG = _mm_add_epi32(MSG0, _mm_set_epi64x(0x53380D134D2C6DFCULL, 0x2E1B213827B70A85ULL)); | |
STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG); | |
TMP = _mm_alignr_epi8(MSG0, MSG3, 4); | |
MSG1 = _mm_add_epi32(MSG1, TMP); | |
MSG1 = _mm_sha256msg2_epu32(MSG1, MSG0); | |
MSG = _mm_shuffle_epi32(MSG, 0x0E); | |
STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG); | |
MSG3 = _mm_sha256msg1_epu32(MSG3, MSG0); | |
/* Rounds 36-39 */ | |
MSG = _mm_add_epi32(MSG1, _mm_set_epi64x(0x92722C8581C2C92EULL, 0x766A0ABB650A7354ULL)); | |
STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG); | |
TMP = _mm_alignr_epi8(MSG1, MSG0, 4); | |
MSG2 = _mm_add_epi32(MSG2, TMP); | |
MSG2 = _mm_sha256msg2_epu32(MSG2, MSG1); | |
MSG = _mm_shuffle_epi32(MSG, 0x0E); | |
STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG); | |
MSG0 = _mm_sha256msg1_epu32(MSG0, MSG1); | |
/* Rounds 40-43 */ | |
MSG = _mm_add_epi32(MSG2, _mm_set_epi64x(0xC76C51A3C24B8B70ULL, 0xA81A664BA2BFE8A1ULL)); | |
STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG); | |
TMP = _mm_alignr_epi8(MSG2, MSG1, 4); | |
MSG3 = _mm_add_epi32(MSG3, TMP); | |
MSG3 = _mm_sha256msg2_epu32(MSG3, MSG2); | |
MSG = _mm_shuffle_epi32(MSG, 0x0E); | |
STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG); | |
MSG1 = _mm_sha256msg1_epu32(MSG1, MSG2); | |
/* Rounds 44-47 */ | |
MSG = _mm_add_epi32(MSG3, _mm_set_epi64x(0x106AA070F40E3585ULL, 0xD6990624D192E819ULL)); | |
STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG); | |
TMP = _mm_alignr_epi8(MSG3, MSG2, 4); | |
MSG0 = _mm_add_epi32(MSG0, TMP); | |
MSG0 = _mm_sha256msg2_epu32(MSG0, MSG3); | |
MSG = _mm_shuffle_epi32(MSG, 0x0E); | |
STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG); | |
MSG2 = _mm_sha256msg1_epu32(MSG2, MSG3); | |
/* Rounds 48-51 */ | |
MSG = _mm_add_epi32(MSG0, _mm_set_epi64x(0x34B0BCB52748774CULL, 0x1E376C0819A4C116ULL)); | |
STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG); | |
TMP = _mm_alignr_epi8(MSG0, MSG3, 4); | |
MSG1 = _mm_add_epi32(MSG1, TMP); | |
MSG1 = _mm_sha256msg2_epu32(MSG1, MSG0); | |
MSG = _mm_shuffle_epi32(MSG, 0x0E); | |
STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG); | |
MSG3 = _mm_sha256msg1_epu32(MSG3, MSG0); | |
/* Rounds 52-55 */ | |
MSG = _mm_add_epi32(MSG1, _mm_set_epi64x(0x682E6FF35B9CCA4FULL, 0x4ED8AA4A391C0CB3ULL)); | |
STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG); | |
TMP = _mm_alignr_epi8(MSG1, MSG0, 4); | |
MSG2 = _mm_add_epi32(MSG2, TMP); | |
MSG2 = _mm_sha256msg2_epu32(MSG2, MSG1); | |
MSG = _mm_shuffle_epi32(MSG, 0x0E); | |
STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG); | |
/* Rounds 56-59 */ | |
MSG = _mm_add_epi32(MSG2, _mm_set_epi64x(0x8CC7020884C87814ULL, 0x78A5636F748F82EEULL)); | |
STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG); | |
TMP = _mm_alignr_epi8(MSG2, MSG1, 4); | |
MSG3 = _mm_add_epi32(MSG3, TMP); | |
MSG3 = _mm_sha256msg2_epu32(MSG3, MSG2); | |
MSG = _mm_shuffle_epi32(MSG, 0x0E); | |
STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG); | |
/* Rounds 60-63 */ | |
MSG = _mm_add_epi32(MSG3, _mm_set_epi64x(0xC67178F2BEF9A3F7ULL, 0xA4506CEB90BEFFFAULL)); | |
STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG); | |
MSG = _mm_shuffle_epi32(MSG, 0x0E); | |
STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG); | |
/* Combine state */ | |
STATE0 = _mm_add_epi32(STATE0, ABEF_SAVE); | |
STATE1 = _mm_add_epi32(STATE1, CDGH_SAVE); | |
data += 64; | |
length -= 64; | |
} | |
TMP = _mm_shuffle_epi32(STATE0, 0x1B); /* FEBA */ | |
STATE1 = _mm_shuffle_epi32(STATE1, 0xB1); /* DCHG */ | |
STATE0 = _mm_blend_epi16(TMP, STATE1, 0xF0); /* DCBA */ | |
STATE1 = _mm_alignr_epi8(STATE1, TMP, 8); /* ABEF */ | |
/* Save state */ | |
_mm_storeu_si128((__m128i*) &state[0], STATE0); | |
_mm_storeu_si128((__m128i*) &state[4], STATE1); | |
} | |
const unsigned char HEXDIGITS[] = "0123456789abcdef"; | |
struct thread_args { | |
int start; | |
int end; | |
}; | |
void *brute_range(void *args) | |
{ | |
struct thread_args *my_args = args; | |
unsigned char buf[64]; | |
memset(buf, 0, sizeof(buf)); | |
buf[8] = 0x80; | |
buf[63] = 8*8; | |
for (int a=my_args->start; a < my_args->end; a++) { | |
buf[0] = HEXDIGITS[a>>4]; | |
buf[1] = HEXDIGITS[a&15]; | |
//printf("%d\n", a); | |
for (int b=0; b<0x100; b++) { | |
buf[2] = HEXDIGITS[b>>4]; | |
buf[3] = HEXDIGITS[b&15]; | |
for (int c=0; c<0x100; c++) { | |
buf[4] = HEXDIGITS[c>>4]; | |
buf[5] = HEXDIGITS[c&15]; | |
for (int d=0; d<0x100; d++) { | |
buf[6] = HEXDIGITS[d>>4]; | |
buf[7] = HEXDIGITS[d&15]; | |
uint32_t state[8] = { | |
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, | |
0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 | |
}; | |
sha256_process_x86(state, buf, 64); | |
if ((state[0] == target[0]) && (state[1] == target[1])) { | |
buf[8] = 0; | |
printf("Firecracker: %s\n", buf); | |
exit(0); | |
} | |
} | |
} | |
} | |
} | |
} | |
int main(int argc, char* argv[]) | |
{ | |
pthread_t threads[NUM_THREADS]; | |
struct thread_args args[NUM_THREADS]; | |
for (int i=0; i<NUM_THREADS; i++) { | |
args[i].start = (0x100 * i) / NUM_THREADS; | |
args[i].end = (0x100 * (i+1)) / NUM_THREADS; | |
pthread_create(&threads[i], NULL, brute_range, &args[i]); | |
} | |
for (int i=0; i<NUM_THREADS; i++) { | |
pthread_join(threads[i], NULL); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment