Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* 1b8719b9969ba88d66c3eb20d2e4a52aa5e9eb80cfedf3c4dae49a09c63ad096 */
- /* Compile with -lgmp and -lcrypto. */
- #include <getopt.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <gmp.h>
- #include <openssl/ecdsa.h>
- #include <openssl/obj_mac.h>
- #include <openssl/ripemd.h>
- #include <openssl/sha.h>
- #include <openssl/x509v3.h>
- static char const *base58_charset = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
- char *base58_encode(const unsigned char *pbegin, const unsigned char *pend)
- {
- unsigned char const *p;
- char *retval;
- int i, n_nonzero;
- mpz_t n;
- mpz_init2(n, (pend - pbegin) * 8);
- mpz_import(n, (pend - pbegin), 1, 1, 0, 0, pbegin);
- // Expected size increase from base58 conversion is approximately 137%
- // use 138% to be safe
- retval = malloc((pend - pbegin) * 138 / 100 + 1);
- for (i = 0; mpz_cmp_ui(n, 0) > 0; i++) {
- unsigned long r;
- r = mpz_fdiv_q_ui(n, n, 58);
- retval[i] = base58_charset[r];
- }
- mpz_clear(n);
- // Leading zeroes encoded as base58 zeros
- for (p = pbegin; p < pend && *p == 0; p++) {
- retval[i++] = base58_charset[0];
- }
- retval[i] = 0;
- // Convert little endian to big endian
- for (n_nonzero = i, i = 0; i < n_nonzero/2; i++) {
- unsigned char t = retval[i];
- retval[i] = retval[n_nonzero-1 - i];
- retval[n_nonzero-1 - i] = t;
- }
- return retval;
- }
- static void hash160(unsigned char const *pubkey, size_t pubkey_len, unsigned char *md)
- {
- unsigned char pubkey_sha256[32];
- SHA256(pubkey, pubkey_len, pubkey_sha256);
- RIPEMD160(pubkey_sha256, 32, md);
- }
- void base58_check_pad(unsigned char *payload_extended, size_t payload_len, unsigned char prefix)
- {
- unsigned char buf_sha256[32];
- /* Network ID. */
- payload_extended[0] = prefix;
- /* Check code: first four bytes of SHA256^2(extended hash160). */
- SHA256(payload_extended, 1 + payload_len, buf_sha256);
- SHA256(buf_sha256, 32, buf_sha256);
- memcpy(1 + payload_extended + payload_len, buf_sha256, 4);
- }
- int generate_key(unsigned char const *seed, size_t seed_len, point_conversion_form_t conv,
- unsigned char **privkey_bytes, unsigned char *md)
- {
- BIGNUM bn_seed;
- BN_CTX *ctx;
- EC_KEY *key;
- const EC_GROUP *group;
- EC_POINT *pubkey = NULL;
- unsigned char *pubkey_bytes = NULL;
- int pubkey_len, privkey_len = -1;
- BN_init(&bn_seed);
- BN_bin2bn(seed, seed_len, &bn_seed);
- ctx = BN_CTX_new();
- if (!ctx) {
- return privkey_len;
- }
- key = EC_KEY_new_by_curve_name(NID_secp256k1);
- group = EC_KEY_get0_group(key);
- pubkey = EC_POINT_new(group);
- if (!pubkey) {
- goto err;
- }
- if (!EC_POINT_mul(group, pubkey, &bn_seed, NULL, NULL, ctx)) {
- goto err;
- }
- EC_KEY_set_private_key(key, &bn_seed);
- EC_KEY_set_public_key(key, pubkey);
- EC_KEY_set_conv_form(key, conv);
- pubkey_len = i2o_ECPublicKey(key, &pubkey_bytes);
- privkey_len = i2d_ECPrivateKey(key, privkey_bytes);
- hash160(pubkey_bytes, pubkey_len, md);
- OPENSSL_free(pubkey_bytes);
- err:
- if (pubkey) {
- EC_POINT_free(pubkey);
- }
- BN_CTX_free(ctx);
- EC_KEY_free(key);
- return privkey_len;
- }
- int main(int argc, char *argv[])
- {
- point_conversion_form_t convform = POINT_CONVERSION_UNCOMPRESSED;
- unsigned char *pubkey_prefix = NULL;
- long pubkey_prefix_len;
- int verbose = 0;
- int i;
- while (1) {
- int c;
- c = getopt(argc, argv, "cs:v");
- if (c == -1) {
- break;
- }
- switch (c) {
- case 'c':
- convform = POINT_CONVERSION_COMPRESSED;
- break;
- case 's':
- pubkey_prefix = string_to_hex(optarg, &pubkey_prefix_len);
- break;
- case 'v':
- verbose++;
- break;
- default:
- fprintf(stderr, "Usage: %s [-c] [SEED]\n", argv[0]);
- exit(1);
- break;
- }
- }
- for (i = optind; i < argc; i++) {
- unsigned char pubkey_hash160[1 + 20 + 4], seed_hash[32];
- unsigned char *privkey_extended;
- unsigned char *privkey_bytes = NULL;
- char const *seed;
- char *address;
- int privkey_len;
- seed = argv[i];
- SHA256((unsigned char const *) seed, strlen(seed), seed_hash);
- privkey_len = generate_key(seed_hash, 32, convform, &privkey_bytes, pubkey_hash160 + 1);
- if (pubkey_prefix) {
- if (memcmp(pubkey_hash160 + 1, pubkey_prefix, pubkey_prefix_len < 20 ? pubkey_prefix_len : 20) != 0) {
- continue;
- }
- }
- if (verbose) {
- address = hex_to_string(seed_hash, 32);
- printf("Seed hash = %s\n", address);
- OPENSSL_free(address);
- privkey_extended = malloc(1 + privkey_len + 1 + 4);
- memcpy(privkey_extended + 1, seed_hash, 32);
- if (convform == POINT_CONVERSION_COMPRESSED) {
- privkey_extended[1 + 32] = 0x01;
- }
- base58_check_pad(privkey_extended, 32 + (convform == POINT_CONVERSION_COMPRESSED), 0x80);
- address = base58_encode(privkey_extended, 1 + privkey_extended + (convform == POINT_CONVERSION_COMPRESSED) + 32 + 4);
- printf("Privkey (WIF) = %s\n", address);
- free(address);
- free(privkey_extended);
- address = hex_to_string(privkey_bytes, privkey_len);
- printf("Privkey (DER) = %s\n", address);
- OPENSSL_free(address);
- } else {
- printf("Seed = %s, ", seed);
- }
- address = hex_to_string(pubkey_hash160 + 1, 20);
- printf("Pubkey hash = %s\n", address);
- OPENSSL_free(address);
- if (verbose) {
- base58_check_pad(pubkey_hash160, 20, 0);
- address = base58_encode(pubkey_hash160, 1 + pubkey_hash160 + 20 + 4);
- printf("%s\n", address);
- free(address);
- }
- }
- if (pubkey_prefix) {
- OPENSSL_free(pubkey_prefix);
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement