From 46258a5c3c3298eb059270ccc87beb10cdf6e297 Mon Sep 17 00:00:00 2001 From: RyanC Date: Wed, 7 Sep 2016 18:06:41 -0700 Subject: [PATCH 1/4] move sha256 asm into subdirectory --- Makefile | 4 ++-- sha256-avx-asm.S => sha256/sha256-avx-asm.S | 0 sha256-avx2-asm.S => sha256/sha256-avx2-asm.S | 0 sha256-ni-asm.S => sha256/sha256-ni-asm.S | 0 sha256-ssse3-asm.S => sha256/sha256-ssse3-asm.S | 0 5 files changed, 2 insertions(+), 2 deletions(-) rename sha256-avx-asm.S => sha256/sha256-avx-asm.S (100%) rename sha256-avx2-asm.S => sha256/sha256-avx2-asm.S (100%) rename sha256-ni-asm.S => sha256/sha256-ni-asm.S (100%) rename sha256-ssse3-asm.S => sha256/sha256-ssse3-asm.S (100%) diff --git a/Makefile b/Makefile index dc07fe2..ba47f9a 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,7 @@ OBJS=vanitygen.o base58.o rmd160.o sha256.o ifeq ($(shell uname -m),x86_64) CFLAGS := -march=native $(CFLAGS) - OBJS += sha256-avx-asm.o sha256-avx2-asm.o sha256-ssse3-asm.o sha256-ni-asm.o + OBJS += sha256/sha256-avx-asm.o sha256/sha256-avx2-asm.o sha256/sha256-ssse3-asm.o sha256/sha256-ni-asm.o else ifeq ($(shell uname -m),i686) CFLAGS := -march=native $(CFLAGS) endif @@ -20,7 +20,7 @@ install: all cp --remove-destination -p vanitygen /usr/local/bin/ clean: - rm -f vanitygen *.o + rm -f vanitygen *.o sha256/*.o distclean: clean $(MAKE) -C secp256k1 distclean diff --git a/sha256-avx-asm.S b/sha256/sha256-avx-asm.S similarity index 100% rename from sha256-avx-asm.S rename to sha256/sha256-avx-asm.S diff --git a/sha256-avx2-asm.S b/sha256/sha256-avx2-asm.S similarity index 100% rename from sha256-avx2-asm.S rename to sha256/sha256-avx2-asm.S diff --git a/sha256-ni-asm.S b/sha256/sha256-ni-asm.S similarity index 100% rename from sha256-ni-asm.S rename to sha256/sha256-ni-asm.S diff --git a/sha256-ssse3-asm.S b/sha256/sha256-ssse3-asm.S similarity index 100% rename from sha256-ssse3-asm.S rename to sha256/sha256-ssse3-asm.S From db150ebefdba1a4e773d6addd1b66b911f08babb Mon Sep 17 00:00:00 2001 From: RyanC Date: Wed, 7 Sep 2016 18:09:51 -0700 Subject: [PATCH 2/4] fix build issues when gcc doesn't know sha256-ni --- Makefile | 2 ++ sha256.c | 13 +++++++++---- sha256/sha256-avx-asm.S | 6 ++++++ sha256/sha256-avx-stub.S | 18 ++++++++++++++++++ sha256/sha256-avx2-asm.S | 6 ++++++ sha256/sha256-avx2-stub.S | 18 ++++++++++++++++++ sha256/sha256-ni-asm.S | 6 ++++++ sha256/sha256-ni-stub.S | 18 ++++++++++++++++++ sha256/sha256-ssse3-asm.S | 6 ++++++ sha256/sha256-ssse3-stub.S | 18 ++++++++++++++++++ 10 files changed, 107 insertions(+), 4 deletions(-) create mode 100644 sha256/sha256-avx-stub.S create mode 100644 sha256/sha256-avx2-stub.S create mode 100644 sha256/sha256-ni-stub.S create mode 100644 sha256/sha256-ssse3-stub.S diff --git a/Makefile b/Makefile index ba47f9a..d96e9b2 100644 --- a/Makefile +++ b/Makefile @@ -25,6 +25,8 @@ clean: distclean: clean $(MAKE) -C secp256k1 distclean +sha256/sha256-%-asm.o: sha256/sha256-%-asm.S sha256/sha256-%-stub.S + $(CC) -c $< -o $@ >/dev/null 2>/dev/null || $(CC) -c $(subst asm,stub,$<) -o $@ vanitygen: $(OBJS) diff --git a/sha256.c b/sha256.c index b432a44..14aa8f0 100644 --- a/sha256.c +++ b/sha256.c @@ -9,6 +9,11 @@ extern void sha256_transform_avx(u32 *digest, const char *data, u64 nblk); extern void sha256_transform_rorx(u32 *digest, const char *data, u64 nblk); extern void sha256_ni_transform(u32 *digest, const char *data, u64 nblk); +extern int sha256_ssse3_built(); +extern int sha256_avx_built(); +extern int sha256_rorx_built(); +extern int sha256_ni_built(); + static void (*sha256_transform_func)(u32 *digest, const char *data, u64 nblk)= sha256_transform; @@ -182,13 +187,13 @@ void sha256_register(bool verbose) cpuid(0, 0, eax, ebx, ecx, edx); if(eax >= 7) { cpuid(7, 0, eax, ebx, ecx, edx); - if(ebx & (1 << 29)) { + if(sha256_ni_built() && ebx & (1 << 29)) { if(verbose) printf("Intel SHA-NI enabled.\n"); sha256_transform_func=sha256_ni_transform; return; } - if((ebx & (1 << 8)) && (ebx & (1 << 5))) { + if(sha256_rorx_built() && (ebx & (1 << 8)) && (ebx & (1 << 5))) { if(verbose) printf("Intel AVX2 enabled.\n"); sha256_transform_func=sha256_transform_rorx; @@ -197,13 +202,13 @@ void sha256_register(bool verbose) } cpuid(1, 0, eax, ebx, ecx, edx); - if(ecx & (1 << 28)) { + if(sha256_avx_built() && ecx & (1 << 28)) { if(verbose) printf("Intel AVX enabled.\n"); sha256_transform_func=sha256_transform_avx; return; } - if(ecx & (1 << 9)) { + if(sha256_ssse3_built() && ecx & (1 << 9)) { if(verbose) printf("Intel SSSE3 enabled.\n"); sha256_transform_func=sha256_transform_ssse3; diff --git a/sha256/sha256-avx-asm.S b/sha256/sha256-avx-asm.S index 23830f7..a4e99ce 100644 --- a/sha256/sha256-avx-asm.S +++ b/sha256/sha256-avx-asm.S @@ -468,6 +468,12 @@ done_hash: ret ENDPROC(sha256_transform_avx) +ENTRY(sha256_avx_built) + xor %eax,%eax + inc %eax + ret +ENDPROC(sha256_avx_built) + .data .align 64 K256: diff --git a/sha256/sha256-avx-stub.S b/sha256/sha256-avx-stub.S new file mode 100644 index 0000000..3cbff1b --- /dev/null +++ b/sha256/sha256-avx-stub.S @@ -0,0 +1,18 @@ +#define ENTRY(name) \ + .globl name; \ + .align 4,0x90; \ + name: + +#define ENDPROC(name) \ + .type name, @function; \ + +.text +.align 32 +ENTRY(sha256_transform_avx) + ret +ENDPROC(sha256_transform_avx) + +ENTRY(sha256_avx_built) + xor %eax,%eax + ret +ENDPROC(sha256_avx_built) diff --git a/sha256/sha256-avx2-asm.S b/sha256/sha256-avx2-asm.S index b0c7a54..99082a8 100644 --- a/sha256/sha256-avx2-asm.S +++ b/sha256/sha256-avx2-asm.S @@ -728,6 +728,12 @@ done_hash: ret ENDPROC(sha256_transform_rorx) +ENTRY(sha256_rorx_built) + xor %eax,%eax + inc %eax + ret +ENDPROC(sha256_rorx_built) + .data .align 64 K256: diff --git a/sha256/sha256-avx2-stub.S b/sha256/sha256-avx2-stub.S new file mode 100644 index 0000000..41ba131 --- /dev/null +++ b/sha256/sha256-avx2-stub.S @@ -0,0 +1,18 @@ +#define ENTRY(name) \ + .globl name; \ + .align 4,0x90; \ + name: + +#define ENDPROC(name) \ + .type name, @function; \ + +.text +.align 32 +ENTRY(sha256_transform_rorx) + ret +ENDPROC(sha256_transform_rorx) + +ENTRY(sha256_rorx_built) + xor %eax,%eax + ret +ENDPROC(sha256_rorx_built) diff --git a/sha256/sha256-ni-asm.S b/sha256/sha256-ni-asm.S index 9d92b2c..4e8bff6 100644 --- a/sha256/sha256-ni-asm.S +++ b/sha256/sha256-ni-asm.S @@ -335,6 +335,12 @@ ENTRY(sha256_ni_transform) ret ENDPROC(sha256_ni_transform) +ENTRY(sha256_ni_built) + xor %eax,%eax + inc %eax + ret +ENDPROC(sha256_ni_built) + .data .align 64 K256: diff --git a/sha256/sha256-ni-stub.S b/sha256/sha256-ni-stub.S new file mode 100644 index 0000000..2bf3ee5 --- /dev/null +++ b/sha256/sha256-ni-stub.S @@ -0,0 +1,18 @@ +#define ENTRY(name) \ + .globl name; \ + .align 4,0x90; \ + name: + +#define ENDPROC(name) \ + .type name, @function; \ + +.text +.align 32 +ENTRY(sha256_ni_transform) + ret +ENDPROC(sha256_ni_transform) + +ENTRY(sha256_ni_built) + xor %eax,%eax + ret +ENDPROC(sha256_ni_built) diff --git a/sha256/sha256-ssse3-asm.S b/sha256/sha256-ssse3-asm.S index dca21c6..f8bb0e6 100644 --- a/sha256/sha256-ssse3-asm.S +++ b/sha256/sha256-ssse3-asm.S @@ -480,6 +480,12 @@ done_hash: ret ENDPROC(sha256_transform_ssse3) +ENTRY(sha256_ssse3_built) + xor %eax,%eax + inc %eax + ret +ENDPROC(sha256_ssse3_built) + .data .align 64 K256: diff --git a/sha256/sha256-ssse3-stub.S b/sha256/sha256-ssse3-stub.S new file mode 100644 index 0000000..1d43d4b --- /dev/null +++ b/sha256/sha256-ssse3-stub.S @@ -0,0 +1,18 @@ +#define ENTRY(name) \ + .globl name; \ + .align 4,0x90; \ + name: + +#define ENDPROC(name) \ + .type name, @function; \ + +.text +.align 32 +ENTRY(sha256_transform_ssse3) + ret +ENDPROC(sha256_transform_ssse3) + +ENTRY(sha256_ssse3_built) + xor %eax,%eax + ret +ENDPROC(sha256_ssse3_built) From 5a71fcb69a2ed106ccb12467a7f9afdd7a29890e Mon Sep 17 00:00:00 2001 From: RyanC Date: Wed, 7 Sep 2016 18:10:16 -0700 Subject: [PATCH 3/4] use stderr for SHA256 engine status --- sha256.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sha256.c b/sha256.c index 14aa8f0..cbb9452 100644 --- a/sha256.c +++ b/sha256.c @@ -189,13 +189,13 @@ void sha256_register(bool verbose) cpuid(7, 0, eax, ebx, ecx, edx); if(sha256_ni_built() && ebx & (1 << 29)) { if(verbose) - printf("Intel SHA-NI enabled.\n"); + fprintf(stderr, "SHA256: Intel SHA-NI enabled.\n"); sha256_transform_func=sha256_ni_transform; return; } if(sha256_rorx_built() && (ebx & (1 << 8)) && (ebx & (1 << 5))) { if(verbose) - printf("Intel AVX2 enabled.\n"); + fprintf(stderr, "SHA256: Intel AVX2 enabled.\n"); sha256_transform_func=sha256_transform_rorx; return; } @@ -204,13 +204,13 @@ void sha256_register(bool verbose) cpuid(1, 0, eax, ebx, ecx, edx); if(sha256_avx_built() && ecx & (1 << 28)) { if(verbose) - printf("Intel AVX enabled.\n"); + fprintf(stderr, "SHA256: Intel AVX enabled.\n"); sha256_transform_func=sha256_transform_avx; return; } if(sha256_ssse3_built() && ecx & (1 << 9)) { if(verbose) - printf("Intel SSSE3 enabled.\n"); + fprintf(stderr, "SHA256: Intel SSSE3 enabled.\n"); sha256_transform_func=sha256_transform_ssse3; return; } From da4f222126661a5c10a91a3b4165bd1d5a405a7e Mon Sep 17 00:00:00 2001 From: RyanC Date: Wed, 7 Sep 2016 18:29:48 -0700 Subject: [PATCH 4/4] add split key generation --- vanitygen.c | 54 ++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 45 insertions(+), 9 deletions(-) diff --git a/vanitygen.c b/vanitygen.c index 12e0186..a6b0484 100644 --- a/vanitygen.c +++ b/vanitygen.c @@ -46,6 +46,9 @@ static double difficulty; /* Per-thread hash counter */ static u64 *thread_count; +/* Public Key for split key generation */ +static u8 split_pub_bytes[65]; + /* Socket pair for sending up results */ static int sock[2]; @@ -73,7 +76,9 @@ static bool verify_key(const u8 result[52]); int main(int argc, char *argv[]) { char *arg; - int i, j, digits, parent_pid, ncpus=get_nprocs_conf(), threads=ncpus; + int i, j, k, digits, parent_pid, ncpus=get_nprocs_conf(), threads=ncpus; + + split_pub_bytes[0] = 0; /* Process command-line arguments */ for(i=1;i < argc;i++) { @@ -81,6 +86,17 @@ int main(int argc, char *argv[]) break; for(j=1;argv[i][j];j++) { switch(argv[i][j]) { + case 'P': /* Public Key */ + parse_arg(); + if(strlen(arg) != 130 && strlen(arg) != 66) { + fprintf(stderr, "invalid public key length\n"); + goto error; + } + for(k = 0; k < 65; k++) { + if(arg[k*2] == 0) { break; } + sscanf(&arg[k*2], "%2hhx", &split_pub_bytes[k]); + } + goto end_arg; case 'k': /* Keep Going */ keep_going=1; break; @@ -133,10 +149,10 @@ int main(int argc, char *argv[]) if(verbose) { digits=(num_patterns > 999)?4:(num_patterns > 99)?3:(num_patterns > 9)?2:1; for(i=0;i < num_patterns;i++) { - printf("P%0*d High limit: ", digits, i+1); + printf("P%0*d High limit: ", digits, i+1); for(j=0;j < 20;j++) printf("%02x", patterns[i].high[j]); - printf("\nP%0*d Low limit: ", digits, i+1); + printf("\nP%0*d Low limit: ", digits, i+1); for(j=0;j < 20;j++) printf("%02x", patterns[i].low[j]); printf("\n"); @@ -304,12 +320,12 @@ static void announce_result(const u8 result[52]) /* Display matching keys in hexadecimal */ if(verbose) { - printf("Private match: "); + printf("Private match: "); for(j=0;j < 32;j++) printf("%02x", result[j]); printf("\n"); - printf("Public match: "); + printf("Public match: "); for(j=0;j < 20;j++) printf("%02x", result[j+32]); printf("\n"); @@ -332,7 +348,11 @@ static void announce_result(const u8 result[52]) memcpy(priv_block+34, checksum, 4); b58enc(wif, priv_block, 38); - printf("PrivKey (WIF): %s\n", wif); + if(split_pub_bytes[0]) { + printf("PrivPart (WIF): %s\n", wif); + } else { + printf("PrivKey (WIF): %s\n", wif); + } /* Convert Public Key to Compressed WIF */ @@ -346,7 +366,7 @@ static void announce_result(const u8 result[52]) memcpy(pub_block+21, checksum, 4); b58enc(wif, pub_block, 25); - printf("PubKey (WIF): %s\n", wif); + printf("Address: %s\n", wif); /* Exit if we only requested one key */ if(!keep_going) @@ -608,7 +628,8 @@ static void engine(int thread) secp256k1_context *sec_ctx; secp256k1_scalar scalar_key, scalar_one; secp256k1_gej temp; - secp256k1_ge offset; + secp256k1_ge offset, split_ge; + secp256k1_pubkey split_pub; cpu_set_t cpuset; align8 u8 sha_block[64], rmd_block[64], result[52], *pubkey=result+32; @@ -667,7 +688,19 @@ static void engine(int thread) privkey[3]=be64(privkey[3]); /* Create group elements for both the random private key and the value 1 */ - secp256k1_ecmult_gen(&sec_ctx->ecmult_gen_ctx, &base[STEP-1], &scalar_key); + if(split_pub_bytes[0]) { + /* Set up for split key generation */ + if(!secp256k1_ec_pubkey_parse(sec_ctx, &split_pub, (unsigned char *)&split_pub_bytes, split_pub_bytes[0] < 4 ? 33 : 65)) { + fprintf(stderr, "invalid public key!\n"); + return; + } + secp256k1_pubkey_load(sec_ctx, &split_ge, &split_pub); + secp256k1_ecmult_gen(&sec_ctx->ecmult_gen_ctx, &temp, &scalar_key); + secp256k1_gej_add_ge_var(&base[STEP-1], &temp, &split_ge, NULL); + } else { + /* Set up for standalone key generation */ + secp256k1_ecmult_gen(&sec_ctx->ecmult_gen_ctx, &base[STEP-1], &scalar_key); + } secp256k1_ecmult_gen(&sec_ctx->ecmult_gen_ctx, &temp, &scalar_one); secp256k1_ge_set_gej_var(&offset, &temp); @@ -741,6 +774,9 @@ static bool verify_key(const u8 result[52]) align8 u8 sha_block[64], rmd_block[64], pubkey[20]; int ret, overflow; + /* TODO: verification for split key generation */ + if(split_pub_bytes[0]) { return 1; } + /* Set up sha256 block for an input length of 33 bytes */ sha256_prepare(sha_block, 33);