static void keytest() { { struct bp_key k; bp_key_init(&k); bp_key_free(&k); } // Signature { const uint8_t test_secret[32] = { 0x1 }; const uint8_t test_data[] = { 1, 2, 3, 4, 5, 6, 7, 8 }; bu256_t hash; SHA256(test_data, sizeof(test_data), (uint8_t *)&hash); void *pub = NULL; size_t publen = 0; void *sig = NULL; size_t siglen = 0; struct bp_key k; bp_key_init(&k); assert(bp_key_secret_set(&k, test_secret, sizeof(test_secret))); assert(bp_pubkey_get(&k, &pub, &publen)); assert(NULL != pub); assert(0 != publen); assert(bp_sign(&k, (uint8_t *)&hash, sizeof(hash), &sig, &siglen)); assert(NULL != sig); assert(0 != siglen); bp_key_free(&k); struct bp_key pubk; bp_key_init(&k); assert(bp_pubkey_set(&pubk, pub, publen)); assert(bp_verify(&pubk, (uint8_t *)&hash, sizeof(hash), sig, siglen)); bp_key_free(&k); free(pub); free(sig); } }
std::vector<unsigned char> decrypt_bip38_ec(const std::vector<unsigned char> key, const std::string& passwd) { int i; uint8_t passfactor[PASSFACTOR_SIZE]; memset(passfactor,0,PASSFACTOR_SIZE); const unsigned char * s_key = reinterpret_cast<const unsigned char*>(key.data()); crypto_scrypt((const uint8_t *)passwd.c_str(), passwd.length(), &s_key[3 + ADDRESSHASH_SIZE], OWNERSALT_SIZE, 16384, 8, 8, passfactor, PASSFACTOR_SIZE ); // compute EC point (passpoint) using passfactor struct bp_key ec_point; if(!bp_key_init(&ec_point)) { fprintf(stderr,"%s","cannot init EC point key"); exit(3); } if(!bp_key_secret_set(&ec_point,passfactor,PASSFACTOR_SIZE)) { fprintf(stderr,"%s","cannot set EC point from passfactor"); exit(3); } // get the passpoint as bytes unsigned char * passpoint; size_t passpoint_len; if(!bp_pubkey_get(&ec_point,(unsigned char **)&passpoint,&passpoint_len)) { fprintf(stderr,"%s","cannot get pubkey for EC point"); exit(4); } // now we need to decrypt seedb uint8_t encryptedpart2[16]; memset(encryptedpart2,0,16); memcpy(encryptedpart2, &s_key[3 + ADDRESSHASH_SIZE + OWNERSALT_SIZE + 8], 16); uint8_t encryptedpart1[16]; memset(encryptedpart1,0,16); memcpy(encryptedpart1, &s_key[3 + ADDRESSHASH_SIZE + OWNERSALT_SIZE], 8); unsigned char derived[DERIVED_SIZE]; // get the encryption key for seedb using scrypt // with passpoint as the key, salt is addresshash+ownersalt unsigned char derived_scrypt_salt[ADDRESSHASH_SIZE + OWNERSALT_SIZE]; memcpy(derived_scrypt_salt, &s_key[3], ADDRESSHASH_SIZE); // copy the addresshash memcpy(derived_scrypt_salt+ADDRESSHASH_SIZE, &s_key[3+ADDRESSHASH_SIZE], OWNERSALT_SIZE); // copy the ownersalt crypto_scrypt( passpoint, passpoint_len, derived_scrypt_salt, ADDRESSHASH_SIZE+OWNERSALT_SIZE, 1024, 1, 1, derived, DERIVED_SIZE ); //get decryption key unsigned char derivedhalf2[DERIVED_SIZE/2]; memcpy(derivedhalf2, derived+(DERIVED_SIZE/2), DERIVED_SIZE/2); unsigned char iv[32]; memset(iv,0,32); EVP_CIPHER_CTX d; EVP_CIPHER_CTX_init(&d); EVP_DecryptInit_ex(&d, EVP_aes_256_ecb(), NULL, derivedhalf2, iv); unsigned char unencryptedpart2[32]; int decrypt_len; EVP_DecryptUpdate(&d, unencryptedpart2, &decrypt_len, encryptedpart2, 16); EVP_DecryptUpdate(&d, unencryptedpart2, &decrypt_len, encryptedpart2, 16); for(i=0; i<16; i++) { unencryptedpart2[i] ^= derived[i + 16]; } unsigned char unencryptedpart1[32]; memcpy(encryptedpart1+8, unencryptedpart2, 8); EVP_DecryptUpdate(&d, unencryptedpart1, &decrypt_len, encryptedpart1, 16); EVP_DecryptUpdate(&d, unencryptedpart1, &decrypt_len, encryptedpart1, 16); for(i=0; i<16; i++) { unencryptedpart1[i] ^= derived[i]; } // recoved seedb unsigned char seedb[24]; memcpy(seedb, unencryptedpart1, 16); memcpy(&(seedb[16]), &(unencryptedpart2[8]), 8); // turn seedb into factorb (factorb = SHA256(SHA256(seedb))) unsigned char factorb[32]; bu_Hash(factorb, seedb, 24); // multiply by passfactor (ec_point_pub) const EC_GROUP * ec_group = EC_KEY_get0_group(ec_point.k); const EC_POINT * ec_point_pub = EC_KEY_get0_public_key(ec_point.k); BIGNUM * bn_passfactor = BN_bin2bn(passfactor,32,BN_new()); BIGNUM * bn_factorb = BN_bin2bn(factorb,32,BN_new()); BIGNUM * bn_res = BN_new(); BIGNUM * bn_final = BN_new(); BIGNUM * bn_n = BN_new(); BN_CTX * ctx = BN_CTX_new(); EC_GROUP_get_order(ec_group, bn_n, ctx); BN_mul(bn_res, bn_passfactor, bn_factorb, ctx); BN_mod(bn_final, bn_res, bn_n, ctx); unsigned char finalKey[32]; memset(finalKey, 0, 32); int n = BN_bn2bin(bn_final, finalKey); BN_clear_free(bn_passfactor); BN_clear_free(bn_factorb); BN_clear_free(bn_res); BN_clear_free(bn_n); BN_clear_free(bn_final); printf("\n"); print_hex((char *)finalKey, 32); printf("\n"); std::vector<unsigned char> out; out.assign(finalKey, finalKey + 32); return out; }