TEST(RIPEMD160, testvectors) { EXPECT_EQ(RIPEMD160().blocksize(), (std::size_t) 512); EXPECT_EQ(RIPEMD160().digestsize(), (std::size_t) 160); hash_test <RIPEMD160> (RIPEMD160_TEST_VECTORS); }
char * getRealBitcoinAddress() { printf("OpenSSL version: %s\n", OPENSSL_VERSION_TEXT); /*printf("Enter the number of keys: "); fflush(stdout); */ char stringMatch[31]; /*getLine1(stringMatch); unsigned long int i = strtol(stringMatch, NULL, 0);*/ printf("Please enter a string of text for the key (30 max): "); fflush(stdout); getLine1(stringMatch); printf("Waiting for entropy... Move the cursor around...\n"); fflush(stdout); char entropy[32]; FILE * f = fopen("/dev/random", "r"); if (fread(entropy, 32, 1, f) != 1) { printf("FAILURING GETTING ENTROPY!"); return 1; } RAND_add(entropy, 32, 32); fclose(f); printf("Making your addresses for \"%s\"\n\n", stringMatch); EC_KEY * key = EC_KEY_new_by_curve_name(NID_secp256k1); uint8_t * pubKey = NULL; int pubSize = 0; uint8_t * privKey = NULL; int privSize = 0; uint8_t * shaHash = malloc(32); uint8_t * ripemdHash = malloc(20); unsigned int x; if (!EC_KEY_generate_key(key)) { printf("GENERATE KEY FAIL\n"); exit(1); } int pubSizeNew = i2o_ECPublicKey(key, NULL); if (!pubSizeNew) { printf("PUB KEY TO DATA ZERO\n"); exit(1); } if (pubSizeNew != pubSize) { pubSize = pubSizeNew; pubKey = realloc(pubKey, pubSize); } uint8_t * pubKey2 = pubKey; if (i2o_ECPublicKey(key, &pubKey2) != pubSize) { printf("PUB KEY TO DATA FAIL\n"); exit(1); } SHA256(pubKey, pubSize, shaHash); RIPEMD160(shaHash, 32, ripemdHash); Address * address = createNewAddressFromRIPEMD160Hash(ripemdHash, 0, 0, err8); ByteArray * string = getStringForVersionChecksumBytes( getVersionChecksumBytes(address)); decrementReferenceCount(address); uint8_t offset = 1; size_t matchSize = strlen(stringMatch); uint8_t y; /* Get private key*/ const BIGNUM * privKeyNum = EC_KEY_get0_private_key(key); if (!privKeyNum) { printf("PRIV KEY TO BN FAIL\n"); } int privSizeNew = BN_num_bytes(privKeyNum); if (privSizeNew != privSize) { privSize = privSizeNew; privKey = realloc(privKey, privSize); } int res = BN_bn2bin(privKeyNum, privKey); if (res != privSize) { printf("PRIV KEY TO DATA FAIL\n"); } /* Print data to stdout*/ printf("Private key (hex): "); int i; for (i = 0; i < privSize; i++) { printf(" %.2X", privKey[i]); } printf("\nPublic key (hex): "); int j; for (j = 0; j < pubSize; j++) { printf(" %.2X", pubKey[j]); } printf("\n"); char *realBitcoinAddress = getByteArrayData(string); /*printf("\nAddress (base-58): %s\n\n", realBitcoinAddress);*/ x++; /*Move to next*/ decrementReferenceCount(string); free(shaHash); free(ripemdHash); EC_KEY_free(key); return realBitcoinAddress; }
void f_hash(void) { const char *algo; const char *data; char *res; algo = (sp - 1)->u.string; data = sp->u.string; /* MD2 Digest */ if (strcasecmp(algo, (const char *)"md2") == 0) { unsigned char md[MD2_DIGEST_LENGTH]; MD2((unsigned char *)data, strlen(data), md); res = hexdump(md, MD2_DIGEST_LENGTH); } /* MD4 Digest */ else if (strcasecmp(algo, (const char *)"md4") == 0) { unsigned char md[MD4_DIGEST_LENGTH]; MD4((unsigned char *)data, strlen(data), md); res = hexdump(md, MD4_DIGEST_LENGTH); } /* MD5 Digest */ else if (strcasecmp(algo, (const char *)"md5") == 0) { unsigned char md[MD5_DIGEST_LENGTH]; MD5((unsigned char *)data, strlen(data), md); res = hexdump(md, MD5_DIGEST_LENGTH); } /* MDC2 Digest */ else if (strcasecmp(algo, (const char *)"mdc2") == 0) { unsigned char md[MDC2_DIGEST_LENGTH]; MDC2((unsigned char *)data, strlen(data), md); res = hexdump(md, MDC2_DIGEST_LENGTH); } /* RIPEMD160 Digest */ else if (strcasecmp(algo, (const char *)"ripemd160") == 0) { unsigned char md[RIPEMD160_DIGEST_LENGTH]; RIPEMD160((unsigned char *)data, strlen(data), md); res = hexdump(md, RIPEMD160_DIGEST_LENGTH); } /* SHA1 Digest */ else if (strcasecmp(algo, (const char *)"sha1") == 0) { unsigned char md[SHA_DIGEST_LENGTH]; SHA1((unsigned char *)data, strlen(data), md); res = hexdump(md, SHA_DIGEST_LENGTH); } else { pop_stack(); res = malloc(29 + strlen(algo)); sprintf(res, "hash() unknown hash type: %s.\n", algo); error(res); } /* Pop the arguments off the stack and push the result */ free_string_svalue(sp--); free_string_svalue(sp); sp->subtype = STRING_MALLOC; sp->u.string = res; }
void * vg_thread_loop(void *arg) { unsigned char hash_buf[128]; unsigned char *eckey_buf; unsigned char hash1[32]; int i, c, len, output_interval; int hash_len; const BN_ULONG rekey_max = 10000000; BN_ULONG npoints, rekey_at, nbatch; vg_context_t *vcp = (vg_context_t *) arg; EC_KEY *pkey = NULL; const EC_GROUP *pgroup; const EC_POINT *pgen; const int ptarraysize = 256; EC_POINT *ppnt[ptarraysize]; EC_POINT *pbatchinc; vg_test_func_t test_func = vcp->vc_test; vg_exec_context_t ctx; vg_exec_context_t *vxcp; struct timeval tvstart; memset(&ctx, 0, sizeof(ctx)); vxcp = &ctx; vg_exec_context_init(vcp, &ctx); pkey = vxcp->vxc_key; pgroup = EC_KEY_get0_group(pkey); pgen = EC_GROUP_get0_generator(pgroup); for (i = 0; i < ptarraysize; i++) { ppnt[i] = EC_POINT_new(pgroup); if (!ppnt[i]) { fprintf(stderr, "ERROR: out of memory?\n"); exit(1); } } pbatchinc = EC_POINT_new(pgroup); if (!pbatchinc) { fprintf(stderr, "ERROR: out of memory?\n"); exit(1); } BN_set_word(&vxcp->vxc_bntmp, ptarraysize); EC_POINT_mul(pgroup, pbatchinc, &vxcp->vxc_bntmp, NULL, NULL, vxcp->vxc_bnctx); EC_POINT_make_affine(pgroup, pbatchinc, vxcp->vxc_bnctx); npoints = 0; rekey_at = 0; nbatch = 0; vxcp->vxc_key = pkey; vxcp->vxc_binres[0] = vcp->vc_addrtype; c = 0; output_interval = 1000; gettimeofday(&tvstart, NULL); if (vcp->vc_format == VCF_SCRIPT) { hash_buf[ 0] = 0x51; // OP_1 hash_buf[ 1] = 0x41; // pubkey length // gap for pubkey hash_buf[67] = 0x51; // OP_1 hash_buf[68] = 0xae; // OP_CHECKMULTISIG eckey_buf = hash_buf + 2; hash_len = 69; } else { eckey_buf = hash_buf; hash_len = (vcp->vc_compressed)?33:65; } while (!vcp->vc_halt) { if (++npoints >= rekey_at) { vg_exec_context_upgrade_lock(vxcp); /* Generate a new random private key */ EC_KEY_generate_key(pkey); npoints = 0; /* Determine rekey interval */ EC_GROUP_get_order(pgroup, &vxcp->vxc_bntmp, vxcp->vxc_bnctx); BN_sub(&vxcp->vxc_bntmp2, &vxcp->vxc_bntmp, EC_KEY_get0_private_key(pkey)); rekey_at = BN_get_word(&vxcp->vxc_bntmp2); if ((rekey_at == BN_MASK2) || (rekey_at > rekey_max)) rekey_at = rekey_max; assert(rekey_at > 0); EC_POINT_copy(ppnt[0], EC_KEY_get0_public_key(pkey)); vg_exec_context_downgrade_lock(vxcp); npoints++; vxcp->vxc_delta = 0; if (vcp->vc_pubkey_base) EC_POINT_add(pgroup, ppnt[0], ppnt[0], vcp->vc_pubkey_base, vxcp->vxc_bnctx); for (nbatch = 1; (nbatch < ptarraysize) && (npoints < rekey_at); nbatch++, npoints++) { EC_POINT_add(pgroup, ppnt[nbatch], ppnt[nbatch-1], pgen, vxcp->vxc_bnctx); } } else { /* * Common case * * EC_POINT_add() can skip a few multiplies if * one or both inputs are affine (Z_is_one). * This is the case for every point in ppnt, as * well as pbatchinc. */ assert(nbatch == ptarraysize); for (nbatch = 0; (nbatch < ptarraysize) && (npoints < rekey_at); nbatch++, npoints++) { EC_POINT_add(pgroup, ppnt[nbatch], ppnt[nbatch], pbatchinc, vxcp->vxc_bnctx); } } /* * The single most expensive operation performed in this * loop is modular inversion of ppnt->Z. There is an * algorithm implemented in OpenSSL to do batched inversion * that only does one actual BN_mod_inverse(), and saves * a _lot_ of time. * * To take advantage of this, we batch up a few points, * and feed them to EC_POINTs_make_affine() below. */ EC_POINTs_make_affine(pgroup, nbatch, ppnt, vxcp->vxc_bnctx); for (i = 0; i < nbatch; i++, vxcp->vxc_delta++) { /* Hash the public key */ len = EC_POINT_point2oct(pgroup, ppnt[i], (vcp->vc_compressed)?POINT_CONVERSION_COMPRESSED:POINT_CONVERSION_UNCOMPRESSED, eckey_buf, (vcp->vc_compressed)?33:65, vxcp->vxc_bnctx); assert(len == (vcp->vc_compressed)?33:65); SHA256(hash_buf, hash_len, hash1); RIPEMD160(hash1, sizeof(hash1), &vxcp->vxc_binres[1]); switch (test_func(vxcp)) { case 1: npoints = 0; rekey_at = 0; i = nbatch; break; case 2: goto out; default: break; } } c += i; if (c >= output_interval) { output_interval = vg_output_timing(vcp, c, &tvstart); if (output_interval > 250000) output_interval = 250000; c = 0; } vg_exec_context_yield(vxcp); } out: vg_exec_context_del(&ctx); vg_context_thread_exit(vcp); for (i = 0; i < ptarraysize; i++) if (ppnt[i]) EC_POINT_free(ppnt[i]); if (pbatchinc) EC_POINT_free(pbatchinc); return NULL; }
/* creates a bitcoin address+private key from the SHA256 * hash of string. converts to base58 if base58 is 'true' * returns 1 if successful, 0 if not*/ int create_address_from_string(const unsigned char *string, unsigned char *address, unsigned char *priv_key, EC_GROUP *precompgroup, bool base58, bool debug) { u_int8_t * hash = malloc(SHA256_DIGEST_LENGTH); BIGNUM * n = BN_new(); //first we hash the string SHA256 (string, strlen(string), hash); //then we convert the hash to the BIGNUM n n = BN_bin2bn(hash, SHA256_DIGEST_LENGTH, n); BIGNUM * order = BN_new(); BIGNUM * nmodorder = BN_new(); BN_CTX *bnctx; bnctx = BN_CTX_new(); //then we create a new EC group with the curve secp256k1 EC_GROUP * pgroup; pgroup = EC_GROUP_new_by_curve_name(NID_secp256k1); if (!pgroup) { printf("ERROR: Couldn't get new group\n"); return 0; } //now we need to get the order of the group, and make sure that //the number we use for the private key is less than or equal to //the group order by using "nmodorder = n % order" EC_GROUP_get_order(pgroup, order, NULL); BN_mod(nmodorder, n, order, bnctx); if (BN_is_zero(nmodorder)) { printf("ERROR: SHA256(string) % order == 0. Pick another string.\n"); return 0; } if (debug) printf ("Secret number: %s\n", BN_bn2dec(nmodorder)); //now we create a new EC point, ecpoint, and place in it the secp256k1 //generator point multiplied by nmodorder. this newly created //point is the public key EC_POINT * ecpoint = EC_POINT_new(pgroup); if (!EC_POINT_mul(pgroup, ecpoint, nmodorder, NULL, NULL, NULL)) { printf("ERROR: Couldn't multiply the generator point with n\n"); return 0; } if (debug) { BIGNUM *x=NULL, *y=NULL; x=BN_new(); y=BN_new(); if (!EC_POINT_get_affine_coordinates_GFp(pgroup, ecpoint, x, y, NULL)) { printf("ERROR: Failed getting coordinates."); //don't fail on debug fail //return 0; } printf ("Public key coordinates. x: %s, y: %s\n", BN_bn2dec(x), BN_bn2dec(y)); BN_free(x); BN_free(y); } //then we need to convert the public key point to data //first we get the required size of the buffer in which the data is placed //by passing NULL as the buffer argument to EC_POINT_point2oct unsigned int bufsize = EC_POINT_point2oct (pgroup, ecpoint, POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL); u_int8_t * buffer = malloc(bufsize); //then we place the data in the buffer int len = EC_POINT_point2oct (pgroup, ecpoint, POINT_CONVERSION_UNCOMPRESSED, buffer, bufsize, NULL); if (len == 0) { printf("ERROR: Couldn't convert point to octet string."); return 0; } if (debug) { printf("DER encoded public key: "); print_hex(buffer, len); } //next we need to hash the public key data. first with SHA256, then with RIPEMD160 SHA256(buffer, len, hash); if (debug) { printf("SHA256 hash of public key: "); print_hex(hash, SHA256_DIGEST_LENGTH); } u_int8_t * ripemd = malloc(RIPEMD160_DIGEST_LENGTH+1+4); RIPEMD160(hash, SHA256_DIGEST_LENGTH, ripemd); if (debug) { printf("RIPEMD160 hash of SHA256 hash: "); print_hex(ripemd, RIPEMD160_DIGEST_LENGTH); } if (base58 == true) { //here we add the version byte to the beginning of the public key and four checksum //bytes at the end prepare_for_address(ripemd, RIPEMD160_DIGEST_LENGTH, 0); if (debug) { printf("Address in hex with version byte and checksum: "); print_hex(ripemd, RIPEMD160_DIGEST_LENGTH+1+4); } //and we convert the resulting data to base58 base58_encode(ripemd, RIPEMD160_DIGEST_LENGTH+1+4, address); } else { memcpy(address, ripemd, RIPEMD160_DIGEST_LENGTH); } //now we need to convert the big number nmodorder (private key) to data int buflen = BN_num_bytes(nmodorder); u_int8_t * buf = malloc(buflen+1+4); int datalen; //nmodorder is converted to binary representation datalen = BN_bn2bin(nmodorder, buf); if (debug) { printf("Private key: "); print_hex(buf, datalen); } if (base58 == true) { //and we add version byte and four byte checksum to the data prepare_for_address(buf, datalen, 0x80); //and convert this to base58 base58_encode(buf, datalen+5, priv_key); } else { memcpy(priv_key, buf, datalen+5); } free(hash); free(buffer); free(ripemd); free(buf); BN_free(n); BN_free(order); BN_free(nmodorder); if (precompgroup == NULL) EC_GROUP_free(pgroup); EC_POINT_free(ecpoint); BN_CTX_free(bnctx); return 1; }
static bool bp_script_eval(GPtrArray *stack, const GString *script, const struct bp_tx *txTo, unsigned int nIn, unsigned int flags, int nHashType) { struct const_buffer pc = { script->str, script->len }; struct const_buffer pend = { script->str + script->len, 0 }; struct const_buffer pbegincodehash = { script->str, script->len }; struct bscript_op op; bool rc = false; GByteArray *vfExec = g_byte_array_new(); GPtrArray *altstack = g_ptr_array_new_with_free_func( (GDestroyNotify) buffer_free); BIGNUM bn; BN_init(&bn); if (script->len > 10000) goto out; bool fStrictEncodings = flags & SCRIPT_VERIFY_STRICTENC; unsigned int nOpCount = 0; struct bscript_parser bp; bsp_start(&bp, &pc); while (pc.p < pend.p) { bool fExec = !count_false(vfExec); if (!bsp_getop(&op, &bp)) goto out; enum opcodetype opcode = op.op; if (op.data.len > 520) goto out; if (opcode > OP_16 && ++nOpCount > 201) goto out; if (disabled_op[opcode]) goto out; if (fExec && is_bsp_pushdata(opcode)) stack_push(stack, (struct buffer *) &op.data); else if (fExec || (OP_IF <= opcode && opcode <= OP_ENDIF)) switch (opcode) { // // Push value // case OP_1NEGATE: case OP_1: case OP_2: case OP_3: case OP_4: case OP_5: case OP_6: case OP_7: case OP_8: case OP_9: case OP_10: case OP_11: case OP_12: case OP_13: case OP_14: case OP_15: case OP_16: bn_set_int(&bn, (int)opcode - (int)(OP_1 - 1)); stack_push_str(stack, bn_getvch(&bn)); break; // // Control // case OP_NOP: case OP_NOP1: case OP_NOP2: case OP_NOP3: case OP_NOP4: case OP_NOP5: case OP_NOP6: case OP_NOP7: case OP_NOP8: case OP_NOP9: case OP_NOP10: break; case OP_IF: case OP_NOTIF: { // <expression> if [statements] [else [statements]] endif bool fValue = false; if (fExec) { if (stack->len < 1) goto out; struct buffer *vch = stacktop(stack, -1); fValue = CastToBool(vch); if (opcode == OP_NOTIF) fValue = !fValue; popstack(stack); } guint8 vc = (guint8) fValue; g_byte_array_append(vfExec, &vc, 1); break; } case OP_ELSE: { if (vfExec->len == 0) goto out; guint8 *v = &vfExec->data[vfExec->len - 1]; *v = !(*v); break; } case OP_ENDIF: if (vfExec->len == 0) goto out; g_byte_array_remove_index(vfExec, vfExec->len - 1); break; case OP_VERIFY: { if (stack->len < 1) goto out; bool fValue = CastToBool(stacktop(stack, -1)); if (fValue) popstack(stack); else goto out; break; } case OP_RETURN: goto out; // // Stack ops // case OP_TOALTSTACK: if (stack->len < 1) goto out; stack_push(altstack, stacktop(stack, -1)); popstack(stack); break; case OP_FROMALTSTACK: if (altstack->len < 1) goto out; stack_push(stack, stacktop(altstack, -1)); popstack(altstack); break; case OP_2DROP: // (x1 x2 -- ) if (stack->len < 2) goto out; popstack(stack); popstack(stack); break; case OP_2DUP: { // (x1 x2 -- x1 x2 x1 x2) if (stack->len < 2) goto out; struct buffer *vch1 = stacktop(stack, -2); struct buffer *vch2 = stacktop(stack, -1); stack_push(stack, vch1); stack_push(stack, vch2); break; } case OP_3DUP: { // (x1 x2 x3 -- x1 x2 x3 x1 x2 x3) if (stack->len < 3) goto out; struct buffer *vch1 = stacktop(stack, -3); struct buffer *vch2 = stacktop(stack, -2); struct buffer *vch3 = stacktop(stack, -1); stack_push(stack, vch1); stack_push(stack, vch2); stack_push(stack, vch3); break; } case OP_2OVER: { // (x1 x2 x3 x4 -- x1 x2 x3 x4 x1 x2) if (stack->len < 4) goto out; struct buffer *vch1 = stacktop(stack, -4); struct buffer *vch2 = stacktop(stack, -3); stack_push(stack, vch1); stack_push(stack, vch2); break; } case OP_2ROT: { // (x1 x2 x3 x4 x5 x6 -- x3 x4 x5 x6 x1 x2) if (stack->len < 6) goto out; struct buffer *vch1 = stack_take(stack, -6); struct buffer *vch2 = stack_take(stack, -5); g_ptr_array_remove_range(stack, stack->len - 6, 2); stack_push(stack, vch1); stack_push(stack, vch2); break; } case OP_2SWAP: // (x1 x2 x3 x4 -- x3 x4 x1 x2) if (stack->len < 4) goto out; stack_swap(stack, -4, -2); stack_swap(stack, -3, -1); break; case OP_IFDUP: { // (x - 0 | x x) if (stack->len < 1) goto out; struct buffer *vch = stacktop(stack, -1); if (CastToBool(vch)) stack_push(stack, vch); break; } case OP_DEPTH: // -- stacksize BN_set_word(&bn, stack->len); stack_push_str(stack, bn_getvch(&bn)); break; case OP_DROP: // (x -- ) if (stack->len < 1) goto out; popstack(stack); break; case OP_DUP: { // (x -- x x) if (stack->len < 1) goto out; struct buffer *vch = stacktop(stack, -1); stack_push(stack, vch); break; } case OP_NIP: // (x1 x2 -- x2) if (stack->len < 2) goto out; g_ptr_array_remove_index(stack, stack->len - 2); break; case OP_OVER: { // (x1 x2 -- x1 x2 x1) if (stack->len < 2) goto out; struct buffer *vch = stacktop(stack, -2); stack_push(stack, vch); break; } case OP_PICK: case OP_ROLL: { // (xn ... x2 x1 x0 n - xn ... x2 x1 x0 xn) // (xn ... x2 x1 x0 n - ... x2 x1 x0 xn) if (stack->len < 2) goto out; int n = stackint(stack, -1); popstack(stack); if (n < 0 || n >= (int)stack->len) goto out; struct buffer *vch = stacktop(stack, -n-1); if (opcode == OP_ROLL) { vch = buffer_copy(vch->p, vch->len); g_ptr_array_remove_index(stack, stack->len - n - 1); stack_push_nocopy(stack, vch); } else stack_push(stack, vch); break; } case OP_ROT: { // (x1 x2 x3 -- x2 x3 x1) // x2 x1 x3 after first swap // x2 x3 x1 after second swap if (stack->len < 3) goto out; stack_swap(stack, -3, -2); stack_swap(stack, -2, -1); break; } case OP_SWAP: { // (x1 x2 -- x2 x1) if (stack->len < 2) goto out; stack_swap(stack, -2, -1); break; } case OP_TUCK: { // (x1 x2 -- x2 x1 x2) if (stack->len < 2) goto out; struct buffer *vch = stacktop(stack, -1); stack_insert(stack, vch, -2); break; } case OP_SIZE: { // (in -- in size) if (stack->len < 1) goto out; struct buffer *vch = stacktop(stack, -1); BN_set_word(&bn, vch->len); stack_push_str(stack, bn_getvch(&bn)); break; } case OP_EQUAL: case OP_EQUALVERIFY: { // (x1 x2 - bool) if (stack->len < 2) goto out; struct buffer *vch1 = stacktop(stack, -2); struct buffer *vch2 = stacktop(stack, -1); bool fEqual = ((vch1->len == vch2->len) && memcmp(vch1->p, vch2->p, vch1->len) == 0); // OP_NOTEQUAL is disabled because it would be too easy to say // something like n != 1 and have some wiseguy pass in 1 with extra // zero bytes after it (numerically, 0x01 == 0x0001 == 0x000001) //if (opcode == OP_NOTEQUAL) // fEqual = !fEqual; popstack(stack); popstack(stack); stack_push_char(stack, fEqual ? 1 : 0); if (opcode == OP_EQUALVERIFY) { if (fEqual) popstack(stack); else goto out; } break; } // // Numeric // case OP_1ADD: case OP_1SUB: case OP_NEGATE: case OP_ABS: case OP_NOT: case OP_0NOTEQUAL: { // (in -- out) if (stack->len < 1) goto out; if (!CastToBigNum(&bn, stacktop(stack, -1))) goto out; switch (opcode) { case OP_1ADD: BN_add_word(&bn, 1); break; case OP_1SUB: BN_sub_word(&bn, 1); break; case OP_NEGATE: BN_set_negative(&bn, !BN_is_negative(&bn)); break; case OP_ABS: if (BN_is_negative(&bn)) BN_set_negative(&bn, 0); break; case OP_NOT: BN_set_word(&bn, BN_is_zero(&bn) ? 1 : 0); break; case OP_0NOTEQUAL: BN_set_word(&bn, BN_is_zero(&bn) ? 0 : 1); break; default: // impossible goto out; } popstack(stack); stack_push_str(stack, bn_getvch(&bn)); break; } case OP_ADD: case OP_SUB: case OP_BOOLAND: case OP_BOOLOR: case OP_NUMEQUAL: case OP_NUMEQUALVERIFY: case OP_NUMNOTEQUAL: case OP_LESSTHAN: case OP_GREATERTHAN: case OP_LESSTHANOREQUAL: case OP_GREATERTHANOREQUAL: case OP_MIN: case OP_MAX: { // (x1 x2 -- out) if (stack->len < 2) goto out; BIGNUM bn1, bn2; BN_init(&bn1); BN_init(&bn2); if (!CastToBigNum(&bn1, stacktop(stack, -2)) || !CastToBigNum(&bn2, stacktop(stack, -1))) { BN_clear_free(&bn1); BN_clear_free(&bn2); goto out; } switch (opcode) { case OP_ADD: BN_add(&bn, &bn1, &bn2); break; case OP_SUB: BN_sub(&bn, &bn1, &bn2); break; case OP_BOOLAND: BN_set_word(&bn, (!BN_is_zero(&bn1) && !BN_is_zero(&bn2)) ? 1 : 0); break; case OP_BOOLOR: BN_set_word(&bn, (!BN_is_zero(&bn1) || !BN_is_zero(&bn2)) ? 1 : 0); break; case OP_NUMEQUAL: case OP_NUMEQUALVERIFY: BN_set_word(&bn, (BN_cmp(&bn1, &bn2) == 0) ? 1 : 0); break; case OP_NUMNOTEQUAL: BN_set_word(&bn, (BN_cmp(&bn1, &bn2) != 0) ? 1 : 0); break; case OP_LESSTHAN: BN_set_word(&bn, (BN_cmp(&bn1, &bn2) < 0) ? 1 : 0); break; case OP_GREATERTHAN: BN_set_word(&bn, (BN_cmp(&bn1, &bn2) > 0) ? 1 : 0); break; case OP_LESSTHANOREQUAL: BN_set_word(&bn, (BN_cmp(&bn1, &bn2) <= 0) ? 1 : 0); break; case OP_GREATERTHANOREQUAL: BN_set_word(&bn, (BN_cmp(&bn1, &bn2) >= 0) ? 1 : 0); break; case OP_MIN: if (BN_cmp(&bn1, &bn2) < 0) BN_copy(&bn, &bn1); else BN_copy(&bn, &bn2); break; case OP_MAX: if (BN_cmp(&bn1, &bn2) > 0) BN_copy(&bn, &bn1); else BN_copy(&bn, &bn2); break; default: // impossible break; } popstack(stack); popstack(stack); stack_push_str(stack, bn_getvch(&bn)); BN_clear_free(&bn1); BN_clear_free(&bn2); if (opcode == OP_NUMEQUALVERIFY) { if (CastToBool(stacktop(stack, -1))) popstack(stack); else goto out; } break; } case OP_WITHIN: { // (x min max -- out) if (stack->len < 3) goto out; BIGNUM bn1, bn2, bn3; BN_init(&bn1); BN_init(&bn2); BN_init(&bn3); bool rc1 = CastToBigNum(&bn1, stacktop(stack, -3)); bool rc2 = CastToBigNum(&bn2, stacktop(stack, -2)); bool rc3 = CastToBigNum(&bn3, stacktop(stack, -1)); bool fValue = (BN_cmp(&bn2, &bn1) <= 0 && BN_cmp(&bn1, &bn3) < 0); popstack(stack); popstack(stack); popstack(stack); stack_push_char(stack, fValue ? 1 : 0); BN_clear_free(&bn1); BN_clear_free(&bn2); BN_clear_free(&bn3); if (!rc1 || !rc2 || !rc3) goto out; break; } // // Crypto // case OP_RIPEMD160: case OP_SHA1: case OP_SHA256: case OP_HASH160: case OP_HASH256: { // (in -- hash) if (stack->len < 1) goto out; struct buffer *vch = stacktop(stack, -1); unsigned int hashlen; unsigned char md[32]; switch (opcode) { case OP_RIPEMD160: hashlen = 20; RIPEMD160(vch->p, vch->len, md); break; case OP_SHA1: hashlen = 20; SHA1(vch->p, vch->len, md); break; case OP_SHA256: hashlen = 32; SHA256(vch->p, vch->len, md); break; case OP_HASH160: hashlen = 20; bu_Hash160(md, vch->p, vch->len); break; case OP_HASH256: hashlen = 32; bu_Hash(md, vch->p, vch->len); break; default: // impossible goto out; } popstack(stack); struct buffer buf = { md, hashlen }; stack_push(stack, &buf); break; } case OP_CODESEPARATOR: // Hash starts after the code separator memcpy(&pbegincodehash, &pc, sizeof(pc)); break; case OP_CHECKSIG: case OP_CHECKSIGVERIFY: { // (sig pubkey -- bool) if (stack->len < 2) goto out; struct buffer *vchSig = stacktop(stack, -2); struct buffer *vchPubKey = stacktop(stack, -1); ////// debug print //PrintHex(vchSig.begin(), vchSig.end(), "sig: %s\n"); //PrintHex(vchPubKey.begin(), vchPubKey.end(), "pubkey: %s\n"); // Subset of script starting at the most recent codeseparator GString *scriptCode = g_string_sized_new(pbegincodehash.len); g_string_append_len(scriptCode, pbegincodehash.p, pbegincodehash.len); // Drop the signature, since there's no way for // a signature to sign itself string_find_del(scriptCode, vchSig); bool fSuccess = (!fStrictEncodings || (IsCanonicalSignature(vchSig) && IsCanonicalPubKey(vchPubKey))); if (fSuccess) fSuccess = bp_checksig(vchSig, vchPubKey, scriptCode, txTo, nIn, nHashType); g_string_free(scriptCode, TRUE); popstack(stack); popstack(stack); stack_push_char(stack, fSuccess ? 1 : 0); if (opcode == OP_CHECKSIGVERIFY) { if (fSuccess) popstack(stack); else goto out; } break; } case OP_CHECKMULTISIG: case OP_CHECKMULTISIGVERIFY: { // ([sig ...] num_of_signatures [pubkey ...] num_of_pubkeys -- bool) int i = 1; if ((int)stack->len < i) goto out; int nKeysCount = stackint(stack, -i); if (nKeysCount < 0 || nKeysCount > 20) goto out; nOpCount += nKeysCount; if (nOpCount > 201) goto out; int ikey = ++i; i += nKeysCount; if ((int)stack->len < i) goto out; int nSigsCount = stackint(stack, -i); if (nSigsCount < 0 || nSigsCount > nKeysCount) goto out; int isig = ++i; i += nSigsCount; if ((int)stack->len < i) goto out; // Subset of script starting at the most recent codeseparator GString *scriptCode = g_string_sized_new(pbegincodehash.len); g_string_append_len(scriptCode, pbegincodehash.p, pbegincodehash.len); // Drop the signatures, since there's no way for // a signature to sign itself int k; for (k = 0; k < nSigsCount; k++) { struct buffer *vchSig =stacktop(stack, -isig-k); string_find_del(scriptCode, vchSig); } bool fSuccess = true; while (fSuccess && nSigsCount > 0) { struct buffer *vchSig = stacktop(stack, -isig); struct buffer *vchPubKey = stacktop(stack, -ikey); // Check signature bool fOk = (!fStrictEncodings || (IsCanonicalSignature(vchSig) && IsCanonicalPubKey(vchPubKey))); if (fOk) fOk = bp_checksig(vchSig, vchPubKey, scriptCode, txTo, nIn, nHashType); if (fOk) { isig++; nSigsCount--; } ikey++; nKeysCount--; // If there are more signatures left than keys left, // then too many signatures have failed if (nSigsCount > nKeysCount) fSuccess = false; } g_string_free(scriptCode, TRUE); while (i-- > 0) popstack(stack); stack_push_char(stack, fSuccess ? 1 : 0); if (opcode == OP_CHECKMULTISIGVERIFY) { if (fSuccess) popstack(stack); else goto out; } break; } default: goto out; } if (stack->len + altstack->len > 1000) goto out; } rc = (vfExec->len == 0 && bp.error == false); out: BN_clear_free(&bn); g_ptr_array_free(altstack, TRUE); g_byte_array_unref(vfExec); return rc; }
int main(){ printf("OpenSSL version: %s\n", OPENSSL_VERSION_TEXT); printf("Enter the number of keys: "); fflush(stdout); char stringMatch[31]; getLine(stringMatch); unsigned long int i = strtol(stringMatch, NULL, 0); printf("Enter a string of text for the key (30 max): "); fflush(stdout); getLine(stringMatch); printf("Waiting for entropy... Move the cursor around...\n"); fflush(stdout); char entropy[32]; FILE * f = fopen("/dev/random", "r"); if (fread(entropy, 32, 1, f) != 1){ printf("FAILURING GETTING ENTROPY!"); return 1; } RAND_add(entropy, 32, 32); fclose(f); printf("Making %lu addresses for \"%s\"\n\n", i, stringMatch); EC_KEY * key = EC_KEY_new_by_curve_name(NID_secp256k1); uint8_t * pubKey = NULL; int pubSize = 0; uint8_t * privKey = NULL; int privSize = 0; uint8_t * shaHash = malloc(32); uint8_t * ripemdHash = malloc(20); for (unsigned int x = 0; x < i;) { if(! EC_KEY_generate_key(key)){ printf("GENERATE KEY FAIL\n"); return 1; } int pubSizeNew = i2o_ECPublicKey(key, NULL); if(! pubSizeNew){ printf("PUB KEY TO DATA ZERO\n"); return 1; } if (pubSizeNew != pubSize) { pubSize = pubSizeNew; pubKey = realloc(pubKey, pubSize); } uint8_t * pubKey2 = pubKey; if(i2o_ECPublicKey(key, &pubKey2) != pubSize){ printf("PUB KEY TO DATA FAIL\n"); return 1; } SHA256(pubKey, pubSize, shaHash); RIPEMD160(shaHash, 32, ripemdHash); CBAddress * address = CBNewAddressFromRIPEMD160Hash(ripemdHash, CB_PRODUCTION_NETWORK_BYTE, false, err); CBByteArray * string = CBChecksumBytesGetString(CBGetChecksumBytes(address)); CBReleaseObject(address); bool match = true; uint8_t offset = 1; size_t matchSize = strlen(stringMatch); for (uint8_t y = 0; y < matchSize;) { char other = islower(stringMatch[y]) ? toupper(stringMatch[y]) : (isupper(stringMatch[y])? tolower(stringMatch[y]) : '\0'); if (CBByteArrayGetByte(string, y+offset) != stringMatch[y] && CBByteArrayGetByte(string, y+offset) != other) { offset++; y = 0; if (string->length < matchSize + offset) { match = false; break; } }else y++; } if (match) { // Get private key const BIGNUM * privKeyNum = EC_KEY_get0_private_key(key); if (! privKeyNum) { printf("PRIV KEY TO BN FAIL\n"); } int privSizeNew = BN_num_bytes(privKeyNum); if (privSizeNew != privSize) { privSize = privSizeNew; privKey = realloc(privKey, privSize); } int res = BN_bn2bin(privKeyNum, privKey); if (res != privSize) { printf("PRIV KEY TO DATA FAIL\n"); } // Print data to stdout printf("Private key (hex): "); for (int x = 0; x < privSize; x++) { printf(" %.2X", privKey[x]); } printf("\nPublic key (hex): "); for (int x = 0; x < pubSize; x++) { printf(" %.2X", pubKey[x]); } printf("\nAddress (base-58): %s\n\n", CBByteArrayGetData(string)); x++; // Move to next } CBReleaseObject(string); } free(shaHash); free(ripemdHash); EC_KEY_free(key); return 0; }
int do_hash(char *algo, char *word) { unsigned char hash[64 + 1], seed[10]; double tm; int iterations = 0; clock_t cstart = clock(), cend = 0; srandom(time(NULL)); memset(&hash, 0, sizeof hash); unsigned long r[NUM_THREADS] = {0}; pthread_t thread[NUM_THREADS]; int i; for(i = 0; i < NUM_THREADS; i++){ r[i] = random()^i; // printf("Thread number %d, r = %lu, ", i, r[i]); //DEBUG // printf("created at 0x%08lx\n", (unsigned long) &thread[i]); //DEBUG } // return 0; //DEBUG if(!strncmp(algo, "md5", 3)){ for(;;){ iterations++; sprintf(seed, "%lu", random()); MD5(seed, sizeof seed, hash); //output_hash(hash, algo); //DEBUG if(check_hash(hash, word)) break; } } else if(!strncmp(algo, "sha1", 4)){ for(;;){ iterations++; sprintf(seed, "%lu", random()); SHA1(seed, sizeof seed, hash); //output_hash(hash, algo); //DEBUG if(check_hash(hash, word)){ break; } } } else if(!strncmp(algo, "sha256", 6)){ for(;;){ iterations++; sprintf(seed, "%lu", random()); SHA256(seed, sizeof seed, hash); //output_hash(hash, algo); //DEBUG if(check_hash(hash, word)){ break; } } } else if(!strncmp(algo, "sha384", 6)){ for(;;){ iterations++; sprintf(seed, "%lu", random()); SHA384(seed, sizeof seed, hash); //output_hash(hash, algo); //DEBUG if(check_hash(hash, word)){ break; } } } else if(!strncmp(algo, "sha512", 6)){ for(;;){ iterations++; sprintf(seed, "%lu", random()); SHA512(seed, sizeof seed, hash); //output_hash(hash, algo); //DEBUG if(check_hash(hash, word)){ break; } } } else if(!strncmp(algo, "rmd160", 6)){ for(;;){ iterations++; sprintf(seed, "%lu", random()); RIPEMD160(seed, sizeof seed, hash); //output_hash(hash, algo); //DEBUG if(check_hash(hash, word)){ break; } } } else { printf("Unknown hashing algorithm.\n\n"); return 1; } cend = clock(); tm = ((double)cend - (double)cstart) * 1.0e-6; printf("String match found in %.3f seconds. (%d iterations)\nHASH: ", tm, iterations); output_hash(hash, algo); printf("SEED: %s\n\n", seed); return 0; }
bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, const CTransaction& txTo, unsigned int nIn, int nHashType) { CAutoBN_CTX pctx; CScript::const_iterator pc = script.begin(); CScript::const_iterator pend = script.end(); CScript::const_iterator pbegincodehash = script.begin(); opcodetype opcode; valtype vchPushValue; vector<bool> vfExec; vector<valtype> altstack; if (script.size() > 10000) return false; int nOpCount = 0; try { while (pc < pend) { bool fExec = !count(vfExec.begin(), vfExec.end(), false); // // Read instruction // if (!script.GetOp(pc, opcode, vchPushValue)) return false; if (vchPushValue.size() > 520) return false; if (opcode > OP_16 && ++nOpCount > 201) return false; if (opcode == OP_CAT || opcode == OP_SUBSTR || opcode == OP_LEFT || opcode == OP_RIGHT || opcode == OP_INVERT || opcode == OP_AND || opcode == OP_OR || opcode == OP_XOR || opcode == OP_2MUL || opcode == OP_2DIV || opcode == OP_MUL || opcode == OP_DIV || opcode == OP_MOD || opcode == OP_LSHIFT || opcode == OP_RSHIFT) return false; if (fExec && 0 <= opcode && opcode <= OP_PUSHDATA4) stack.push_back(vchPushValue); else if (fExec || (OP_IF <= opcode && opcode <= OP_ENDIF)) switch (opcode) { // // Push value // case OP_1NEGATE: case OP_1: case OP_2: case OP_3: case OP_4: case OP_5: case OP_6: case OP_7: case OP_8: case OP_9: case OP_10: case OP_11: case OP_12: case OP_13: case OP_14: case OP_15: case OP_16: { // ( -- value) CBigNum bn((int)opcode - (int)(OP_1 - 1)); stack.push_back(bn.getvch()); } break; // // Control // case OP_NOP: case OP_NOP1: case OP_NOP2: case OP_NOP3: case OP_NOP4: case OP_NOP5: case OP_NOP6: case OP_NOP7: case OP_NOP8: case OP_NOP9: case OP_NOP10: break; case OP_IF: case OP_NOTIF: { // <expression> if [statements] [else [statements]] endif bool fValue = false; if (fExec) { if (stack.size() < 1) return false; valtype& vch = stacktop(-1); fValue = CastToBool(vch); if (opcode == OP_NOTIF) fValue = !fValue; popstack(stack); } vfExec.push_back(fValue); } break; case OP_ELSE: { if (vfExec.empty()) return false; vfExec.back() = !vfExec.back(); } break; case OP_ENDIF: { if (vfExec.empty()) return false; vfExec.pop_back(); } break; case OP_VERIFY: { // (true -- ) or // (false -- false) and return if (stack.size() < 1) return false; bool fValue = CastToBool(stacktop(-1)); if (fValue) popstack(stack); else return false; } break; case OP_RETURN: { return false; } break; // // Stack ops // case OP_TOALTSTACK: { if (stack.size() < 1) return false; altstack.push_back(stacktop(-1)); popstack(stack); } break; case OP_FROMALTSTACK: { if (altstack.size() < 1) return false; stack.push_back(altstacktop(-1)); popstack(altstack); } break; case OP_2DROP: { // (x1 x2 -- ) if (stack.size() < 2) return false; popstack(stack); popstack(stack); } break; case OP_2DUP: { // (x1 x2 -- x1 x2 x1 x2) if (stack.size() < 2) return false; valtype vch1 = stacktop(-2); valtype vch2 = stacktop(-1); stack.push_back(vch1); stack.push_back(vch2); } break; case OP_3DUP: { // (x1 x2 x3 -- x1 x2 x3 x1 x2 x3) if (stack.size() < 3) return false; valtype vch1 = stacktop(-3); valtype vch2 = stacktop(-2); valtype vch3 = stacktop(-1); stack.push_back(vch1); stack.push_back(vch2); stack.push_back(vch3); } break; case OP_2OVER: { // (x1 x2 x3 x4 -- x1 x2 x3 x4 x1 x2) if (stack.size() < 4) return false; valtype vch1 = stacktop(-4); valtype vch2 = stacktop(-3); stack.push_back(vch1); stack.push_back(vch2); } break; case OP_2ROT: { // (x1 x2 x3 x4 x5 x6 -- x3 x4 x5 x6 x1 x2) if (stack.size() < 6) return false; valtype vch1 = stacktop(-6); valtype vch2 = stacktop(-5); stack.erase(stack.end()-6, stack.end()-4); stack.push_back(vch1); stack.push_back(vch2); } break; case OP_2SWAP: { // (x1 x2 x3 x4 -- x3 x4 x1 x2) if (stack.size() < 4) return false; swap(stacktop(-4), stacktop(-2)); swap(stacktop(-3), stacktop(-1)); } break; case OP_IFDUP: { // (x - 0 | x x) if (stack.size() < 1) return false; valtype vch = stacktop(-1); if (CastToBool(vch)) stack.push_back(vch); } break; case OP_DEPTH: { // -- stacksize CBigNum bn(stack.size()); stack.push_back(bn.getvch()); } break; case OP_DROP: { // (x -- ) if (stack.size() < 1) return false; popstack(stack); } break; case OP_DUP: { // (x -- x x) if (stack.size() < 1) return false; valtype vch = stacktop(-1); stack.push_back(vch); } break; case OP_NIP: { // (x1 x2 -- x2) if (stack.size() < 2) return false; stack.erase(stack.end() - 2); } break; case OP_OVER: { // (x1 x2 -- x1 x2 x1) if (stack.size() < 2) return false; valtype vch = stacktop(-2); stack.push_back(vch); } break; case OP_PICK: case OP_ROLL: { // (xn ... x2 x1 x0 n - xn ... x2 x1 x0 xn) // (xn ... x2 x1 x0 n - ... x2 x1 x0 xn) if (stack.size() < 2) return false; int n = CastToBigNum(stacktop(-1)).getint(); popstack(stack); if (n < 0 || n >= stack.size()) return false; valtype vch = stacktop(-n-1); if (opcode == OP_ROLL) stack.erase(stack.end()-n-1); stack.push_back(vch); } break; case OP_ROT: { // (x1 x2 x3 -- x2 x3 x1) // x2 x1 x3 after first swap // x2 x3 x1 after second swap if (stack.size() < 3) return false; swap(stacktop(-3), stacktop(-2)); swap(stacktop(-2), stacktop(-1)); } break; case OP_SWAP: { // (x1 x2 -- x2 x1) if (stack.size() < 2) return false; swap(stacktop(-2), stacktop(-1)); } break; case OP_TUCK: { // (x1 x2 -- x2 x1 x2) if (stack.size() < 2) return false; valtype vch = stacktop(-1); stack.insert(stack.end()-2, vch); } break; // // Splice ops // case OP_CAT: { // (x1 x2 -- out) if (stack.size() < 2) return false; valtype& vch1 = stacktop(-2); valtype& vch2 = stacktop(-1); vch1.insert(vch1.end(), vch2.begin(), vch2.end()); popstack(stack); if (stacktop(-1).size() > 520) return false; } break; case OP_SUBSTR: { // (in begin size -- out) if (stack.size() < 3) return false; valtype& vch = stacktop(-3); int nBegin = CastToBigNum(stacktop(-2)).getint(); int nEnd = nBegin + CastToBigNum(stacktop(-1)).getint(); if (nBegin < 0 || nEnd < nBegin) return false; if (nBegin > vch.size()) nBegin = vch.size(); if (nEnd > vch.size()) nEnd = vch.size(); vch.erase(vch.begin() + nEnd, vch.end()); vch.erase(vch.begin(), vch.begin() + nBegin); popstack(stack); popstack(stack); } break; case OP_LEFT: case OP_RIGHT: { // (in size -- out) if (stack.size() < 2) return false; valtype& vch = stacktop(-2); int nSize = CastToBigNum(stacktop(-1)).getint(); if (nSize < 0) return false; if (nSize > vch.size()) nSize = vch.size(); if (opcode == OP_LEFT) vch.erase(vch.begin() + nSize, vch.end()); else vch.erase(vch.begin(), vch.end() - nSize); popstack(stack); } break; case OP_SIZE: { // (in -- in size) if (stack.size() < 1) return false; CBigNum bn(stacktop(-1).size()); stack.push_back(bn.getvch()); } break; // // Bitwise logic // case OP_INVERT: { // (in - out) if (stack.size() < 1) return false; valtype& vch = stacktop(-1); for (int i = 0; i < vch.size(); i++) vch[i] = ~vch[i]; } break; case OP_AND: case OP_OR: case OP_XOR: { // (x1 x2 - out) if (stack.size() < 2) return false; valtype& vch1 = stacktop(-2); valtype& vch2 = stacktop(-1); MakeSameSize(vch1, vch2); if (opcode == OP_AND) { for (int i = 0; i < vch1.size(); i++) vch1[i] &= vch2[i]; } else if (opcode == OP_OR) { for (int i = 0; i < vch1.size(); i++) vch1[i] |= vch2[i]; } else if (opcode == OP_XOR) { for (int i = 0; i < vch1.size(); i++) vch1[i] ^= vch2[i]; } popstack(stack); } break; case OP_EQUAL: case OP_EQUALVERIFY: //case OP_NOTEQUAL: // use OP_NUMNOTEQUAL { // (x1 x2 - bool) if (stack.size() < 2) return false; valtype& vch1 = stacktop(-2); valtype& vch2 = stacktop(-1); bool fEqual = (vch1 == vch2); // OP_NOTEQUAL is disabled because it would be too easy to say // something like n != 1 and have some wiseguy pass in 1 with extra // zero bytes after it (numerically, 0x01 == 0x0001 == 0x000001) //if (opcode == OP_NOTEQUAL) // fEqual = !fEqual; popstack(stack); popstack(stack); stack.push_back(fEqual ? vchTrue : vchFalse); if (opcode == OP_EQUALVERIFY) { if (fEqual) popstack(stack); else return false; } } break; // // Numeric // case OP_1ADD: case OP_1SUB: case OP_2MUL: case OP_2DIV: case OP_NEGATE: case OP_ABS: case OP_NOT: case OP_0NOTEQUAL: { // (in -- out) if (stack.size() < 1) return false; CBigNum bn = CastToBigNum(stacktop(-1)); switch (opcode) { case OP_1ADD: bn += bnOne; break; case OP_1SUB: bn -= bnOne; break; case OP_2MUL: bn <<= 1; break; case OP_2DIV: bn >>= 1; break; case OP_NEGATE: bn = -bn; break; case OP_ABS: if (bn < bnZero) bn = -bn; break; case OP_NOT: bn = (bn == bnZero); break; case OP_0NOTEQUAL: bn = (bn != bnZero); break; } popstack(stack); stack.push_back(bn.getvch()); } break; case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV: case OP_MOD: case OP_LSHIFT: case OP_RSHIFT: case OP_BOOLAND: case OP_BOOLOR: case OP_NUMEQUAL: case OP_NUMEQUALVERIFY: case OP_NUMNOTEQUAL: case OP_LESSTHAN: case OP_GREATERTHAN: case OP_LESSTHANOREQUAL: case OP_GREATERTHANOREQUAL: case OP_MIN: case OP_MAX: { // (x1 x2 -- out) if (stack.size() < 2) return false; CBigNum bn1 = CastToBigNum(stacktop(-2)); CBigNum bn2 = CastToBigNum(stacktop(-1)); CBigNum bn; switch (opcode) { case OP_ADD: bn = bn1 + bn2; break; case OP_SUB: bn = bn1 - bn2; break; case OP_MUL: if (!BN_mul(&bn, &bn1, &bn2, pctx)) return false; break; case OP_DIV: if (!BN_div(&bn, NULL, &bn1, &bn2, pctx)) return false; break; case OP_MOD: if (!BN_mod(&bn, &bn1, &bn2, pctx)) return false; break; case OP_LSHIFT: if (bn2 < bnZero || bn2 > CBigNum(2048)) return false; bn = bn1 << bn2.getulong(); break; case OP_RSHIFT: if (bn2 < bnZero || bn2 > CBigNum(2048)) return false; bn = bn1 >> bn2.getulong(); break; case OP_BOOLAND: bn = (bn1 != bnZero && bn2 != bnZero); break; case OP_BOOLOR: bn = (bn1 != bnZero || bn2 != bnZero); break; case OP_NUMEQUAL: bn = (bn1 == bn2); break; case OP_NUMEQUALVERIFY: bn = (bn1 == bn2); break; case OP_NUMNOTEQUAL: bn = (bn1 != bn2); break; case OP_LESSTHAN: bn = (bn1 < bn2); break; case OP_GREATERTHAN: bn = (bn1 > bn2); break; case OP_LESSTHANOREQUAL: bn = (bn1 <= bn2); break; case OP_GREATERTHANOREQUAL: bn = (bn1 >= bn2); break; case OP_MIN: bn = (bn1 < bn2 ? bn1 : bn2); break; case OP_MAX: bn = (bn1 > bn2 ? bn1 : bn2); break; } popstack(stack); popstack(stack); stack.push_back(bn.getvch()); if (opcode == OP_NUMEQUALVERIFY) { if (CastToBool(stacktop(-1))) popstack(stack); else return false; } } break; case OP_WITHIN: { // (x min max -- out) if (stack.size() < 3) return false; CBigNum bn1 = CastToBigNum(stacktop(-3)); CBigNum bn2 = CastToBigNum(stacktop(-2)); CBigNum bn3 = CastToBigNum(stacktop(-1)); bool fValue = (bn2 <= bn1 && bn1 < bn3); popstack(stack); popstack(stack); popstack(stack); stack.push_back(fValue ? vchTrue : vchFalse); } break; // // Crypto // case OP_RIPEMD160: case OP_SHA1: case OP_SHA256: case OP_HASH160: case OP_HASH256: { // (in -- hash) if (stack.size() < 1) return false; valtype& vch = stacktop(-1); valtype vchHash((opcode == OP_RIPEMD160 || opcode == OP_SHA1 || opcode == OP_HASH160) ? 20 : 32); if (opcode == OP_RIPEMD160) RIPEMD160(&vch[0], vch.size(), &vchHash[0]); else if (opcode == OP_SHA1) SHA1(&vch[0], vch.size(), &vchHash[0]); else if (opcode == OP_SHA256) SHA256(&vch[0], vch.size(), &vchHash[0]); else if (opcode == OP_HASH160) { uint160 hash160 = Hash160(vch); memcpy(&vchHash[0], &hash160, sizeof(hash160)); } else if (opcode == OP_HASH256) { uint256 hash = Hash(vch.begin(), vch.end()); memcpy(&vchHash[0], &hash, sizeof(hash)); } popstack(stack); stack.push_back(vchHash); } break; case OP_CODESEPARATOR: { // Hash starts after the code separator pbegincodehash = pc; } break; case OP_CHECKSIG: case OP_CHECKSIGVERIFY: { // (sig pubkey -- bool) if (stack.size() < 2) return false; valtype& vchSig = stacktop(-2); valtype& vchPubKey = stacktop(-1); ////// debug print //PrintHex(vchSig.begin(), vchSig.end(), "sig: %s\n"); //PrintHex(vchPubKey.begin(), vchPubKey.end(), "pubkey: %s\n"); // Subset of script starting at the most recent codeseparator CScript scriptCode(pbegincodehash, pend); // Drop the signature, since there's no way for a signature to sign itself scriptCode.FindAndDelete(CScript(vchSig)); bool fSuccess = CheckSig(vchSig, vchPubKey, scriptCode, txTo, nIn, nHashType); popstack(stack); popstack(stack); stack.push_back(fSuccess ? vchTrue : vchFalse); if (opcode == OP_CHECKSIGVERIFY) { if (fSuccess) popstack(stack); else return false; } } break; case OP_CHECKMULTISIG: case OP_CHECKMULTISIGVERIFY: { // ([sig ...] num_of_signatures [pubkey ...] num_of_pubkeys -- bool) int i = 1; if (stack.size() < i) return false; int nKeysCount = CastToBigNum(stacktop(-i)).getint(); if (nKeysCount < 0 || nKeysCount > 20) return false; nOpCount += nKeysCount; if (nOpCount > 201) return false; int ikey = ++i; i += nKeysCount; if (stack.size() < i) return false; int nSigsCount = CastToBigNum(stacktop(-i)).getint(); if (nSigsCount < 0 || nSigsCount > nKeysCount) return false; int isig = ++i; i += nSigsCount; if (stack.size() < i) return false; // Subset of script starting at the most recent codeseparator CScript scriptCode(pbegincodehash, pend); // Drop the signatures, since there's no way for a signature to sign itself for (int k = 0; k < nSigsCount; k++) { valtype& vchSig = stacktop(-isig-k); scriptCode.FindAndDelete(CScript(vchSig)); } bool fSuccess = true; while (fSuccess && nSigsCount > 0) { valtype& vchSig = stacktop(-isig); valtype& vchPubKey = stacktop(-ikey); // Check signature if (CheckSig(vchSig, vchPubKey, scriptCode, txTo, nIn, nHashType)) { isig++; nSigsCount--; } ikey++; nKeysCount--; // If there are more signatures left than keys left, // then too many signatures have failed if (nSigsCount > nKeysCount) fSuccess = false; } while (i-- > 0) popstack(stack); stack.push_back(fSuccess ? vchTrue : vchFalse); if (opcode == OP_CHECKMULTISIGVERIFY) { if (fSuccess) popstack(stack); else return false; } } break; default: return false; } // Size limits if (stack.size() + altstack.size() > 1000) return false; } } catch (...) { return false; } if (!vfExec.empty()) return false; return true; }
void CBRipemd160(uint8_t * data, uint16_t len, uint8_t * output){ RIPEMD160(data, len, output); }
HashValue160 Hash160(const ConstBuf& mb) { return HashValue160(RIPEMD160().ComputeHash(SHA256().ComputeHash(mb))); }