Beispiel #1
0
static bool bp_checksig(const struct buffer *vchSigIn,
			const struct buffer *vchPubKey,
			const cstring *scriptCode,
			const struct bp_tx *txTo, unsigned int nIn)
{
	if (!vchSigIn || !vchPubKey || !scriptCode || !txTo ||
	    !vchSigIn->len || !vchPubKey->len || !scriptCode->len)
		return false;

	// Hash type is one byte tacked on to the end of the signature
	unsigned char *vch_back = vchSigIn->p + (vchSigIn->len - 1);
	int nHashType = *vch_back;
	struct buffer vchSig = { vchSigIn->p, vchSigIn->len - 1 };

	/* calculate signature hash of transaction */
	bu256_t sighash;
	bp_tx_sighash(&sighash, scriptCode, txTo, nIn, nHashType);

	/* verify signature hash */
	struct bp_key pubkey;
	bp_key_init(&pubkey);
	bool rc = false;
	if (!bp_pubkey_set(&pubkey, vchPubKey->p, vchPubKey->len))
		goto out;
	if (!bp_verify(&pubkey, &sighash, sizeof(sighash), vchSig.p, vchSig.len))
		goto out;

	rc = true;

out:
	bp_key_free(&pubkey);
	return rc;
}
Beispiel #2
0
static bool bp_checksig(const struct buffer *vchSigHT,
			const struct buffer *vchPubKey,
			const GString *scriptCode,
			const struct bp_tx *txTo, unsigned int nIn,
			int nHashType)
{
	if (!vchSigHT || !vchPubKey || !scriptCode || !txTo ||
	    !vchSigHT->len || !vchPubKey->len || !scriptCode->len)
		return false;

	/* examine hashtype at end of string, then remove it */
	unsigned char *vch_back = vchSigHT->p + (vchSigHT->len - 1);
	if (nHashType == 0)
		nHashType = *vch_back;
	else if (nHashType != *vch_back)
		return false;
	struct buffer vchSig = { vchSigHT->p, vchSigHT->len - 1 };

	/* calculate signature hash of transaction */
	bu256_t sighash;
	bp_tx_sighash(&sighash, scriptCode, txTo, nIn, nHashType);

	/* verify signature hash */
	struct bp_key key;
	bp_key_init(&key);

	bool rc = false;
	if (!bp_pubkey_set(&key, vchPubKey->p, vchPubKey->len))
		goto out;
	if (!bp_verify(&key, &sighash, sizeof(sighash), vchSig.p, vchSig.len))
		goto out;

	rc = true;

out:
	bp_key_free(&key);
	return rc;
}
Beispiel #3
0
bool bp_script_sign(struct bp_keystore *ks, const cstring *fromPubKey,
		    const struct bp_tx *txTo, unsigned int nIn,
		    int nHashType)
{
	if (!txTo || !txTo->vin || nIn >= txTo->vin->len)
		return false;

	struct bp_txin *txin = parr_idx(txTo->vin, nIn);

	/* get signature hash */
	bu256_t hash;
	bp_tx_sighash(&hash, fromPubKey, txTo, nIn, nHashType);

	/* match fromPubKey against templates, to find what pubkey[hashes]
	 * are required for signing
	 */
	struct bscript_addr addrs;
	if (!bsp_addr_parse(&addrs, fromPubKey->str, fromPubKey->len))
		return false;

	cstring *scriptSig = cstr_new_sz(64);
	bool rc = false;
	bu160_t key_id;
	struct buffer *kbuf;

	/* sign, based on script template matched above */
	switch (addrs.txtype) {
	case TX_PUBKEY:
		kbuf = addrs.pub->data;
		bu_Hash160((unsigned char *)&key_id, kbuf->p, kbuf->len);

		if (!sign1(&key_id, ks, &hash, nHashType, scriptSig))
			goto out;
		break;

	case TX_PUBKEYHASH:
		kbuf = addrs.pubhash->data;
		memcpy(&key_id, kbuf->p, kbuf->len);

		if (!sign1(&key_id, ks, &hash, nHashType, scriptSig))
			goto out;
		if (!bkeys_pubkey_append(ks, &key_id, scriptSig))
			goto out;
		break;

	case TX_SCRIPTHASH:		/* TODO; not supported yet */
	case TX_MULTISIG:
		goto out;

	case TX_NONSTANDARD:		/* unknown script type, cannot sign */
		goto out;
	}

	if (txin->scriptSig)
		cstr_free(txin->scriptSig, true);
	txin->scriptSig = scriptSig;
	scriptSig = NULL;
	rc = true;

out:
	if (scriptSig)
		cstr_free(scriptSig, true);
	bsp_addr_free(&addrs);
	return rc;
}