Guest User

bip38 cracker changes

a guest
Mar 4th, 2014
250
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 10.29 KB | None | 0 0
  1. /* cracker for casascius's contest, details here:
  2.  
  3.    https://bitcointalk.org/index.php?topic=128699.0
  4.  
  5. */
  6.  
  7. #include <stdlib.h>
  8. #include <stdio.h>
  9. #include <string.h>
  10. #include <sys/types.h>
  11. #include <time.h>
  12. #include <glib.h>
  13. #include <openssl/evp.h>
  14. #include <openssl/sha.h>
  15. #include <pthread.h>
  16. #include "scrypt/crypto/crypto_scrypt.h"
  17. #include "ccoin/base58.h"
  18. #include "ccoin/key.h"
  19. #include "ccoin/address.h"
  20.  
  21. #define NUM_THREADS 4
  22.  
  23. void print_hex(char * hex, size_t len) {
  24.     int i;
  25.     for(i=0; i<len; i++) {
  26.         printf("%.02x",(unsigned char)hex[i]);
  27.     }
  28. }
  29.  
  30. #define PASSFACTOR_SIZE 32
  31. #define PASSPHRASE_MAGIC_SIZE 8
  32. #define PASSPHRASE_SIZE (PASSPHRASE_MAGIC_SIZE + OWNERSALT_SIZE + 33)
  33. #define DERIVED_SIZE 64
  34. #define ADDRESSHASH_SIZE 4
  35. #define OWNERSALT_SIZE 8
  36.  
  37. int crack(char * pKey, char * pKey_pass) {
  38.     int i;
  39.     uint8_t passfactor[PASSFACTOR_SIZE];
  40.  
  41.     printf("testing key %s, %s\r\n",pKey, pKey_pass);
  42.  
  43.     GString * b58dec;
  44.     b58dec = base58_decode_check(NULL,pKey);
  45.  
  46.     if(b58dec) {
  47.         /*
  48.         printf("%s", "base58decode of encrypted key: ");
  49.         print_hex(b58dec->str,b58dec->len);
  50.         printf("%s", "\r\n");
  51.         printf("flagByte: %.02x addresshash:%.02x%.02x%.02x%.02x ownersalt:",
  52.             (unsigned char)b58dec->str[2], (unsigned char)b58dec->str[3],
  53.             (unsigned char)b58dec->str[4], (unsigned char)b58dec->str[5],
  54.             (unsigned char)b58dec->str[6]);
  55.         print_hex(&b58dec->str[3+ADDRESSHASH_SIZE], OWNERSALT_SIZE);
  56.         printf("\r\n");
  57.         */
  58.         memset(passfactor,0,PASSFACTOR_SIZE);
  59.         crypto_scrypt( pKey_pass, strlen(pKey_pass),
  60.                        &(b58dec->str[3+ADDRESSHASH_SIZE]), OWNERSALT_SIZE,
  61.                        16384, 8, 8, passfactor, PASSFACTOR_SIZE );
  62.         /*
  63.         printf("%s", "passfactor: ");
  64.         print_hex(passfactor, PASSFACTOR_SIZE);
  65.         printf("%s", "\r\n");
  66.         */
  67.     } else {
  68.         fprintf(stderr,"%s","cannot b58 decode private key.");
  69.         return 1;
  70.         exit(1);
  71.     }
  72.  
  73.     // compute EC point (passpoint) using passfactor
  74.     struct bp_key ec_point;
  75.     if(!bp_key_init(&ec_point)) {
  76.         fprintf(stderr,"%s","cannot init EC point key");
  77.         exit(3);
  78.     }
  79.     if(!bp_key_secret_set(&ec_point,passfactor,PASSFACTOR_SIZE)) {
  80.         fprintf(stderr,"%s","cannot set EC point from passfactor");
  81.         exit(3);
  82.     }
  83.  
  84.     // get the passpoint as bytes
  85.     unsigned char * passpoint;
  86.     unsigned int passpoint_len;
  87.  
  88.     if(!bp_pubkey_get(&ec_point,(void *)&passpoint,&passpoint_len)) {
  89.         fprintf(stderr,"%s","cannot get pubkey for EC point");
  90.         exit(4);
  91.     }
  92.  
  93.     /*
  94.     printf("len is %d, passpoint: ", passpoint_len);
  95.     print_hex(passpoint,passpoint_len);
  96.     printf("%s", "\r\n");
  97.     */
  98.  
  99.     /*
  100.     // check: generate the passphrase
  101.     char passphrase_bytes[PASSPHRASE_SIZE];
  102.     char passphrase_magic[] = { 0x2C, 0xE9, 0xB3, 0xE1, 0xFF, 0x39, 0xE2, 0x53 };
  103.     memset(passphrase_bytes,0,PASSPHRASE_SIZE);
  104.     memcpy(passphrase_bytes, passphrase_magic, PASSPHRASE_MAGIC_SIZE);
  105.     memcpy(passphrase_bytes + PASSPHRASE_MAGIC_SIZE,
  106.         &b58dec->str[3+ADDRESSHASH_SIZE], OWNERSALT_SIZE);
  107.     memcpy(passphrase_bytes + PASSPHRASE_MAGIC_SIZE + OWNERSALT_SIZE,
  108.         passpoint, passpoint_len);
  109.     GString * passphrase_g = base58_encode_check(0,false,
  110.         passphrase_bytes, PASSPHRASE_SIZE);
  111.         printf("Passphrase: %s\r\n\r\n", passphrase_g->str);
  112.     */
  113.  
  114.     // now we need to decrypt seedb
  115.     uint8_t encryptedpart2[16];
  116.     memset(encryptedpart2,0,16);
  117.     memcpy(encryptedpart2,
  118.            &b58dec->str[3 + ADDRESSHASH_SIZE + OWNERSALT_SIZE + 8],16);
  119.     uint8_t encryptedpart1[16];
  120.     memset(encryptedpart1,0,16);
  121.     memcpy(encryptedpart1,
  122.            &b58dec->str[3 + ADDRESSHASH_SIZE + OWNERSALT_SIZE],8);
  123.  
  124.     unsigned char derived[DERIVED_SIZE];
  125.     // get the encryption key for seedb using scrypt
  126.     // with passpoint as the key, salt is addresshash+ownersalt
  127.     unsigned char derived_scrypt_salt[ADDRESSHASH_SIZE + OWNERSALT_SIZE];
  128.     memcpy(derived_scrypt_salt,
  129.            &b58dec->str[3], ADDRESSHASH_SIZE); // copy the addresshash
  130.     memcpy(derived_scrypt_salt+ADDRESSHASH_SIZE,
  131.            &b58dec->str[3+ADDRESSHASH_SIZE], OWNERSALT_SIZE); // copy the ownersalt
  132.     crypto_scrypt( passpoint, passpoint_len,
  133.                    derived_scrypt_salt, ADDRESSHASH_SIZE+OWNERSALT_SIZE,
  134.                    1024, 1, 1, derived, DERIVED_SIZE );
  135.  
  136.     //get decryption key
  137.     unsigned char derivedhalf2[DERIVED_SIZE/2];
  138.     memcpy(derivedhalf2, derived+(DERIVED_SIZE/2), DERIVED_SIZE/2);
  139.  
  140.     unsigned char iv[32];
  141.     memset(iv,0,32);
  142.     EVP_CIPHER_CTX d;
  143.     EVP_CIPHER_CTX_init(&d);
  144.     EVP_DecryptInit_ex(&d, EVP_aes_256_ecb(), NULL, derivedhalf2, iv);
  145.  
  146.     unsigned char unencryptedpart2[32];
  147.     int decrypt_len;
  148.     EVP_DecryptUpdate(&d, unencryptedpart2, &decrypt_len, encryptedpart2, 16);
  149.     EVP_DecryptUpdate(&d, unencryptedpart2, &decrypt_len, encryptedpart2, 16);
  150.     for(i=0; i<16; i++) {
  151.         unencryptedpart2[i] ^= derived[i + 16];
  152.     }
  153.     unsigned char unencryptedpart1[32];
  154.     memcpy(encryptedpart1+8, unencryptedpart2, 8);
  155.     EVP_DecryptUpdate(&d, unencryptedpart1, &decrypt_len, encryptedpart1, 16);
  156.     EVP_DecryptUpdate(&d, unencryptedpart1, &decrypt_len, encryptedpart1, 16);
  157.     for(i=0; i<16; i++) {
  158.         unencryptedpart1[i] ^= derived[i];
  159.     }
  160.  
  161.     // recoved seedb
  162.     unsigned char seedb[24];
  163.     memcpy(seedb, unencryptedpart1, 16);
  164.     memcpy(&(seedb[16]), &(unencryptedpart2[8]), 8);
  165.  
  166.     // turn seedb into factorb (factorb = SHA256(SHA256(seedb)))
  167.     unsigned char factorb[32];
  168.     bu_Hash(factorb, seedb, 24);
  169.  
  170.     // multiply by passfactor (ec_point_pub)
  171.     const EC_GROUP * ec_group = EC_KEY_get0_group(ec_point.k);
  172.     const EC_POINT * ec_point_pub = EC_KEY_get0_public_key(ec_point.k);
  173.     BIGNUM * bn_passfactor = BN_bin2bn(passfactor,32,BN_new());
  174.     BIGNUM * bn_factorb = BN_bin2bn(factorb,32,BN_new());
  175.     BIGNUM * bn_res = BN_new();
  176.     BIGNUM * bn_final = BN_new();
  177.     BIGNUM * bn_n = BN_new();
  178.     BN_CTX * ctx = BN_CTX_new();
  179.     EC_GROUP_get_order(ec_group, bn_n, ctx);
  180.     BN_mul(bn_res, bn_passfactor, bn_factorb, ctx);
  181.     BN_mod(bn_final, bn_res, bn_n, ctx);
  182.  
  183.     unsigned char finalKey[32];
  184.     memset(finalKey, 0, 32);
  185.     int n = BN_bn2bin(bn_final, finalKey);
  186.  
  187.     BN_clear_free(bn_passfactor);
  188.     BN_clear_free(bn_factorb);
  189.     BN_clear_free(bn_res);
  190.     BN_clear_free(bn_n);
  191.     BN_clear_free(bn_final);
  192.  
  193.     // we have a private key! check hash
  194.     /*
  195.     printf("have private key: ");
  196.     print_hex(finalKey, 32);
  197.     printf("%s", "\r\n");
  198.     */
  199.  
  200.     // turn it into a real address
  201.     struct bp_key wallet;
  202.     if(!bp_key_init(&wallet)) {
  203.         fprintf(stderr,"%s","cannot init wallet key");
  204.         exit(10);
  205.     }
  206.     if(!bp_key_secret_set(&wallet,finalKey,32)) {
  207.         fprintf(stderr,"%s","cannot init wallet key");
  208.         exit(10);
  209.     }
  210.  
  211.     unsigned char * pubKey;
  212.     size_t pubKeylen;
  213.     bp_pubkey_get(&wallet, ((void **) &pubKey), &pubKeylen);
  214.  
  215.     /*
  216.     printf("pubkey len: %d hex: ",pubKeylen);
  217.     print_hex(pubKey,pubKeylen);
  218.     printf("%s","\r\n");
  219.     */
  220.  
  221.     GString * btcAddress;
  222.     btcAddress = bp_pubkey_get_address(&wallet, 0);
  223.  
  224.     /*
  225.     printf("address: %s\r\n",btcAddress->str);
  226.     */
  227.  
  228.     unsigned char checkHash[32];
  229.     bu_Hash(checkHash, btcAddress->str, strlen(btcAddress->str));
  230.  
  231.     /* printf("checkhash: %.02x%.02x%.02x%.02x\r\n",
  232.     checkHash[0],checkHash[1],checkHash[2],checkHash[3]); */
  233.  
  234.     if(!memcmp(&b58dec->str[3],checkHash,4)) {
  235.         printf("!!!!!!!!!!!!!!!!!!!!\r\n");
  236.         printf("!!hash match found!!\r\n");
  237.         printf("!!  key is %s  !!\r\n", pKey_pass);
  238.         printf("!!!!!!!!!!!!!!!!!!!!\r\n");
  239.         return 0;
  240.     }
  241.  
  242.     return 1;
  243. }
  244.  
  245. char pass[6]; // the current password being checked
  246. pthread_mutex_t coderoll_mutex;
  247. long unsigned int number_tested;
  248.  
  249. void coderoll(char * currentPass) {
  250.     pthread_mutex_lock(&coderoll_mutex);
  251.     if(number_tested % 10 == 0) {
  252.         printf("total tested: %lu, current code: %s\r\n",number_tested, pass);
  253.     }
  254.     number_tested ++;
  255.     if (number_tested != 1)
  256.     {
  257.         pass[3]++;
  258.     }
  259.         if(pass[3] > 'z') {
  260.             pass[3] = 'a';
  261.             pass[2]++;
  262.             if(pass[2] > 'Z') {
  263.                 pass[2] = 'A';
  264.                 pass[1]++;
  265.                 if(pass[1] > 'z') {
  266.                     pass[1] = 'a';
  267.                     pass[0]++;
  268.                     if(pass[0] > 'Z') {
  269.                         pass[0] = 'A';
  270.                         pass[1] = 'a';
  271.                         pass[2] = 'A';
  272.                         pass[3] = 'a';
  273.                     }
  274.                 }
  275.             }
  276.         }
  277.    
  278.     strcpy(currentPass,pass);
  279.     pthread_mutex_unlock(&coderoll_mutex);
  280. }
  281.  
  282. void * crackthread(void * ctx) {
  283.     char * pKey;
  284.     char currentPass[6];
  285.     pKey = (char *)ctx;
  286.     while(true) {
  287.         coderoll(currentPass);
  288.         if(!crack(pKey, currentPass)) {
  289.             printf("found password: %s\r\n",currentPass);
  290.             exit(0);
  291.         }
  292.     }
  293. }
  294.  
  295. int main(int argc, char * argv[]) {
  296.     int i;
  297.     pthread_t threads[NUM_THREADS];
  298.     number_tested = 0;
  299.     printf("casascius bip38 private key brute forcer\r\n");
  300.  
  301.     /* takes a single command line arg. */
  302.     /* if passed in, this is the starting string to check instead of AaAaA */
  303.     if(argc > 1) {
  304.         strncpy(pass,argv[1],4);
  305.     } else {
  306.         strncpy(pass,"AaAa",4);
  307.     }
  308.  
  309.     /* make sure the crack function is working */
  310.     /*if(crack("6PfLGnQs6VZnrNpmVKfjotbnQuaJK4KZoPFrAjx1JMJUa1Ft8gnf5WxfKd","Satoshi")){
  311.         fprintf(stderr,"the crack function is not working, sorry.");
  312.     }*/
  313.  
  314.     /* the target encrypted private key to crack. */
  315.     //const char pKey[] = "6PfTokDpyZUYwaVg37aZZ67MvD1bTyrCyjrjacz1XAgfVndWjZSsxLuDrE"; // official Casascius contest key
  316.  
  317.     const char pKey[] = "6PfQoEzqbz3i2LpHibYnwAspwBwa3Nei1rU7UH9yzfutXT7tyUzV8aYAvG"; // test key that decrypts with AaAaJ
  318.     pthread_mutex_t coderoll_mutex = PTHREAD_MUTEX_INITIALIZER;
  319.  
  320.     for(i=0; i < NUM_THREADS; i++) {
  321.         pthread_create(&threads[i], NULL, crackthread, (void *)pKey);
  322.     }
  323.  
  324.     pthread_exit(NULL);
  325.     return 0;
  326. }
Add Comment
Please, Sign In to add comment