#include "jets.h"
#include "ops.h"
#include "primitive.h"
#include "../../simplicity_assert.h"
static void readHash(sha256_midstate* h, frameItem *src) {
read32s(h->s, 8, src);
}
static void writeHash(frameItem* dst, const sha256_midstate* h) {
write32s(dst, h->s, 8);
}
static void prevOutpoint(frameItem* dst, const outpoint* op) {
writeHash(dst, &op->txid);
write32(dst, op->ix);
}
static void asset(frameItem* dst, const confidential* asset) {
if (writeBit(dst, EXPLICIT == asset->prefix)) {
skipBits(dst, 1);
} else {
writeBit(dst, ODD_Y == asset->prefix);
}
writeHash(dst, &asset->data);
}
static void amt(frameItem* dst, const confAmount* amt) {
if (writeBit(dst, EXPLICIT == amt->prefix)) {
skipBits(dst, 1 + 256 - 64);
write64(dst, amt->explicit);
} else {
writeBit(dst, ODD_Y == amt->prefix);
writeHash(dst, &amt->confidential);
}
}
static void nonce(frameItem* dst, const confidential* nonce) {
if (writeBit(dst, NONE != nonce->prefix)) {
if (writeBit(dst, EXPLICIT == nonce->prefix)) {
skipBits(dst, 1);
} else {
writeBit(dst, ODD_Y == nonce->prefix);
}
writeHash(dst, &nonce->data);
} else {
skipBits(dst, 1+1+256);
}
}
static void reissuanceBlinding(frameItem* dst, const assetIssuance* issuance) {
if (writeBit(dst, REISSUANCE == issuance->type)) {
writeHash(dst, &issuance->blindingNonce);
} else {
skipBits(dst, 256);
}
}
static void newIssuanceContract(frameItem* dst, const assetIssuance* issuance) {
if (writeBit(dst, NEW_ISSUANCE == issuance->type)) {
writeHash(dst, &issuance->contractHash);
} else {
skipBits(dst, 256);
}
}
static void reissuanceEntropy(frameItem* dst, const assetIssuance* issuance) {
if (writeBit(dst, REISSUANCE == issuance->type)) {
writeHash(dst, &issuance->entropy);
} else {
skipBits(dst, 256);
}
}
static void issuanceAssetAmt(frameItem* dst, const assetIssuance* issuance) {
if (writeBit(dst, NO_ISSUANCE != issuance->type)) {
amt(dst, &issuance->assetAmt);
} else {
skipBits(dst, 258);
}
}
static void issuanceTokenAmt(frameItem* dst, const assetIssuance* issuance) {
if (writeBit(dst, NO_ISSUANCE != issuance->type)) {
amt(dst, NEW_ISSUANCE == issuance->type ? &issuance->tokenAmt : &(confAmount){ .prefix = EXPLICIT, .explicit = 0});
} else {
skipBits(dst, 258);
}
}
static uint_fast32_t lockHeight(const transaction* tx) {
return !tx->isFinal && tx->lockTime < 500000000U ? tx->lockTime : 0;
}
static uint_fast32_t lockTime(const transaction* tx) {
return !tx->isFinal && 500000000U <= tx->lockTime ? tx->lockTime : 0;
}
static uint_fast16_t lockDistance(const transaction* tx) {
return 2 <= tx->version ? tx->lockDistance : 0;
}
static uint_fast16_t lockDuration(const transaction* tx) {
return 2 <= tx->version ? (uint_fast32_t)tx->lockDuration : 0;
}
static bool isFee(const sigOutput* output) {
return output->emptyScript && EXPLICIT == output->asset.prefix && EXPLICIT == output->amt.prefix;
}
bool version(frameItem* dst, frameItem src, const txEnv* env) {
(void) src; write32(dst, env->tx->version);
return true;
}
bool lock_time(frameItem* dst, frameItem src, const txEnv* env) {
(void) src; write32(dst, env->tx->lockTime);
return true;
}
bool input_pegin(frameItem* dst, frameItem src, const txEnv* env) {
uint_fast32_t i = read32(&src);
if (writeBit(dst, i < env->tx->numInputs)) {
if (writeBit(dst, env->tx->input[i].isPegin)) {
writeHash(dst, &env->tx->input[i].pegin);
} else {
skipBits(dst, 256);
}
} else {
skipBits(dst, 257);
}
return true;
}
bool input_prev_outpoint(frameItem* dst, frameItem src, const txEnv* env) {
uint_fast32_t i = read32(&src);
if (writeBit(dst, i < env->tx->numInputs)) {
prevOutpoint(dst, &env->tx->input[i].prevOutpoint);
} else {
skipBits(dst, 288);
}
return true;
}
bool input_asset(frameItem* dst, frameItem src, const txEnv* env) {
uint_fast32_t i = read32(&src);
if (writeBit(dst, i < env->tx->numInputs)) {
asset(dst, &env->tx->input[i].txo.asset);
} else {
skipBits(dst, 258);
}
return true;
}
bool input_amount(frameItem* dst, frameItem src, const txEnv* env) {
uint_fast32_t i = read32(&src);
if (writeBit(dst, i < env->tx->numInputs)) {
asset(dst, &env->tx->input[i].txo.asset);
amt(dst, &env->tx->input[i].txo.amt);
} else {
skipBits(dst, 516);
}
return true;
}
bool input_script_hash(frameItem* dst, frameItem src, const txEnv* env) {
uint_fast32_t i = read32(&src);
if (writeBit(dst, i < env->tx->numInputs)) {
writeHash(dst, &env->tx->input[i].txo.scriptPubKey);
} else {
skipBits(dst, 256);
}
return true;
}
bool input_sequence(frameItem* dst, frameItem src, const txEnv* env) {
uint_fast32_t i = read32(&src);
if (writeBit(dst, i < env->tx->numInputs)) {
write32(dst, env->tx->input[i].sequence);
} else {
skipBits(dst, 32);
}
return true;
}
bool reissuance_blinding(frameItem* dst, frameItem src, const txEnv* env) {
uint_fast32_t i = read32(&src);
if (writeBit(dst, i < env->tx->numInputs)) {
reissuanceBlinding(dst, &env->tx->input[i].issuance);
} else {
skipBits(dst, 257);
}
return true;
}
bool new_issuance_contract(frameItem* dst, frameItem src, const txEnv* env) {
uint_fast32_t i = read32(&src);
if (writeBit(dst, i < env->tx->numInputs)) {
newIssuanceContract(dst, &env->tx->input[i].issuance);
} else {
skipBits(dst, 257);
}
return true;
}
bool reissuance_entropy(frameItem* dst, frameItem src, const txEnv* env) {
uint_fast32_t i = read32(&src);
if (writeBit(dst, i < env->tx->numInputs)) {
reissuanceEntropy(dst, &env->tx->input[i].issuance);
} else {
skipBits(dst, 257);
}
return true;
}
bool issuance_asset_amount(frameItem* dst, frameItem src, const txEnv* env) {
uint_fast32_t i = read32(&src);
if (writeBit(dst, i < env->tx->numInputs)) {
issuanceAssetAmt(dst, &env->tx->input[i].issuance);
} else {
skipBits(dst, 259);
}
return true;
}
bool issuance_token_amount(frameItem* dst, frameItem src, const txEnv* env) {
uint_fast32_t i = read32(&src);
if (writeBit(dst, i < env->tx->numInputs)) {
issuanceTokenAmt(dst, &env->tx->input[i].issuance);
} else {
skipBits(dst, 259);
}
return true;
}
bool issuance_asset_proof(frameItem* dst, frameItem src, const txEnv* env) {
uint_fast32_t i = read32(&src);
if (writeBit(dst, i < env->tx->numInputs)) {
writeHash(dst, &env->tx->input[i].issuance.assetRangeProofHash);
} else {
skipBits(dst, 256);
}
return true;
}
bool issuance_token_proof(frameItem* dst, frameItem src, const txEnv* env) {
uint_fast32_t i = read32(&src);
if (writeBit(dst, i < env->tx->numInputs)) {
writeHash(dst, &env->tx->input[i].issuance.tokenRangeProofHash);
} else {
skipBits(dst, 256);
}
return true;
}
bool input_annex_hash(frameItem* dst, frameItem src, const txEnv* env) {
uint_fast32_t i = read32(&src);
if (writeBit(dst, i < env->tx->numInputs)) {
if (writeBit(dst, env->tx->input[i].hasAnnex)) {
writeHash(dst, &env->tx->input[i].annexHash);
} else {
skipBits(dst, 256);
}
} else {
skipBits(dst, 257);
}
return true;
}
bool input_script_sig_hash(frameItem* dst, frameItem src, const txEnv* env) {
uint_fast32_t i = read32(&src);
if (writeBit(dst, i < env->tx->numInputs)) {
writeHash(dst, &env->tx->input[i].scriptSigHash);
} else {
skipBits(dst, 256);
}
return true;
}
bool output_asset(frameItem* dst, frameItem src, const txEnv* env) {
uint_fast32_t i = read32(&src);
if (writeBit(dst, i < env->tx->numOutputs)) {
asset(dst, &env->tx->output[i].asset);
} else {
skipBits(dst, 258);
}
return true;
}
bool output_amount(frameItem* dst, frameItem src, const txEnv* env) {
uint_fast32_t i = read32(&src);
if (writeBit(dst, i < env->tx->numOutputs)) {
asset(dst, &env->tx->output[i].asset);
amt(dst, &env->tx->output[i].amt);
} else {
skipBits(dst, 516);
}
return true;
}
bool output_nonce(frameItem* dst, frameItem src, const txEnv* env) {
uint_fast32_t i = read32(&src);
if (writeBit(dst, i < env->tx->numOutputs)) {
nonce(dst, &env->tx->output[i].nonce);
} else {
skipBits(dst, 259);
}
return true;
}
bool output_script_hash(frameItem* dst, frameItem src, const txEnv* env) {
uint_fast32_t i = read32(&src);
if (writeBit(dst, i < env->tx->numOutputs)) {
writeHash(dst, &env->tx->output[i].scriptPubKey);
} else {
skipBits(dst, 256);
}
return true;
}
bool output_null_datum(frameItem* dst, frameItem src, const txEnv* env) {
uint_fast32_t i = read32(&src);
if (writeBit(dst, i < env->tx->numOutputs && env->tx->output[i].isNullData)) {
uint_fast32_t j = read32(&src);
if (writeBit(dst, j < env->tx->output[i].pnd.len)) {
if (writeBit(dst, OP_PUSHDATA4 < env->tx->output[i].pnd.op[j].code)) {
skipBits(dst, 2 + 256 - 5);
if (writeBit(dst, OP_1 <= env->tx->output[i].pnd.op[j].code)) {
switch (env->tx->output[i].pnd.op[j].code) {
case OP_1 : writeBit(dst, 0); writeBit(dst, 0); writeBit(dst, 0); writeBit(dst, 0); break;
case OP_2 : writeBit(dst, 0); writeBit(dst, 0); writeBit(dst, 0); writeBit(dst, 1); break;
case OP_3 : writeBit(dst, 0); writeBit(dst, 0); writeBit(dst, 1); writeBit(dst, 0); break;
case OP_4 : writeBit(dst, 0); writeBit(dst, 0); writeBit(dst, 1); writeBit(dst, 1); break;
case OP_5 : writeBit(dst, 0); writeBit(dst, 1); writeBit(dst, 0); writeBit(dst, 0); break;
case OP_6 : writeBit(dst, 0); writeBit(dst, 1); writeBit(dst, 0); writeBit(dst, 1); break;
case OP_7 : writeBit(dst, 0); writeBit(dst, 1); writeBit(dst, 1); writeBit(dst, 0); break;
case OP_8 : writeBit(dst, 0); writeBit(dst, 1); writeBit(dst, 1); writeBit(dst, 1); break;
case OP_9 : writeBit(dst, 1); writeBit(dst, 0); writeBit(dst, 0); writeBit(dst, 0); break;
case OP_10: writeBit(dst, 1); writeBit(dst, 0); writeBit(dst, 0); writeBit(dst, 1); break;
case OP_11: writeBit(dst, 1); writeBit(dst, 0); writeBit(dst, 1); writeBit(dst, 0); break;
case OP_12: writeBit(dst, 1); writeBit(dst, 0); writeBit(dst, 1); writeBit(dst, 1); break;
case OP_13: writeBit(dst, 1); writeBit(dst, 1); writeBit(dst, 0); writeBit(dst, 0); break;
case OP_14: writeBit(dst, 1); writeBit(dst, 1); writeBit(dst, 0); writeBit(dst, 1); break;
case OP_15: writeBit(dst, 1); writeBit(dst, 1); writeBit(dst, 1); writeBit(dst, 0); break;
case OP_16: writeBit(dst, 1); writeBit(dst, 1); writeBit(dst, 1); writeBit(dst, 1); break;
default: SIMPLICITY_UNREACHABLE;
}
} else {
simplicity_debug_assert(OP_RESERVED == env->tx->output[i].pnd.op[j].code ||
OP_1NEGATE == env->tx->output[i].pnd.op[j].code);
skipBits(dst, 3);
writeBit(dst, OP_RESERVED == env->tx->output[i].pnd.op[j].code);
}
} else {
switch (env->tx->output[i].pnd.op[j].code) {
case OP_IMMEDIATE: writeBit(dst, 0); writeBit(dst, 0); break;
case OP_PUSHDATA: writeBit(dst, 0); writeBit(dst, 1); break;
case OP_PUSHDATA2: writeBit(dst, 1); writeBit(dst, 0); break;
case OP_PUSHDATA4: writeBit(dst, 1); writeBit(dst, 1); break;
default: SIMPLICITY_UNREACHABLE;
}
writeHash(dst, &env->tx->output[i].pnd.op[j].dataHash);
}
} else {
skipBits(dst, 1 + 2 + 256);
}
} else {
skipBits(dst, 1 + 1 + 2 + 256);
}
return true;
}
bool output_is_fee(frameItem* dst, frameItem src, const txEnv* env) {
uint_fast32_t i = read32(&src);
if (writeBit(dst, i < env->tx->numOutputs)) {
writeBit(dst, isFee(&env->tx->output[i]));
} else {
skipBits(dst, 1);
}
return true;
}
bool output_surjection_proof(frameItem* dst, frameItem src, const txEnv* env) {
uint_fast32_t i = read32(&src);
if (writeBit(dst, i < env->tx->numOutputs)) {
writeHash(dst, &env->tx->output[i].surjectionProofHash);
} else {
skipBits(dst, 256);
}
return true;
}
bool output_range_proof(frameItem* dst, frameItem src, const txEnv* env) {
uint_fast32_t i = read32(&src);
if (writeBit(dst, i < env->tx->numOutputs)) {
writeHash(dst, &env->tx->output[i].rangeProofHash);
} else {
skipBits(dst, 256);
}
return true;
}
bool genesis_block_hash(frameItem* dst, frameItem src, const txEnv* env) {
(void) src; write32s(dst, env->genesisHash.s, 8);
return true;
}
bool script_cmr(frameItem* dst, frameItem src, const txEnv* env) {
(void) src; write32s(dst, env->taproot->scriptCMR.s, 8);
return true;
}
bool current_index(frameItem* dst, frameItem src, const txEnv* env) {
(void) src; write32(dst, env->ix);
return true;
}
bool current_pegin(frameItem* dst, frameItem src, const txEnv* env) {
(void) src; if (env->tx->numInputs <= env->ix) return false;
if (writeBit(dst, env->tx->input[env->ix].isPegin)) {
writeHash(dst, &env->tx->input[env->ix].pegin);
} else {
skipBits(dst, 256);
}
return true;
}
bool current_prev_outpoint(frameItem* dst, frameItem src, const txEnv* env) {
(void) src; if (env->tx->numInputs <= env->ix) return false;
prevOutpoint(dst, &env->tx->input[env->ix].prevOutpoint);
return true;
}
bool current_asset(frameItem* dst, frameItem src, const txEnv* env) {
(void) src; if (env->tx->numInputs <= env->ix) return false;
asset(dst, &env->tx->input[env->ix].txo.asset);
return true;
}
bool current_amount(frameItem* dst, frameItem src, const txEnv* env) {
(void) src; if (env->tx->numInputs <= env->ix) return false;
asset(dst, &env->tx->input[env->ix].txo.asset);
amt(dst, &env->tx->input[env->ix].txo.amt);
return true;
}
bool current_script_hash(frameItem* dst, frameItem src, const txEnv* env) {
(void) src; if (env->tx->numInputs <= env->ix) return false;
writeHash(dst, &env->tx->input[env->ix].txo.scriptPubKey);
return true;
}
bool current_sequence(frameItem* dst, frameItem src, const txEnv* env) {
(void) src; if (env->tx->numInputs <= env->ix) return false;
write32(dst, env->tx->input[env->ix].sequence);
return true;
}
bool current_reissuance_blinding(frameItem* dst, frameItem src, const txEnv* env) {
(void) src; if (env->tx->numInputs <= env->ix) return false;
reissuanceBlinding(dst, &env->tx->input[env->ix].issuance);
return true;
}
bool current_new_issuance_contract(frameItem* dst, frameItem src, const txEnv* env) {
(void) src; if (env->tx->numInputs <= env->ix) return false;
newIssuanceContract(dst, &env->tx->input[env->ix].issuance);
return true;
}
bool current_reissuance_entropy(frameItem* dst, frameItem src, const txEnv* env) {
(void) src; if (env->tx->numInputs <= env->ix) return false;
reissuanceEntropy(dst, &env->tx->input[env->ix].issuance);
return true;
}
bool current_issuance_asset_amount(frameItem* dst, frameItem src, const txEnv* env) {
(void) src; if (env->tx->numInputs <= env->ix) return false;
issuanceAssetAmt(dst, &env->tx->input[env->ix].issuance);
return true;
}
bool current_issuance_token_amount(frameItem* dst, frameItem src, const txEnv* env) {
(void) src; if (env->tx->numInputs <= env->ix) return false;
issuanceTokenAmt(dst, &env->tx->input[env->ix].issuance);
return true;
}
bool current_issuance_asset_proof(frameItem* dst, frameItem src, const txEnv* env) {
(void) src; if (env->tx->numInputs <= env->ix) return false;
writeHash(dst, &env->tx->input[env->ix].issuance.assetRangeProofHash);
return true;
}
bool current_issuance_token_proof(frameItem* dst, frameItem src, const txEnv* env) {
(void) src; if (env->tx->numInputs <= env->ix) return false;
writeHash(dst, &env->tx->input[env->ix].issuance.tokenRangeProofHash);
return true;
}
bool current_script_sig_hash(frameItem* dst, frameItem src, const txEnv* env) {
(void) src; if (env->tx->numInputs <= env->ix) return false;
writeHash(dst, &env->tx->input[env->ix].scriptSigHash);
return true;
}
bool current_annex_hash(frameItem* dst, frameItem src, const txEnv* env) {
(void) src; if (env->tx->numInputs <= env->ix) return false;
if (writeBit(dst, env->tx->input[env->ix].hasAnnex)) {
writeHash(dst, &env->tx->input[env->ix].annexHash);
} else {
skipBits(dst, 256);
}
return true;
}
bool tapleaf_version(frameItem* dst, frameItem src, const txEnv* env) {
(void) src; write8(dst, env->taproot->leafVersion);
return true;
}
bool tappath(frameItem* dst, frameItem src, const txEnv* env) {
uint_fast8_t i = read8(&src);
if (writeBit(dst, i < env->taproot->pathLen)) {
writeHash(dst, &env->taproot->path[i]);
} else {
skipBits(dst, 256);
}
return true;
}
bool internal_key(frameItem* dst, frameItem src, const txEnv* env) {
(void) src; writeHash(dst, &env->taproot->internalKey);
return true;
}
bool num_inputs(frameItem* dst, frameItem src, const txEnv* env) {
(void) src; write32(dst, env->tx->numInputs);
return true;
}
bool num_outputs(frameItem* dst, frameItem src, const txEnv* env) {
(void) src; write32(dst, env->tx->numOutputs);
return true;
}
bool tx_is_final(frameItem* dst, frameItem src, const txEnv* env) {
(void) src; writeBit(dst, env->tx->isFinal);
return true;
}
bool tx_lock_height(frameItem* dst, frameItem src, const txEnv* env) {
(void) src; write32(dst, lockHeight(env->tx));
return true;
}
bool tx_lock_time(frameItem* dst, frameItem src, const txEnv* env) {
(void) src; write32(dst, lockTime(env->tx));
return true;
}
bool tx_lock_distance(frameItem* dst, frameItem src, const txEnv* env) {
(void) src; write16(dst, lockDistance(env->tx));
return true;
}
bool tx_lock_duration(frameItem* dst, frameItem src, const txEnv* env) {
(void) src; write16(dst, lockDuration(env->tx));
return true;
}
bool check_lock_height(frameItem* dst, frameItem src, const txEnv* env) {
(void) dst; uint_fast32_t x = read32(&src);
return x <= lockHeight(env->tx);
}
bool check_lock_time(frameItem* dst, frameItem src, const txEnv* env) {
(void) dst; uint_fast32_t x = read32(&src);
return x <= lockTime(env->tx);
}
bool check_lock_distance(frameItem* dst, frameItem src, const txEnv* env) {
(void) dst; uint_fast16_t x = read16(&src);
return x <= lockDistance(env->tx);
}
bool check_lock_duration(frameItem* dst, frameItem src, const txEnv* env) {
(void) dst; uint_fast16_t x = read16(&src);
return x <= lockDuration(env->tx);
}
bool calculate_issuance_entropy(frameItem* dst, frameItem src, const txEnv* env) {
(void) env; outpoint op;
sha256_midstate contract;
sha256_midstate result;
read32s(op.txid.s, 8, &src);
op.ix = read32(&src);
read32s(contract.s, 8, &src);
result = generateIssuanceEntropy(&op, &contract);
writeHash(dst, &result);
return true;
}
bool calculate_asset(frameItem* dst, frameItem src, const txEnv* env) {
(void) env; sha256_midstate entropy;
sha256_midstate result;
read32s(entropy.s, 8, &src);
result = calculateAsset(&entropy);
writeHash(dst, &result);
return true;
}
bool calculate_explicit_token(frameItem* dst, frameItem src, const txEnv* env) {
(void) env; sha256_midstate entropy;
sha256_midstate result;
read32s(entropy.s, 8, &src);
result = calculateToken(&entropy, EXPLICIT);
writeHash(dst, &result);
return true;
}
bool calculate_confidential_token(frameItem* dst, frameItem src, const txEnv* env) {
(void) env; sha256_midstate entropy;
sha256_midstate result;
read32s(entropy.s, 8, &src);
result = calculateToken(&entropy, EVEN_Y );
writeHash(dst, &result);
return true;
}
bool build_tapleaf_simplicity(frameItem* dst, frameItem src, const txEnv* env) {
(void) env; sha256_midstate cmr;
readHash(&cmr, &src);
sha256_midstate result = make_tapleaf(0xbe, &cmr);
writeHash(dst, &result);
return true;
}
bool build_tapbranch(frameItem* dst, frameItem src, const txEnv* env) {
(void) env; sha256_midstate a, b;
readHash(&a, &src);
readHash(&b, &src);
sha256_midstate result = make_tapbranch(&a, &b);
writeHash(dst, &result);
return true;
}
bool outpoint_hash(frameItem* dst, frameItem src, const txEnv* env) {
(void) env; sha256_midstate midstate;
unsigned char buf[36];
sha256_context ctx = {.output = midstate.s};
if (!read_sha256_context(&ctx, &src)) return false;
if (readBit(&src)) {
read8s(buf, 32, &src);
sha256_uchar(&ctx, 0x01);
sha256_uchars(&ctx, buf, 32);
} else {
sha256_uchar(&ctx, 0x00);
forwardBits(&src, 256);
}
read8s(buf, 36, &src);
sha256_uchars(&ctx, buf, 36);
return write_sha256_context(dst, &ctx);
}
bool asset_amount_hash(frameItem* dst, frameItem src, const txEnv* env) {
(void) env; sha256_midstate midstate;
unsigned char buf[32];
sha256_context ctx = {.output = midstate.s};
if (!read_sha256_context(&ctx, &src)) return false;
if (readBit(&src)) {
forwardBits(&src, 1);
sha256_uchar(&ctx, 0x01);
} else {
if (readBit(&src)) {
sha256_uchar(&ctx, 0x0b);
} else {
sha256_uchar(&ctx, 0x0a);
}
}
read8s(buf, 32, &src);
sha256_uchars(&ctx, buf, 32);
if (readBit(&src)) {
sha256_uchar(&ctx, 0x01);
forwardBits(&src, 257-64);
read8s(buf, 8, &src);
sha256_uchars(&ctx, buf, 8);
} else {
if (readBit(&src)) {
sha256_uchar(&ctx, 0x09);
} else {
sha256_uchar(&ctx, 0x08);
}
read8s(buf, 32, &src);
sha256_uchars(&ctx, buf, 32);
}
return write_sha256_context(dst, &ctx);
}
bool nonce_hash(frameItem* dst, frameItem src, const txEnv* env) {
(void) env; sha256_midstate midstate;
unsigned char buf[32];
sha256_context ctx = {.output = midstate.s};
if (!read_sha256_context(&ctx, &src)) return false;
if (readBit(&src)) {
if (readBit(&src)) {
forwardBits(&src, 1);
sha256_uchar(&ctx, 0x01);
} else {
if (readBit(&src)) {
sha256_uchar(&ctx, 0x03);
} else {
sha256_uchar(&ctx, 0x02);
}
}
read8s(buf, 32, &src);
sha256_uchars(&ctx, buf, 32);
} else {
sha256_uchar(&ctx, 0x00);
}
return write_sha256_context(dst, &ctx);
}
bool annex_hash(frameItem* dst, frameItem src, const txEnv* env) {
(void) env; sha256_midstate midstate;
unsigned char buf[32];
sha256_context ctx = {.output = midstate.s};
if (!read_sha256_context(&ctx, &src)) return false;
if (readBit(&src)) {
read8s(buf, 32, &src);
sha256_uchar(&ctx, 0x01);
sha256_uchars(&ctx, buf, 32);
} else {
sha256_uchar(&ctx, 0x00);
}
return write_sha256_context(dst, &ctx);
}
bool issuance(frameItem* dst, frameItem src, const txEnv* env) {
uint_fast32_t i = read32(&src);
if (writeBit(dst, i < env->tx->numInputs)) {
const sigInput* input = &env->tx->input[i];
if (writeBit(dst, NO_ISSUANCE != input->issuance.type)) {
writeBit(dst, REISSUANCE == input->issuance.type);
} else {
skipBits(dst, 1);
}
} else {
skipBits(dst, 2);
}
return true;
}
bool issuance_entropy(frameItem* dst, frameItem src, const txEnv* env) {
uint_fast32_t i = read32(&src);
if (writeBit(dst, i < env->tx->numInputs)) {
const sigInput* input = &env->tx->input[i];
if (writeBit(dst, NO_ISSUANCE != input->issuance.type)) {
writeHash(dst, &input->issuance.entropy);
} else {
skipBits(dst, 256);
}
} else {
skipBits(dst, 257);
}
return true;
}
bool issuance_asset(frameItem* dst, frameItem src, const txEnv* env) {
uint_fast32_t i = read32(&src);
if (writeBit(dst, i < env->tx->numInputs)) {
const sigInput* input = &env->tx->input[i];
if (writeBit(dst, NO_ISSUANCE != input->issuance.type)) {
writeHash(dst, &input->issuance.assetId);
} else {
skipBits(dst, 256);
}
} else {
skipBits(dst, 257);
}
return true;
}
bool issuance_token(frameItem* dst, frameItem src, const txEnv* env) {
uint_fast32_t i = read32(&src);
if (writeBit(dst, i < env->tx->numInputs)) {
const sigInput* input = &env->tx->input[i];
if (writeBit(dst, NO_ISSUANCE != input->issuance.type)) {
writeHash(dst, &input->issuance.tokenId);
} else {
skipBits(dst, 256);
}
} else {
skipBits(dst, 257);
}
return true;
}
bool output_amounts_hash(frameItem* dst, frameItem src, const txEnv* env) {
(void) src; writeHash(dst, &env->tx->outputAssetAmountsHash);
return true;
}
bool output_nonces_hash(frameItem* dst, frameItem src, const txEnv* env) {
(void) src; writeHash(dst, &env->tx->outputNoncesHash);
return true;
}
bool output_scripts_hash(frameItem* dst, frameItem src, const txEnv* env) {
(void) src; writeHash(dst, &env->tx->outputScriptsHash);
return true;
}
bool output_range_proofs_hash(frameItem* dst, frameItem src, const txEnv* env) {
(void) src; writeHash(dst, &env->tx->outputRangeProofsHash);
return true;
}
bool output_surjection_proofs_hash(frameItem* dst, frameItem src, const txEnv* env) {
(void) src; writeHash(dst, &env->tx->outputSurjectionProofsHash);
return true;
}
bool outputs_hash(frameItem* dst, frameItem src, const txEnv* env) {
(void) src; writeHash(dst, &env->tx->outputsHash);
return true;
}
bool input_outpoints_hash(frameItem* dst, frameItem src, const txEnv* env) {
(void) src; writeHash(dst, &env->tx->inputOutpointsHash);
return true;
}
bool input_amounts_hash(frameItem* dst, frameItem src, const txEnv* env) {
(void) src; writeHash(dst, &env->tx->inputAssetAmountsHash);
return true;
}
bool input_scripts_hash(frameItem* dst, frameItem src, const txEnv* env) {
(void) src; writeHash(dst, &env->tx->inputScriptsHash);
return true;
}
bool input_utxos_hash(frameItem* dst, frameItem src, const txEnv* env) {
(void) src; writeHash(dst, &env->tx->inputUTXOsHash);
return true;
}
bool input_sequences_hash(frameItem* dst, frameItem src, const txEnv* env) {
(void) src; writeHash(dst, &env->tx->inputSequencesHash);
return true;
}
bool input_annexes_hash(frameItem* dst, frameItem src, const txEnv* env) {
(void) src; writeHash(dst, &env->tx->inputAnnexesHash);
return true;
}
bool input_script_sigs_hash(frameItem* dst, frameItem src, const txEnv* env) {
(void) src; writeHash(dst, &env->tx->inputScriptSigsHash);
return true;
}
bool inputs_hash(frameItem* dst, frameItem src, const txEnv* env) {
(void) src; writeHash(dst, &env->tx->inputsHash);
return true;
}
bool issuance_asset_amounts_hash(frameItem* dst, frameItem src, const txEnv* env) {
(void) src; writeHash(dst, &env->tx->issuanceAssetAmountsHash);
return true;
}
bool issuance_token_amounts_hash(frameItem* dst, frameItem src, const txEnv* env) {
(void) src; writeHash(dst, &env->tx->issuanceTokenAmountsHash);
return true;
}
bool issuance_range_proofs_hash(frameItem* dst, frameItem src, const txEnv* env) {
(void) src; writeHash(dst, &env->tx->issuanceRangeProofsHash);
return true;
}
bool issuance_blinding_entropy_hash(frameItem* dst, frameItem src, const txEnv* env) {
(void) src; writeHash(dst, &env->tx->issuanceBlindingEntropyHash);
return true;
}
bool issuances_hash(frameItem* dst, frameItem src, const txEnv* env) {
(void) src; writeHash(dst, &env->tx->issuancesHash);
return true;
}
bool tx_hash(frameItem* dst, frameItem src, const txEnv* env) {
(void) src; writeHash(dst, &env->tx->txHash);
return true;
}
bool tapleaf_hash(frameItem* dst, frameItem src, const txEnv* env) {
(void) src; writeHash(dst, &env->taproot->tapLeafHash);
return true;
}
bool tappath_hash(frameItem* dst, frameItem src, const txEnv* env) {
(void) src; writeHash(dst, &env->taproot->tappathHash);
return true;
}
bool tap_env_hash(frameItem* dst, frameItem src, const txEnv* env) {
(void) src; writeHash(dst, &env->taproot->tapEnvHash);
return true;
}
bool sig_all_hash(frameItem* dst, frameItem src, const txEnv* env) {
(void) src; writeHash(dst, &env->sigAllHash);
return true;
}