mirror of
https://github.com/ElementsProject/elements.git
synced 2026-08-15 12:51:00 +02:00
6d503ea4f8 Rename elements/jets.c c68063f9ef Add testcases that are an even multiple of 1000 milliWU 92887000e6 Add minCost parameter 82d6260ed8 Remove intermedite primitive directory 09b4eee340 Make raw environment struct tags elements specific a93cd359df Make environment struct tags elements specific 26de216e24 Make primitive.h functions indirect 35d188a247 rename elementsJets.* to jets.* 7fd6dbe2ca simplicity_computeCmr -> simplicity_elements_computeCmr git-subtree-dir: src/simplicity git-subtree-split: 6d503ea4f8859ec63ad22a22c0ccef067b1a0b5d
180 lines
5.6 KiB
C
180 lines
5.6 KiB
C
#include "ops.h"
|
|
|
|
/* Add an 'confidential' value to be consumed by an ongoing SHA-256 evaluation.
|
|
* If the 'confidential' value is blinded, then the 'evenPrefix' used if the y coordinate is even,
|
|
* and the 'oddPrefix' is used if the y coordinate is odd.
|
|
* If the 'confidential' value is explicit, then '0x01' is used as the prefix.
|
|
* If the 'confidential' value is "NULL" then only '0x00' added.
|
|
*
|
|
* Precondition: NULL != ctx;
|
|
* NULL != conf;
|
|
*/
|
|
void simplicity_sha256_confidential(unsigned char evenPrefix, unsigned char oddPrefix, sha256_context* ctx, const confidential* conf) {
|
|
switch (conf->prefix) {
|
|
case NONE: sha256_uchar(ctx, 0x00); return;
|
|
case EXPLICIT: sha256_uchar(ctx, 0x01); break;
|
|
case EVEN_Y: sha256_uchar(ctx, evenPrefix); break;
|
|
case ODD_Y: sha256_uchar(ctx, oddPrefix); break;
|
|
}
|
|
sha256_hash(ctx, &conf->data);
|
|
}
|
|
|
|
/* Add an 'confidential' asset to be consumed by an ongoing SHA-256 evaluation.
|
|
*
|
|
* Precondition: NULL != ctx;
|
|
* NULL != asset;
|
|
*/
|
|
void simplicity_sha256_confAsset(sha256_context* ctx, const confidential* asset) {
|
|
simplicity_sha256_confidential(0x0a, 0x0b, ctx, asset);
|
|
}
|
|
|
|
/* Add an 'confidential' nonce to be consumed by an ongoing SHA-256 evaluation.
|
|
*
|
|
* Precondition: NULL != ctx;
|
|
* NULL != nonce;
|
|
*/
|
|
void simplicity_sha256_confNonce(sha256_context* ctx, const confidential* nonce) {
|
|
simplicity_sha256_confidential(0x02, 0x03, ctx, nonce);
|
|
}
|
|
|
|
/* Add an 'confidential' amount to be consumed by an ongoing SHA-256 evaluation.
|
|
*
|
|
* Precondition: NULL != ctx;
|
|
* NULL != amt;
|
|
*/
|
|
void simplicity_sha256_confAmt(sha256_context* ctx, const confAmount* amt) {
|
|
switch (amt->prefix) {
|
|
case NONE: SIMPLICITY_UNREACHABLE;
|
|
case EXPLICIT:
|
|
sha256_uchar(ctx, 0x01);
|
|
sha256_u64be(ctx, amt->explicit);
|
|
return;
|
|
case EVEN_Y:
|
|
case ODD_Y:
|
|
sha256_uchar(ctx, EVEN_Y == amt->prefix ? 0x08 : 0x09);
|
|
sha256_hash(ctx, &amt->confidential);
|
|
return;
|
|
}
|
|
}
|
|
|
|
/* Compute an Element's entropy value from a prevoutpoint and a contract hash.
|
|
* A reimplementation of GenerateAssetEntropy from Element's 'issuance.cpp'.
|
|
*
|
|
* Precondition: NULL != op;
|
|
* NULL != contract;
|
|
*/
|
|
sha256_midstate simplicity_generateIssuanceEntropy(const outpoint* op, const sha256_midstate* contract) {
|
|
uint32_t block[16];
|
|
unsigned char buf[32];
|
|
sha256_midstate result;
|
|
|
|
/* First hash the outpoint data. */
|
|
{
|
|
sha256_context ctx = sha256_init(result.s);
|
|
sha256_fromMidstate(buf, op->txid.s);
|
|
sha256_uchars(&ctx, buf, 32);
|
|
sha256_u32le(&ctx, op->ix);
|
|
sha256_finalize(&ctx);
|
|
}
|
|
/* Fill in the first half of the block with the double hashed outpoint data. */
|
|
{
|
|
sha256_context ctx = sha256_init(&block[0]);
|
|
sha256_fromMidstate(buf, result.s);
|
|
sha256_uchars(&ctx, buf, 32);
|
|
sha256_finalize(&ctx);
|
|
}
|
|
|
|
memcpy(&block[8], contract->s, sizeof(contract->s));
|
|
sha256_iv(result.s);
|
|
simplicity_sha256_compression(result.s, block);
|
|
|
|
return result;
|
|
}
|
|
|
|
/* Compute an Element's issuance Asset ID value from an entropy value.
|
|
* A reimplementation of CalculateAsset from Element's 'issuance.cpp'.
|
|
*
|
|
* Precondition: NULL != entropy;
|
|
*/
|
|
sha256_midstate simplicity_calculateAsset(const sha256_midstate* entropy) {
|
|
uint32_t block[16] = {0};
|
|
sha256_midstate result;
|
|
|
|
memcpy(&block[0], entropy->s, sizeof(entropy->s));
|
|
sha256_iv(result.s);
|
|
simplicity_sha256_compression(result.s, block);
|
|
|
|
return result;
|
|
}
|
|
|
|
/* Compute an Element's issuance Token ID value from an entropy value and an amount prefix.
|
|
* A reimplementation of CalculateReissuanceToken from Element's 'issuance.cpp'.
|
|
*
|
|
* Precondition: NULL != entropy;
|
|
*/
|
|
sha256_midstate simplicity_calculateToken(const sha256_midstate* entropy, confPrefix prefix) {
|
|
uint32_t block[16] = {0};
|
|
sha256_midstate result;
|
|
|
|
memcpy(&block[0], entropy->s, sizeof(entropy->s));
|
|
block[8] = is_confidential(prefix) ? 0x02000000 : 0x01000000;
|
|
sha256_iv(result.s);
|
|
simplicity_sha256_compression(result.s, block);
|
|
|
|
return result;
|
|
}
|
|
|
|
/* Compute an Element's tapleaf hash from a tapleaf version and a 256-bit script value.
|
|
* A reimplementation of ComputeTapleafHash from Element's 'interpreter.cpp'.
|
|
* Only 256-bit script values are supported as that is the size used for Simplicity CMRs.
|
|
*
|
|
* Precondition: NULL != cmr;
|
|
*/
|
|
sha256_midstate simplicity_make_tapleaf(unsigned char version, const sha256_midstate* cmr) {
|
|
sha256_midstate result;
|
|
sha256_midstate tapleafTag;
|
|
{
|
|
static unsigned char tagName[] = "TapLeaf/elements";
|
|
sha256_context ctx = sha256_init(tapleafTag.s);
|
|
sha256_uchars(&ctx, tagName, sizeof(tagName) - 1);
|
|
sha256_finalize(&ctx);
|
|
}
|
|
sha256_context ctx = sha256_init(result.s);
|
|
sha256_hash(&ctx, &tapleafTag);
|
|
sha256_hash(&ctx, &tapleafTag);
|
|
sha256_uchar(&ctx, version);
|
|
sha256_uchar(&ctx, 32);
|
|
sha256_hash(&ctx, cmr);
|
|
sha256_finalize(&ctx);
|
|
|
|
return result;
|
|
}
|
|
|
|
/* Compute an Element's tapbrach hash from two branches.
|
|
*
|
|
* Precondition: NULL != a;
|
|
* NULL != b;
|
|
*/
|
|
sha256_midstate simplicity_make_tapbranch(const sha256_midstate* a, const sha256_midstate* b) {
|
|
sha256_midstate result;
|
|
sha256_midstate tapbranchTag;
|
|
{
|
|
static unsigned char tagName[] = "TapBranch/elements";
|
|
sha256_context ctx = sha256_init(tapbranchTag.s);
|
|
sha256_uchars(&ctx, tagName, sizeof(tagName) - 1);
|
|
sha256_finalize(&ctx);
|
|
}
|
|
sha256_context ctx = sha256_init(result.s);
|
|
sha256_hash(&ctx, &tapbranchTag);
|
|
sha256_hash(&ctx, &tapbranchTag);
|
|
if (sha256_cmp_be(a, b) < 0) {
|
|
sha256_hash(&ctx, a);
|
|
sha256_hash(&ctx, b);
|
|
} else {
|
|
sha256_hash(&ctx, b);
|
|
sha256_hash(&ctx, a);
|
|
}
|
|
sha256_finalize(&ctx);
|
|
|
|
return result;
|
|
}
|