From 1c871c8c20a0c097232126c7d00297f2c397cfe8 Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Mon, 20 Jan 2025 21:51:40 +0000 Subject: [PATCH 01/22] interpreter: fix use-after-free in Simplicity init code We have the code fragment `txTo.GetHash().begin()`, which takes a transaction, computes its txid as a uint256, and then saves a pointer to the internal data of the uint256. However, in C++, expressions of the form a.b().c() lead to the return value of `b` being dropped immediately after the call to `c`. This is fine if `c` is something like `GetHex` which returns a new independently allocated object with no pointers to its input. It is not fine for `begin` which returns a pointer into the return value of `GetHash`. So this fragment returns a dangling pointer, which is later used by the Simplicity interpreter, leading to UB. In practice this code appeared to work, possibly because the stack layout was such that it actually did work ok. Or possibly because we don't test with enough fidelity to tell that Simplicity's view of the txid of a transaction was mangled. --- src/script/interpreter.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index 5945356439..1f24c69c1f 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -2660,7 +2660,8 @@ void PrecomputedTransactionData::Init(const T& txTo, std::vector&& spent } rawTransaction simplicityRawTx; - simplicityRawTx.txid = txTo.GetHash().begin(); + uint256 rawHash = txTo.GetHash(); + simplicityRawTx.txid = rawHash.begin(); simplicityRawTx.input = simplicityRawInput.data(); simplicityRawTx.numInputs = simplicityRawInput.size(); simplicityRawTx.output = simplicityRawOutput.data(); From b1b4e6d5c9ef056ca31936431364c94c5ab5b257 Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Mon, 20 Jan 2025 21:50:35 +0000 Subject: [PATCH 02/22] Sanitize libsimplicity Without this patch, the --with-sanitizers config flag has no effect on the copy of libsimplicity in Elements Core. This means that we aren't running asan or tsan when we intend to, and also means that when fuzzing we aren't instrumenting the Simplicity binary. The result is extremely bad fuzz coverage and missed bugs. ubsan suppression for simplicity sha256.c ubsan detects when a left shift would overflow an integer type. This is not UB (it would be if you tried to shift more than the type's width in one shot) but "may be unintentional" and is therefore detected. Add a whitelist to the giant list of whitelists. --- src/Makefile.elementssimplicity.include | 2 +- test/sanitizer_suppressions/ubsan | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Makefile.elementssimplicity.include b/src/Makefile.elementssimplicity.include index 2a6c06fc49..f1e5421957 100644 --- a/src/Makefile.elementssimplicity.include +++ b/src/Makefile.elementssimplicity.include @@ -3,4 +3,4 @@ include simplicity/elements-sources.mk LIBELEMENTSSIMPLICITY = libelementssimplicity.la noinst_LTLIBRARIES += $(LIBELEMENTSSIMPLICITY) libelementssimplicity_la_SOURCES = $(ELEMENTS_SIMPLICITY_LIB_SOURCES_INT) $(ELEMENTS_SIMPLICITY_DIST_HEADERS_INT) $(ELEMENTS_SIMPLICITY_LIB_HEADERS_INT) -libelementssimplicity_la_CPPFLAGS = $(AM_CPPFLAGS) $(SHANI_CXXFLAGS) -I$(srcdir)/$(ELEMENTS_SIMPLICITY_INCLUDE_DIR_INT) +libelementssimplicity_la_CPPFLAGS = $(AM_CPPFLAGS) $(SHANI_CXXFLAGS) $(SANITIZER_CXXFLAGS) -I$(srcdir)/$(ELEMENTS_SIMPLICITY_INCLUDE_DIR_INT) diff --git a/test/sanitizer_suppressions/ubsan b/test/sanitizer_suppressions/ubsan index 2d5df53f75..682ec7f60b 100644 --- a/test/sanitizer_suppressions/ubsan +++ b/test/sanitizer_suppressions/ubsan @@ -79,3 +79,5 @@ implicit-integer-sign-change:blech32.cpp implicit-integer-sign-change:primitives/block.h implicit-integer-sign-change:primitives/confidential.cpp implicit-integer-sign-change:primitives/confidential.h +shift-base:simplicity/sha256.c +unsigned-integer-overflow:simplicity/sha256.c From 3b60583dd2c4ffe8e341a65f6115bae2c031f83f Mon Sep 17 00:00:00 2001 From: Russell O'Connor Date: Fri, 31 Jan 2025 11:44:47 -0500 Subject: [PATCH 03/22] Squashed 'src/simplicity/' changes from 86ac0f92c4..c2d4c3d07b c2d4c3d07b Update elements-sources.mk 5ba4a709ac Add explicit deallocation functions to the Simplicity API fd3a1a7c3f Fix comments e10d34fa49 Clarify comment about illegal hidden children 3b55e8150e Rename STOP code error message f67d1ad145 Generate contents of decodePrimitive automatically 991fddcb6a Correctly name identity hashes a840706c2f Static asserts on imr_buf not needed 7e91641218 Prep C code for VST proving git-subtree-dir: src/simplicity git-subtree-split: c2d4c3d07bb7e5973fc22cf172ed8fb9a84b4365 --- ctx8Pruned.c | 4 +- ctx8Pruned.h | 4 +- ctx8Unpruned.c | 4 +- ctx8Unpruned.h | 4 +- dag.c | 74 +- dag.h | 8 +- decodeCoreJets.inc | 1037 +++++++++++++++++++ deserialize.c | 14 +- deserialize.h | 4 +- elements-sources.mk | 2 + hashBlock.c | 4 +- hashBlock.h | 4 +- include/simplicity/elements/env.h | 13 +- include/simplicity/elements/exec.h | 9 +- include/simplicity/errorCodes.h | 8 +- primitive/elements/checkSigHashAllTx1.c | 4 +- primitive/elements/checkSigHashAllTx1.h | 4 +- primitive/elements/decodeElementsJets.inc | 136 +++ primitive/elements/env.c | 15 +- primitive/elements/exec.c | 17 +- primitive/elements/primitive.c | 1097 +-------------------- schnorr0.c | 4 +- schnorr0.h | 4 +- schnorr6.c | 4 +- schnorr6.h | 4 +- secp256k1/int128_struct.h | 2 +- secp256k1/modinv64.h | 16 +- secp256k1/modinv64_impl.h | 10 +- secp256k1/precomputed_ecmult.h | 16 +- test.c | 46 +- typeSkipTest.c | 4 +- typeSkipTest.h | 4 +- 32 files changed, 1352 insertions(+), 1228 deletions(-) create mode 100644 decodeCoreJets.inc create mode 100644 primitive/elements/decodeElementsJets.inc diff --git a/ctx8Pruned.c b/ctx8Pruned.c index cc8488ec12..c396381671 100644 --- a/ctx8Pruned.c +++ b/ctx8Pruned.c @@ -270,8 +270,8 @@ const uint32_t ctx8Pruned_cmr[] = { 0x7f11746fu, 0xb68fdaedu, 0x3cadda80u, 0xc7cd0245u, 0xa341b927u, 0xe98e60f8u, 0x745dc441u, 0xe11ce1a3u }; -/* The identity Merkle root of the above ctx8Pruned Simplicity expression. */ -const uint32_t ctx8Pruned_imr[] = { +/* The identity hash of the root of the above ctx8Pruned Simplicity expression. */ +const uint32_t ctx8Pruned_ihr[] = { 0x8e8742acu, 0x27f42d29u, 0xd87f5229u, 0x02bc0ae2u, 0xbcfc1298u, 0x1641a2ddu, 0x77091830u, 0xb79bf12du }; diff --git a/ctx8Pruned.h b/ctx8Pruned.h index 7b66bdbeca..26d107b28d 100644 --- a/ctx8Pruned.h +++ b/ctx8Pruned.h @@ -18,8 +18,8 @@ extern const size_t sizeof_ctx8Pruned_witness; /* The commitment Merkle root of the above ctx8Pruned Simplicity expression. */ extern const uint32_t ctx8Pruned_cmr[]; -/* The identity Merkle root of the above ctx8Pruned Simplicity expression. */ -extern const uint32_t ctx8Pruned_imr[]; +/* The identity hash of the root of the above ctx8Pruned Simplicity expression. */ +extern const uint32_t ctx8Pruned_ihr[]; /* The annotated Merkle root of the above ctx8Pruned Simplicity expression. */ extern const uint32_t ctx8Pruned_amr[]; diff --git a/ctx8Unpruned.c b/ctx8Unpruned.c index b92bc2e4d7..e9c4a9bb89 100644 --- a/ctx8Unpruned.c +++ b/ctx8Unpruned.c @@ -260,8 +260,8 @@ const uint32_t ctx8Unpruned_cmr[] = { 0x7f11746fu, 0xb68fdaedu, 0x3cadda80u, 0xc7cd0245u, 0xa341b927u, 0xe98e60f8u, 0x745dc441u, 0xe11ce1a3u }; -/* The identity Merkle root of the above ctx8Unpruned Simplicity expression. */ -const uint32_t ctx8Unpruned_imr[] = { +/* The identity hash of the root of the above ctx8Unpruned Simplicity expression. */ +const uint32_t ctx8Unpruned_ihr[] = { 0x8e8742acu, 0x27f42d29u, 0xd87f5229u, 0x02bc0ae2u, 0xbcfc1298u, 0x1641a2ddu, 0x77091830u, 0xb79bf12du }; diff --git a/ctx8Unpruned.h b/ctx8Unpruned.h index 8024e33c2b..5af8deab76 100644 --- a/ctx8Unpruned.h +++ b/ctx8Unpruned.h @@ -18,8 +18,8 @@ extern const size_t sizeof_ctx8Unpruned_witness; /* The commitment Merkle root of the above ctx8Unpruned Simplicity expression. */ extern const uint32_t ctx8Unpruned_cmr[]; -/* The identity Merkle root of the above ctx8Unpruned Simplicity expression. */ -extern const uint32_t ctx8Unpruned_imr[]; +/* The identity hash of the root of the above ctx8Unpruned Simplicity expression. */ +extern const uint32_t ctx8Unpruned_ihr[]; /* The annotated Merkle root of the above ctx8Unpruned Simplicity expression. */ extern const uint32_t ctx8Unpruned_amr[]; diff --git a/dag.c b/dag.c index 0b604a2a37..bfcf561b02 100644 --- a/dag.c +++ b/dag.c @@ -77,16 +77,16 @@ static sha256_midstate amrIV(tag_t tag) { SIMPLICITY_UNREACHABLE; } -/* Given the IMR of a jet specification, return the CMR for a jet that implements that specification. +/* Given the identity hash of a jet specification, return the CMR for a jet that implements that specification. * - * Precondition: uint32_t imr[8] + * Precondition: uint32_t ih[8] */ -static sha256_midstate mkJetCMR(uint32_t *imr, uint_fast64_t weight) { +static sha256_midstate mkJetCMR(uint32_t *ih, uint_fast64_t weight) { sha256_midstate result = jetIV; uint32_t block[16] = {0}; block[6] = (uint32_t)(weight >> 32); block[7] = (uint32_t)weight; - memcpy(&block[8], imr, sizeof(uint32_t[8])); + memcpy(&block[8], ih, sizeof(uint32_t[8])); simplicity_sha256_compression(result.s, block); return result; @@ -100,7 +100,7 @@ sha256_midstate simplicity_computeWordCMR(const bitstring* value, size_t n) { /* 'stack' is an array of 30 hashes consisting of 8 'uint32_t's each. */ uint32_t stack[8*30] = {0}; uint32_t *stack_ptr = stack; - sha256_midstate imr = identityIV; + sha256_midstate ih = identityIV; simplicity_assert(n < 32); simplicity_assert((size_t)1 << n == value->len); /* Pass 1: Compute the CMR for the expression that writes 'value'. @@ -135,14 +135,14 @@ sha256_midstate simplicity_computeWordCMR(const bitstring* value, size_t n) { /* value->len is a power of 2.*/ simplicity_assert(stack_ptr == stack + 8); - /* Pass 2: Compute the IMR for the expression by adding the type roots of ONE and TWO^(2^n) to the CMR. */ - simplicity_sha256_compression(imr.s, stack); + /* Pass 2: Compute the identity hash for the expression by adding the type roots of ONE and TWO^(2^n) to the CMR. */ + simplicity_sha256_compression(ih.s, stack); memcpy(&stack[0], word_type_root[0].s, sizeof(uint32_t[8])); memcpy(&stack[8], word_type_root[n+1].s, sizeof(uint32_t[8])); - simplicity_sha256_compression(imr.s, stack); + simplicity_sha256_compression(ih.s, stack); - /* Pass 3: Compute the jet's CMR from the specificion's IMR. */ - return mkJetCMR(imr.s, ((uint_fast64_t)1 << n)); + /* Pass 3: Compute the jet's CMR from the specificion's identity hash. */ + return mkJetCMR(ih.s, ((uint_fast64_t)1 << n)); } /* Given a well-formed dag[i + 1], such that for all 'j', 0 <= 'j' < 'i', @@ -192,21 +192,21 @@ void simplicity_computeCommitmentMerkleRoot(dag_node* dag, const uint_fast32_t i } } -/* Computes the identity Merkle roots of every subexpression in a well-typed 'dag' with witnesses. - * 'imr[i]' is set to the identity Merkle root of the subexpression 'dag[i]'. - * When 'HIDDEN == dag[i].tag', then 'imr[i]' is instead set to a hidden root hash for that hidden node. +/* Computes the identity hash roots of every subexpression in a well-typed 'dag' with witnesses. + * 'ihr[i]' is set to the identity hash of the root of the subexpression 'dag[i]'. + * When 'HIDDEN == dag[i].tag', then 'ihr[i]' is instead set to a hidden root hash for that hidden node. * - * Precondition: sha256_midstate imr[len]; + * Precondition: sha256_midstate ihr[len]; * dag_node dag[len] and 'dag' is well-typed with 'type_dag' and contains witnesses. */ -static void computeIdentityMerkleRoot(sha256_midstate* imr, const dag_node* dag, const type* type_dag, const uint_fast32_t len) { +static void computeIdentityHashRoots(sha256_midstate* ihr, const dag_node* dag, const type* type_dag, const uint_fast32_t len) { /* Pass 1 */ for (size_t i = 0; i < len; ++i) { uint32_t block[16] = {0}; size_t j = 8; /* For jets, the first pass identity Merkle root is the same as their commitment Merkle root. */ - imr[i] = HIDDEN == dag[i].tag ? dag[i].cmr + ihr[i] = HIDDEN == dag[i].tag ? dag[i].cmr : JET == dag[i].tag ? dag[i].cmr : WORD == dag[i].tag ? dag[i].cmr : imrIV(dag[i].tag); @@ -214,7 +214,7 @@ static void computeIdentityMerkleRoot(sha256_midstate* imr, const dag_node* dag, case WITNESS: simplicity_sha256_bitstring(block, &dag[i].compactValue); memcpy(block + 8, type_dag[WITNESS_B(dag, type_dag, i)].typeMerkleRoot.s, sizeof(uint32_t[8])); - simplicity_sha256_compression(imr[i].s, block); + simplicity_sha256_compression(ihr[i].s, block); break; case COMP: case ASSERTL: @@ -222,15 +222,15 @@ static void computeIdentityMerkleRoot(sha256_midstate* imr, const dag_node* dag, case CASE: case PAIR: case DISCONNECT: - memcpy(block + j, imr[dag[i].child[1]].s, sizeof(uint32_t[8])); + memcpy(block + j, ihr[dag[i].child[1]].s, sizeof(uint32_t[8])); j = 0; /*@fallthrough@*/ case INJL: case INJR: case TAKE: case DROP: - memcpy(block + j, imr[dag[i].child[0]].s, sizeof(uint32_t[8])); - simplicity_sha256_compression(imr[i].s, block); + memcpy(block + j, ihr[dag[i].child[0]].s, sizeof(uint32_t[8])); + simplicity_sha256_compression(ihr[i].s, block); case IDEN: case UNIT: case HIDDEN: @@ -245,16 +245,16 @@ static void computeIdentityMerkleRoot(sha256_midstate* imr, const dag_node* dag, uint32_t block[16] = {0}; if (HIDDEN == dag[i].tag) { - memcpy(block + 8, imr[i].s, sizeof(uint32_t[8])); - imr[i] = hiddenIV; - simplicity_sha256_compression(imr[i].s, block); + memcpy(block + 8, ihr[i].s, sizeof(uint32_t[8])); + ihr[i] = hiddenIV; + simplicity_sha256_compression(ihr[i].s, block); } else { - memcpy(block + 8, imr[i].s, sizeof(uint32_t[8])); - imr[i] = identityIV; - simplicity_sha256_compression(imr[i].s, block); + memcpy(block + 8, ihr[i].s, sizeof(uint32_t[8])); + ihr[i] = identityIV; + simplicity_sha256_compression(ihr[i].s, block); memcpy(block, type_dag[dag[i].sourceType].typeMerkleRoot.s, sizeof(uint32_t[8])); memcpy(block + 8, type_dag[dag[i].targetType].typeMerkleRoot.s, sizeof(uint32_t[8])); - simplicity_sha256_compression(imr[i].s, block); + simplicity_sha256_compression(ihr[i].s, block); } } } @@ -559,30 +559,30 @@ simplicity_err simplicity_fillWitnessData(dag_node* dag, type* type_dag, const u return SIMPLICITY_NO_ERROR; } -/* Verifies that identity Merkle roots of every subexpression in a well-typed 'dag' with witnesses are all unique, +/* Verifies that identity hash of every subexpression in a well-typed 'dag' with witnesses are all unique, * including that each hidden root hash for every 'HIDDEN' node is unique. * - * if 'imr' is not NULL, then '*imr' is set to the identity Merkle root of the 'dag'. + * if 'ihr' is not NULL, then '*ihr' is set to the identity hash of the root of the 'dag'. * * If malloc fails, returns 'SIMPLICITY_ERR_MALLOC'. - * If all the identity Merkle roots (and hidden roots) are all unique, returns 'SIMPLICITY_NO_ERROR'. + * If all the identity hahes (and hidden roots) are all unique, returns 'SIMPLICITY_NO_ERROR'. * Otherwise returns 'SIMPLICITY_ERR_UNSHARED_SUBEXPRESSION'. * * Precondition: dag_node dag[len] and 'dag' is well-typed with 'type_dag' and contains witnesses. */ -simplicity_err simplicity_verifyNoDuplicateIdentityRoots(sha256_midstate* imr, const dag_node* dag, const type* type_dag, const uint_fast32_t dag_len) { +simplicity_err simplicity_verifyNoDuplicateIdentityHashes(sha256_midstate* ihr, const dag_node* dag, const type* type_dag, const uint_fast32_t dag_len) { simplicity_assert(0 < dag_len); simplicity_assert(dag_len <= DAG_LEN_MAX); - sha256_midstate* imr_buf = simplicity_malloc((size_t)dag_len * sizeof(sha256_midstate)); - if (!imr_buf) return SIMPLICITY_ERR_MALLOC; + sha256_midstate* ih_buf = simplicity_malloc((size_t)dag_len * sizeof(sha256_midstate)); + if (!ih_buf) return SIMPLICITY_ERR_MALLOC; - computeIdentityMerkleRoot(imr_buf, dag, type_dag, dag_len); + computeIdentityHashRoots(ih_buf, dag, type_dag, dag_len); - if (imr) *imr = imr_buf[dag_len-1]; + if (ihr) *ihr = ih_buf[dag_len-1]; - int result = simplicity_hasDuplicates(imr_buf, dag_len); + int result = simplicity_hasDuplicates(ih_buf, dag_len); - simplicity_free(imr_buf); + simplicity_free(ih_buf); switch (result) { case -1: return SIMPLICITY_ERR_MALLOC; diff --git a/dag.h b/dag.h index f2f9cd2701..afe0d44eb7 100644 --- a/dag.h +++ b/dag.h @@ -377,17 +377,17 @@ simplicity_err simplicity_verifyCanonicalOrder(dag_node* dag, const uint_fast32_ */ simplicity_err simplicity_fillWitnessData(dag_node* dag, type* type_dag, const uint_fast32_t len, bitstream *witness); -/* Verifies that identity Merkle roots of every subexpression in a well-typed 'dag' with witnesses are all unique, +/* Verifies that identity hash of every subexpression in a well-typed 'dag' with witnesses are all unique, * including that each hidden root hash for every 'HIDDEN' node is unique. * - * if 'imr' is not NULL, then '*imr' is set to the identity Merkle root of the 'dag'. + * if 'ihr' is not NULL, then '*ihr' is set to the identity hash of the root of the 'dag'. * * If malloc fails, returns 'SIMPLICITY_ERR_MALLOC'. - * If all the identity Merkle roots (and hidden roots) are all unique, returns 'SIMPLICITY_NO_ERROR'. + * If all the identity hahes (and hidden roots) are all unique, returns 'SIMPLICITY_NO_ERROR'. * Otherwise returns 'SIMPLICITY_ERR_UNSHARED_SUBEXPRESSION'. * * Precondition: dag_node dag[len] and 'dag' is well-typed with 'type_dag' and contains witnesses. */ -simplicity_err simplicity_verifyNoDuplicateIdentityRoots(sha256_midstate* imr, const dag_node* dag, const type* type_dag, const uint_fast32_t dag_len); +simplicity_err simplicity_verifyNoDuplicateIdentityHashes(sha256_midstate* ihr, const dag_node* dag, const type* type_dag, const uint_fast32_t dag_len); #endif diff --git a/decodeCoreJets.inc b/decodeCoreJets.inc new file mode 100644 index 0000000000..a38932e81b --- /dev/null +++ b/decodeCoreJets.inc @@ -0,0 +1,1037 @@ +/* This file has been automatically generated. */ + +{ + int32_t code; + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: *result = VERIFY; return SIMPLICITY_NO_ERROR; + case 2: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: *result = LOW_1; return SIMPLICITY_NO_ERROR; + case 3: *result = LOW_8; return SIMPLICITY_NO_ERROR; + case 4: *result = LOW_16; return SIMPLICITY_NO_ERROR; + case 5: *result = LOW_32; return SIMPLICITY_NO_ERROR; + case 6: *result = LOW_64; return SIMPLICITY_NO_ERROR; + } + break; + case 3: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: *result = HIGH_1; return SIMPLICITY_NO_ERROR; + case 3: *result = HIGH_8; return SIMPLICITY_NO_ERROR; + case 4: *result = HIGH_16; return SIMPLICITY_NO_ERROR; + case 5: *result = HIGH_32; return SIMPLICITY_NO_ERROR; + case 6: *result = HIGH_64; return SIMPLICITY_NO_ERROR; + } + break; + case 4: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: *result = COMPLEMENT_1; return SIMPLICITY_NO_ERROR; + case 3: *result = COMPLEMENT_8; return SIMPLICITY_NO_ERROR; + case 4: *result = COMPLEMENT_16; return SIMPLICITY_NO_ERROR; + case 5: *result = COMPLEMENT_32; return SIMPLICITY_NO_ERROR; + case 6: *result = COMPLEMENT_64; return SIMPLICITY_NO_ERROR; + } + break; + case 5: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: *result = AND_1; return SIMPLICITY_NO_ERROR; + case 3: *result = AND_8; return SIMPLICITY_NO_ERROR; + case 4: *result = AND_16; return SIMPLICITY_NO_ERROR; + case 5: *result = AND_32; return SIMPLICITY_NO_ERROR; + case 6: *result = AND_64; return SIMPLICITY_NO_ERROR; + } + break; + case 6: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: *result = OR_1; return SIMPLICITY_NO_ERROR; + case 3: *result = OR_8; return SIMPLICITY_NO_ERROR; + case 4: *result = OR_16; return SIMPLICITY_NO_ERROR; + case 5: *result = OR_32; return SIMPLICITY_NO_ERROR; + case 6: *result = OR_64; return SIMPLICITY_NO_ERROR; + } + break; + case 7: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: *result = XOR_1; return SIMPLICITY_NO_ERROR; + case 3: *result = XOR_8; return SIMPLICITY_NO_ERROR; + case 4: *result = XOR_16; return SIMPLICITY_NO_ERROR; + case 5: *result = XOR_32; return SIMPLICITY_NO_ERROR; + case 6: *result = XOR_64; return SIMPLICITY_NO_ERROR; + } + break; + case 8: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: *result = MAJ_1; return SIMPLICITY_NO_ERROR; + case 3: *result = MAJ_8; return SIMPLICITY_NO_ERROR; + case 4: *result = MAJ_16; return SIMPLICITY_NO_ERROR; + case 5: *result = MAJ_32; return SIMPLICITY_NO_ERROR; + case 6: *result = MAJ_64; return SIMPLICITY_NO_ERROR; + } + break; + case 9: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: *result = XOR_XOR_1; return SIMPLICITY_NO_ERROR; + case 3: *result = XOR_XOR_8; return SIMPLICITY_NO_ERROR; + case 4: *result = XOR_XOR_16; return SIMPLICITY_NO_ERROR; + case 5: *result = XOR_XOR_32; return SIMPLICITY_NO_ERROR; + case 6: *result = XOR_XOR_64; return SIMPLICITY_NO_ERROR; + } + break; + case 10: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: *result = CH_1; return SIMPLICITY_NO_ERROR; + case 3: *result = CH_8; return SIMPLICITY_NO_ERROR; + case 4: *result = CH_16; return SIMPLICITY_NO_ERROR; + case 5: *result = CH_32; return SIMPLICITY_NO_ERROR; + case 6: *result = CH_64; return SIMPLICITY_NO_ERROR; + } + break; + case 11: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: *result = SOME_1; return SIMPLICITY_NO_ERROR; + case 3: *result = SOME_8; return SIMPLICITY_NO_ERROR; + case 4: *result = SOME_16; return SIMPLICITY_NO_ERROR; + case 5: *result = SOME_32; return SIMPLICITY_NO_ERROR; + case 6: *result = SOME_64; return SIMPLICITY_NO_ERROR; + } + break; + case 12: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 3: *result = ALL_8; return SIMPLICITY_NO_ERROR; + case 4: *result = ALL_16; return SIMPLICITY_NO_ERROR; + case 5: *result = ALL_32; return SIMPLICITY_NO_ERROR; + case 6: *result = ALL_64; return SIMPLICITY_NO_ERROR; + } + break; + case 13: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: *result = EQ_1; return SIMPLICITY_NO_ERROR; + case 3: *result = EQ_8; return SIMPLICITY_NO_ERROR; + case 4: *result = EQ_16; return SIMPLICITY_NO_ERROR; + case 5: *result = EQ_32; return SIMPLICITY_NO_ERROR; + case 6: *result = EQ_64; return SIMPLICITY_NO_ERROR; + case 8: *result = EQ_256; return SIMPLICITY_NO_ERROR; + } + break; + case 14: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 3: *result = FULL_LEFT_SHIFT_8_1; return SIMPLICITY_NO_ERROR; + case 4: *result = FULL_LEFT_SHIFT_16_1; return SIMPLICITY_NO_ERROR; + case 5: *result = FULL_LEFT_SHIFT_32_1; return SIMPLICITY_NO_ERROR; + case 6: *result = FULL_LEFT_SHIFT_64_1; return SIMPLICITY_NO_ERROR; + } + break; + case 2: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 2: *result = FULL_LEFT_SHIFT_8_2; return SIMPLICITY_NO_ERROR; + case 3: *result = FULL_LEFT_SHIFT_16_2; return SIMPLICITY_NO_ERROR; + case 4: *result = FULL_LEFT_SHIFT_32_2; return SIMPLICITY_NO_ERROR; + case 5: *result = FULL_LEFT_SHIFT_64_2; return SIMPLICITY_NO_ERROR; + } + break; + case 3: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: *result = FULL_LEFT_SHIFT_8_4; return SIMPLICITY_NO_ERROR; + case 2: *result = FULL_LEFT_SHIFT_16_4; return SIMPLICITY_NO_ERROR; + case 3: *result = FULL_LEFT_SHIFT_32_4; return SIMPLICITY_NO_ERROR; + case 4: *result = FULL_LEFT_SHIFT_64_4; return SIMPLICITY_NO_ERROR; + } + break; + case 4: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: *result = FULL_LEFT_SHIFT_16_8; return SIMPLICITY_NO_ERROR; + case 2: *result = FULL_LEFT_SHIFT_32_8; return SIMPLICITY_NO_ERROR; + case 3: *result = FULL_LEFT_SHIFT_64_8; return SIMPLICITY_NO_ERROR; + } + break; + case 5: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: *result = FULL_LEFT_SHIFT_32_16; return SIMPLICITY_NO_ERROR; + case 2: *result = FULL_LEFT_SHIFT_64_16; return SIMPLICITY_NO_ERROR; + } + break; + case 6: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: *result = FULL_LEFT_SHIFT_64_32; return SIMPLICITY_NO_ERROR; + } + break; + } + break; + case 15: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 3: *result = FULL_RIGHT_SHIFT_8_1; return SIMPLICITY_NO_ERROR; + case 4: *result = FULL_RIGHT_SHIFT_16_1; return SIMPLICITY_NO_ERROR; + case 5: *result = FULL_RIGHT_SHIFT_32_1; return SIMPLICITY_NO_ERROR; + case 6: *result = FULL_RIGHT_SHIFT_64_1; return SIMPLICITY_NO_ERROR; + } + break; + case 2: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 2: *result = FULL_RIGHT_SHIFT_8_2; return SIMPLICITY_NO_ERROR; + case 3: *result = FULL_RIGHT_SHIFT_16_2; return SIMPLICITY_NO_ERROR; + case 4: *result = FULL_RIGHT_SHIFT_32_2; return SIMPLICITY_NO_ERROR; + case 5: *result = FULL_RIGHT_SHIFT_64_2; return SIMPLICITY_NO_ERROR; + } + break; + case 3: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: *result = FULL_RIGHT_SHIFT_8_4; return SIMPLICITY_NO_ERROR; + case 2: *result = FULL_RIGHT_SHIFT_16_4; return SIMPLICITY_NO_ERROR; + case 3: *result = FULL_RIGHT_SHIFT_32_4; return SIMPLICITY_NO_ERROR; + case 4: *result = FULL_RIGHT_SHIFT_64_4; return SIMPLICITY_NO_ERROR; + } + break; + case 4: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: *result = FULL_RIGHT_SHIFT_16_8; return SIMPLICITY_NO_ERROR; + case 2: *result = FULL_RIGHT_SHIFT_32_8; return SIMPLICITY_NO_ERROR; + case 3: *result = FULL_RIGHT_SHIFT_64_8; return SIMPLICITY_NO_ERROR; + } + break; + case 5: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: *result = FULL_RIGHT_SHIFT_32_16; return SIMPLICITY_NO_ERROR; + case 2: *result = FULL_RIGHT_SHIFT_64_16; return SIMPLICITY_NO_ERROR; + } + break; + case 6: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: *result = FULL_RIGHT_SHIFT_64_32; return SIMPLICITY_NO_ERROR; + } + break; + } + break; + case 16: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 3: *result = LEFTMOST_8_1; return SIMPLICITY_NO_ERROR; + case 4: *result = LEFTMOST_16_1; return SIMPLICITY_NO_ERROR; + case 5: *result = LEFTMOST_32_1; return SIMPLICITY_NO_ERROR; + case 6: *result = LEFTMOST_64_1; return SIMPLICITY_NO_ERROR; + } + break; + case 2: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 2: *result = LEFTMOST_8_2; return SIMPLICITY_NO_ERROR; + case 3: *result = LEFTMOST_16_2; return SIMPLICITY_NO_ERROR; + case 4: *result = LEFTMOST_32_2; return SIMPLICITY_NO_ERROR; + case 5: *result = LEFTMOST_64_2; return SIMPLICITY_NO_ERROR; + } + break; + case 3: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: *result = LEFTMOST_8_4; return SIMPLICITY_NO_ERROR; + case 2: *result = LEFTMOST_16_4; return SIMPLICITY_NO_ERROR; + case 3: *result = LEFTMOST_32_4; return SIMPLICITY_NO_ERROR; + case 4: *result = LEFTMOST_64_4; return SIMPLICITY_NO_ERROR; + } + break; + case 4: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: *result = LEFTMOST_16_8; return SIMPLICITY_NO_ERROR; + case 2: *result = LEFTMOST_32_8; return SIMPLICITY_NO_ERROR; + case 3: *result = LEFTMOST_64_8; return SIMPLICITY_NO_ERROR; + } + break; + case 5: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: *result = LEFTMOST_32_16; return SIMPLICITY_NO_ERROR; + case 2: *result = LEFTMOST_64_16; return SIMPLICITY_NO_ERROR; + } + break; + case 6: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: *result = LEFTMOST_64_32; return SIMPLICITY_NO_ERROR; + } + break; + } + break; + case 17: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 3: *result = RIGHTMOST_8_1; return SIMPLICITY_NO_ERROR; + case 4: *result = RIGHTMOST_16_1; return SIMPLICITY_NO_ERROR; + case 5: *result = RIGHTMOST_32_1; return SIMPLICITY_NO_ERROR; + case 6: *result = RIGHTMOST_64_1; return SIMPLICITY_NO_ERROR; + } + break; + case 2: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 2: *result = RIGHTMOST_8_2; return SIMPLICITY_NO_ERROR; + case 3: *result = RIGHTMOST_16_2; return SIMPLICITY_NO_ERROR; + case 4: *result = RIGHTMOST_32_2; return SIMPLICITY_NO_ERROR; + case 5: *result = RIGHTMOST_64_2; return SIMPLICITY_NO_ERROR; + } + break; + case 3: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: *result = RIGHTMOST_8_4; return SIMPLICITY_NO_ERROR; + case 2: *result = RIGHTMOST_16_4; return SIMPLICITY_NO_ERROR; + case 3: *result = RIGHTMOST_32_4; return SIMPLICITY_NO_ERROR; + case 4: *result = RIGHTMOST_64_4; return SIMPLICITY_NO_ERROR; + } + break; + case 4: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: *result = RIGHTMOST_16_8; return SIMPLICITY_NO_ERROR; + case 2: *result = RIGHTMOST_32_8; return SIMPLICITY_NO_ERROR; + case 3: *result = RIGHTMOST_64_8; return SIMPLICITY_NO_ERROR; + } + break; + case 5: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: *result = RIGHTMOST_32_16; return SIMPLICITY_NO_ERROR; + case 2: *result = RIGHTMOST_64_16; return SIMPLICITY_NO_ERROR; + } + break; + case 6: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: *result = RIGHTMOST_64_32; return SIMPLICITY_NO_ERROR; + } + break; + } + break; + case 18: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 3: *result = LEFT_PAD_LOW_1_8; return SIMPLICITY_NO_ERROR; + case 4: *result = LEFT_PAD_LOW_1_16; return SIMPLICITY_NO_ERROR; + case 5: *result = LEFT_PAD_LOW_1_32; return SIMPLICITY_NO_ERROR; + case 6: *result = LEFT_PAD_LOW_1_64; return SIMPLICITY_NO_ERROR; + } + break; + case 4: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: *result = LEFT_PAD_LOW_8_16; return SIMPLICITY_NO_ERROR; + case 2: *result = LEFT_PAD_LOW_8_32; return SIMPLICITY_NO_ERROR; + case 3: *result = LEFT_PAD_LOW_8_64; return SIMPLICITY_NO_ERROR; + } + break; + case 5: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: *result = LEFT_PAD_LOW_16_32; return SIMPLICITY_NO_ERROR; + case 2: *result = LEFT_PAD_LOW_16_64; return SIMPLICITY_NO_ERROR; + } + break; + case 6: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: *result = LEFT_PAD_LOW_32_64; return SIMPLICITY_NO_ERROR; + } + break; + } + break; + case 19: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 3: *result = LEFT_PAD_HIGH_1_8; return SIMPLICITY_NO_ERROR; + case 4: *result = LEFT_PAD_HIGH_1_16; return SIMPLICITY_NO_ERROR; + case 5: *result = LEFT_PAD_HIGH_1_32; return SIMPLICITY_NO_ERROR; + case 6: *result = LEFT_PAD_HIGH_1_64; return SIMPLICITY_NO_ERROR; + } + break; + case 4: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: *result = LEFT_PAD_HIGH_8_16; return SIMPLICITY_NO_ERROR; + case 2: *result = LEFT_PAD_HIGH_8_32; return SIMPLICITY_NO_ERROR; + case 3: *result = LEFT_PAD_HIGH_8_64; return SIMPLICITY_NO_ERROR; + } + break; + case 5: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: *result = LEFT_PAD_HIGH_16_32; return SIMPLICITY_NO_ERROR; + case 2: *result = LEFT_PAD_HIGH_16_64; return SIMPLICITY_NO_ERROR; + } + break; + case 6: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: *result = LEFT_PAD_HIGH_32_64; return SIMPLICITY_NO_ERROR; + } + break; + } + break; + case 20: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 3: *result = LEFT_EXTEND_1_8; return SIMPLICITY_NO_ERROR; + case 4: *result = LEFT_EXTEND_1_16; return SIMPLICITY_NO_ERROR; + case 5: *result = LEFT_EXTEND_1_32; return SIMPLICITY_NO_ERROR; + case 6: *result = LEFT_EXTEND_1_64; return SIMPLICITY_NO_ERROR; + } + break; + case 4: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: *result = LEFT_EXTEND_8_16; return SIMPLICITY_NO_ERROR; + case 2: *result = LEFT_EXTEND_8_32; return SIMPLICITY_NO_ERROR; + case 3: *result = LEFT_EXTEND_8_64; return SIMPLICITY_NO_ERROR; + } + break; + case 5: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: *result = LEFT_EXTEND_16_32; return SIMPLICITY_NO_ERROR; + case 2: *result = LEFT_EXTEND_16_64; return SIMPLICITY_NO_ERROR; + } + break; + case 6: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: *result = LEFT_EXTEND_32_64; return SIMPLICITY_NO_ERROR; + } + break; + } + break; + case 21: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 3: *result = RIGHT_PAD_LOW_1_8; return SIMPLICITY_NO_ERROR; + case 4: *result = RIGHT_PAD_LOW_1_16; return SIMPLICITY_NO_ERROR; + case 5: *result = RIGHT_PAD_LOW_1_32; return SIMPLICITY_NO_ERROR; + case 6: *result = RIGHT_PAD_LOW_1_64; return SIMPLICITY_NO_ERROR; + } + break; + case 4: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: *result = RIGHT_PAD_LOW_8_16; return SIMPLICITY_NO_ERROR; + case 2: *result = RIGHT_PAD_LOW_8_32; return SIMPLICITY_NO_ERROR; + case 3: *result = RIGHT_PAD_LOW_8_64; return SIMPLICITY_NO_ERROR; + } + break; + case 5: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: *result = RIGHT_PAD_LOW_16_32; return SIMPLICITY_NO_ERROR; + case 2: *result = RIGHT_PAD_LOW_16_64; return SIMPLICITY_NO_ERROR; + } + break; + case 6: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: *result = RIGHT_PAD_LOW_32_64; return SIMPLICITY_NO_ERROR; + } + break; + } + break; + case 22: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 3: *result = RIGHT_PAD_HIGH_1_8; return SIMPLICITY_NO_ERROR; + case 4: *result = RIGHT_PAD_HIGH_1_16; return SIMPLICITY_NO_ERROR; + case 5: *result = RIGHT_PAD_HIGH_1_32; return SIMPLICITY_NO_ERROR; + case 6: *result = RIGHT_PAD_HIGH_1_64; return SIMPLICITY_NO_ERROR; + } + break; + case 4: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: *result = RIGHT_PAD_HIGH_8_16; return SIMPLICITY_NO_ERROR; + case 2: *result = RIGHT_PAD_HIGH_8_32; return SIMPLICITY_NO_ERROR; + case 3: *result = RIGHT_PAD_HIGH_8_64; return SIMPLICITY_NO_ERROR; + } + break; + case 5: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: *result = RIGHT_PAD_HIGH_16_32; return SIMPLICITY_NO_ERROR; + case 2: *result = RIGHT_PAD_HIGH_16_64; return SIMPLICITY_NO_ERROR; + } + break; + case 6: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: *result = RIGHT_PAD_HIGH_32_64; return SIMPLICITY_NO_ERROR; + } + break; + } + break; + case 23: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 4: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: *result = RIGHT_EXTEND_8_16; return SIMPLICITY_NO_ERROR; + case 2: *result = RIGHT_EXTEND_8_32; return SIMPLICITY_NO_ERROR; + case 3: *result = RIGHT_EXTEND_8_64; return SIMPLICITY_NO_ERROR; + } + break; + case 5: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: *result = RIGHT_EXTEND_16_32; return SIMPLICITY_NO_ERROR; + case 2: *result = RIGHT_EXTEND_16_64; return SIMPLICITY_NO_ERROR; + } + break; + case 6: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: *result = RIGHT_EXTEND_32_64; return SIMPLICITY_NO_ERROR; + } + break; + } + break; + case 24: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 3: *result = LEFT_SHIFT_WITH_8; return SIMPLICITY_NO_ERROR; + case 4: *result = LEFT_SHIFT_WITH_16; return SIMPLICITY_NO_ERROR; + case 5: *result = LEFT_SHIFT_WITH_32; return SIMPLICITY_NO_ERROR; + case 6: *result = LEFT_SHIFT_WITH_64; return SIMPLICITY_NO_ERROR; + } + break; + case 25: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 3: *result = RIGHT_SHIFT_WITH_8; return SIMPLICITY_NO_ERROR; + case 4: *result = RIGHT_SHIFT_WITH_16; return SIMPLICITY_NO_ERROR; + case 5: *result = RIGHT_SHIFT_WITH_32; return SIMPLICITY_NO_ERROR; + case 6: *result = RIGHT_SHIFT_WITH_64; return SIMPLICITY_NO_ERROR; + } + break; + case 26: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 3: *result = LEFT_SHIFT_8; return SIMPLICITY_NO_ERROR; + case 4: *result = LEFT_SHIFT_16; return SIMPLICITY_NO_ERROR; + case 5: *result = LEFT_SHIFT_32; return SIMPLICITY_NO_ERROR; + case 6: *result = LEFT_SHIFT_64; return SIMPLICITY_NO_ERROR; + } + break; + case 27: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 3: *result = RIGHT_SHIFT_8; return SIMPLICITY_NO_ERROR; + case 4: *result = RIGHT_SHIFT_16; return SIMPLICITY_NO_ERROR; + case 5: *result = RIGHT_SHIFT_32; return SIMPLICITY_NO_ERROR; + case 6: *result = RIGHT_SHIFT_64; return SIMPLICITY_NO_ERROR; + } + break; + case 28: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 3: *result = LEFT_ROTATE_8; return SIMPLICITY_NO_ERROR; + case 4: *result = LEFT_ROTATE_16; return SIMPLICITY_NO_ERROR; + case 5: *result = LEFT_ROTATE_32; return SIMPLICITY_NO_ERROR; + case 6: *result = LEFT_ROTATE_64; return SIMPLICITY_NO_ERROR; + } + break; + case 29: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 3: *result = RIGHT_ROTATE_8; return SIMPLICITY_NO_ERROR; + case 4: *result = RIGHT_ROTATE_16; return SIMPLICITY_NO_ERROR; + case 5: *result = RIGHT_ROTATE_32; return SIMPLICITY_NO_ERROR; + case 6: *result = RIGHT_ROTATE_64; return SIMPLICITY_NO_ERROR; + } + break; + } + break; + case 2: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 3: *result = ONE_8; return SIMPLICITY_NO_ERROR; + case 4: *result = ONE_16; return SIMPLICITY_NO_ERROR; + case 5: *result = ONE_32; return SIMPLICITY_NO_ERROR; + case 6: *result = ONE_64; return SIMPLICITY_NO_ERROR; + } + break; + case 2: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 3: *result = FULL_ADD_8; return SIMPLICITY_NO_ERROR; + case 4: *result = FULL_ADD_16; return SIMPLICITY_NO_ERROR; + case 5: *result = FULL_ADD_32; return SIMPLICITY_NO_ERROR; + case 6: *result = FULL_ADD_64; return SIMPLICITY_NO_ERROR; + } + break; + case 3: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 3: *result = ADD_8; return SIMPLICITY_NO_ERROR; + case 4: *result = ADD_16; return SIMPLICITY_NO_ERROR; + case 5: *result = ADD_32; return SIMPLICITY_NO_ERROR; + case 6: *result = ADD_64; return SIMPLICITY_NO_ERROR; + } + break; + case 4: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 3: *result = FULL_INCREMENT_8; return SIMPLICITY_NO_ERROR; + case 4: *result = FULL_INCREMENT_16; return SIMPLICITY_NO_ERROR; + case 5: *result = FULL_INCREMENT_32; return SIMPLICITY_NO_ERROR; + case 6: *result = FULL_INCREMENT_64; return SIMPLICITY_NO_ERROR; + } + break; + case 5: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 3: *result = INCREMENT_8; return SIMPLICITY_NO_ERROR; + case 4: *result = INCREMENT_16; return SIMPLICITY_NO_ERROR; + case 5: *result = INCREMENT_32; return SIMPLICITY_NO_ERROR; + case 6: *result = INCREMENT_64; return SIMPLICITY_NO_ERROR; + } + break; + case 7: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 3: *result = FULL_SUBTRACT_8; return SIMPLICITY_NO_ERROR; + case 4: *result = FULL_SUBTRACT_16; return SIMPLICITY_NO_ERROR; + case 5: *result = FULL_SUBTRACT_32; return SIMPLICITY_NO_ERROR; + case 6: *result = FULL_SUBTRACT_64; return SIMPLICITY_NO_ERROR; + } + break; + case 8: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 3: *result = SUBTRACT_8; return SIMPLICITY_NO_ERROR; + case 4: *result = SUBTRACT_16; return SIMPLICITY_NO_ERROR; + case 5: *result = SUBTRACT_32; return SIMPLICITY_NO_ERROR; + case 6: *result = SUBTRACT_64; return SIMPLICITY_NO_ERROR; + } + break; + case 9: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 3: *result = NEGATE_8; return SIMPLICITY_NO_ERROR; + case 4: *result = NEGATE_16; return SIMPLICITY_NO_ERROR; + case 5: *result = NEGATE_32; return SIMPLICITY_NO_ERROR; + case 6: *result = NEGATE_64; return SIMPLICITY_NO_ERROR; + } + break; + case 10: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 3: *result = FULL_DECREMENT_8; return SIMPLICITY_NO_ERROR; + case 4: *result = FULL_DECREMENT_16; return SIMPLICITY_NO_ERROR; + case 5: *result = FULL_DECREMENT_32; return SIMPLICITY_NO_ERROR; + case 6: *result = FULL_DECREMENT_64; return SIMPLICITY_NO_ERROR; + } + break; + case 11: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 3: *result = DECREMENT_8; return SIMPLICITY_NO_ERROR; + case 4: *result = DECREMENT_16; return SIMPLICITY_NO_ERROR; + case 5: *result = DECREMENT_32; return SIMPLICITY_NO_ERROR; + case 6: *result = DECREMENT_64; return SIMPLICITY_NO_ERROR; + } + break; + case 12: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 3: *result = FULL_MULTIPLY_8; return SIMPLICITY_NO_ERROR; + case 4: *result = FULL_MULTIPLY_16; return SIMPLICITY_NO_ERROR; + case 5: *result = FULL_MULTIPLY_32; return SIMPLICITY_NO_ERROR; + case 6: *result = FULL_MULTIPLY_64; return SIMPLICITY_NO_ERROR; + } + break; + case 13: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 3: *result = MULTIPLY_8; return SIMPLICITY_NO_ERROR; + case 4: *result = MULTIPLY_16; return SIMPLICITY_NO_ERROR; + case 5: *result = MULTIPLY_32; return SIMPLICITY_NO_ERROR; + case 6: *result = MULTIPLY_64; return SIMPLICITY_NO_ERROR; + } + break; + case 14: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 3: *result = IS_ZERO_8; return SIMPLICITY_NO_ERROR; + case 4: *result = IS_ZERO_16; return SIMPLICITY_NO_ERROR; + case 5: *result = IS_ZERO_32; return SIMPLICITY_NO_ERROR; + case 6: *result = IS_ZERO_64; return SIMPLICITY_NO_ERROR; + } + break; + case 15: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 3: *result = IS_ONE_8; return SIMPLICITY_NO_ERROR; + case 4: *result = IS_ONE_16; return SIMPLICITY_NO_ERROR; + case 5: *result = IS_ONE_32; return SIMPLICITY_NO_ERROR; + case 6: *result = IS_ONE_64; return SIMPLICITY_NO_ERROR; + } + break; + case 16: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 3: *result = LE_8; return SIMPLICITY_NO_ERROR; + case 4: *result = LE_16; return SIMPLICITY_NO_ERROR; + case 5: *result = LE_32; return SIMPLICITY_NO_ERROR; + case 6: *result = LE_64; return SIMPLICITY_NO_ERROR; + } + break; + case 17: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 3: *result = LT_8; return SIMPLICITY_NO_ERROR; + case 4: *result = LT_16; return SIMPLICITY_NO_ERROR; + case 5: *result = LT_32; return SIMPLICITY_NO_ERROR; + case 6: *result = LT_64; return SIMPLICITY_NO_ERROR; + } + break; + case 18: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 3: *result = MIN_8; return SIMPLICITY_NO_ERROR; + case 4: *result = MIN_16; return SIMPLICITY_NO_ERROR; + case 5: *result = MIN_32; return SIMPLICITY_NO_ERROR; + case 6: *result = MIN_64; return SIMPLICITY_NO_ERROR; + } + break; + case 19: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 3: *result = MAX_8; return SIMPLICITY_NO_ERROR; + case 4: *result = MAX_16; return SIMPLICITY_NO_ERROR; + case 5: *result = MAX_32; return SIMPLICITY_NO_ERROR; + case 6: *result = MAX_64; return SIMPLICITY_NO_ERROR; + } + break; + case 20: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 3: *result = MEDIAN_8; return SIMPLICITY_NO_ERROR; + case 4: *result = MEDIAN_16; return SIMPLICITY_NO_ERROR; + case 5: *result = MEDIAN_32; return SIMPLICITY_NO_ERROR; + case 6: *result = MEDIAN_64; return SIMPLICITY_NO_ERROR; + } + break; + case 21: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 6: *result = DIV_MOD_128_64; return SIMPLICITY_NO_ERROR; + } + break; + case 22: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 3: *result = DIV_MOD_8; return SIMPLICITY_NO_ERROR; + case 4: *result = DIV_MOD_16; return SIMPLICITY_NO_ERROR; + case 5: *result = DIV_MOD_32; return SIMPLICITY_NO_ERROR; + case 6: *result = DIV_MOD_64; return SIMPLICITY_NO_ERROR; + } + break; + case 23: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 3: *result = DIVIDE_8; return SIMPLICITY_NO_ERROR; + case 4: *result = DIVIDE_16; return SIMPLICITY_NO_ERROR; + case 5: *result = DIVIDE_32; return SIMPLICITY_NO_ERROR; + case 6: *result = DIVIDE_64; return SIMPLICITY_NO_ERROR; + } + break; + case 24: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 3: *result = MODULO_8; return SIMPLICITY_NO_ERROR; + case 4: *result = MODULO_16; return SIMPLICITY_NO_ERROR; + case 5: *result = MODULO_32; return SIMPLICITY_NO_ERROR; + case 6: *result = MODULO_64; return SIMPLICITY_NO_ERROR; + } + break; + case 25: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 3: *result = DIVIDES_8; return SIMPLICITY_NO_ERROR; + case 4: *result = DIVIDES_16; return SIMPLICITY_NO_ERROR; + case 5: *result = DIVIDES_32; return SIMPLICITY_NO_ERROR; + case 6: *result = DIVIDES_64; return SIMPLICITY_NO_ERROR; + } + break; + } + break; + case 3: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: *result = SHA_256_BLOCK; return SIMPLICITY_NO_ERROR; + case 2: *result = SHA_256_IV; return SIMPLICITY_NO_ERROR; + case 3: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: *result = SHA_256_CTX_8_ADD_1; return SIMPLICITY_NO_ERROR; + case 2: *result = SHA_256_CTX_8_ADD_2; return SIMPLICITY_NO_ERROR; + case 3: *result = SHA_256_CTX_8_ADD_4; return SIMPLICITY_NO_ERROR; + case 4: *result = SHA_256_CTX_8_ADD_8; return SIMPLICITY_NO_ERROR; + case 5: *result = SHA_256_CTX_8_ADD_16; return SIMPLICITY_NO_ERROR; + case 6: *result = SHA_256_CTX_8_ADD_32; return SIMPLICITY_NO_ERROR; + case 7: *result = SHA_256_CTX_8_ADD_64; return SIMPLICITY_NO_ERROR; + case 8: *result = SHA_256_CTX_8_ADD_128; return SIMPLICITY_NO_ERROR; + case 9: *result = SHA_256_CTX_8_ADD_256; return SIMPLICITY_NO_ERROR; + case 10: *result = SHA_256_CTX_8_ADD_512; return SIMPLICITY_NO_ERROR; + } + break; + case 4: *result = SHA_256_CTX_8_ADD_BUFFER_511; return SIMPLICITY_NO_ERROR; + case 5: *result = SHA_256_CTX_8_FINALIZE; return SIMPLICITY_NO_ERROR; + case 6: *result = SHA_256_CTX_8_INIT; return SIMPLICITY_NO_ERROR; + } + break; + } + break; + case 4: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: *result = POINT_VERIFY_1; return SIMPLICITY_NO_ERROR; + } + break; + case 2: *result = DECOMPRESS; return SIMPLICITY_NO_ERROR; + case 3: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: *result = LINEAR_VERIFY_1; return SIMPLICITY_NO_ERROR; + } + break; + case 4: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: *result = LINEAR_COMBINATION_1; return SIMPLICITY_NO_ERROR; + } + break; + case 5: *result = SCALE; return SIMPLICITY_NO_ERROR; + case 6: *result = GENERATE; return SIMPLICITY_NO_ERROR; + case 7: *result = GEJ_INFINITY; return SIMPLICITY_NO_ERROR; + case 8: *result = GEJ_NORMALIZE; return SIMPLICITY_NO_ERROR; + case 9: *result = GEJ_NEGATE; return SIMPLICITY_NO_ERROR; + case 10: *result = GE_NEGATE; return SIMPLICITY_NO_ERROR; + case 11: *result = GEJ_DOUBLE; return SIMPLICITY_NO_ERROR; + case 12: *result = GEJ_ADD; return SIMPLICITY_NO_ERROR; + case 13: *result = GEJ_GE_ADD_EX; return SIMPLICITY_NO_ERROR; + case 14: *result = GEJ_GE_ADD; return SIMPLICITY_NO_ERROR; + case 15: *result = GEJ_RESCALE; return SIMPLICITY_NO_ERROR; + case 16: *result = GEJ_IS_INFINITY; return SIMPLICITY_NO_ERROR; + case 17: *result = GEJ_EQUIV; return SIMPLICITY_NO_ERROR; + case 18: *result = GEJ_GE_EQUIV; return SIMPLICITY_NO_ERROR; + case 19: *result = GEJ_X_EQUIV; return SIMPLICITY_NO_ERROR; + case 20: *result = GEJ_Y_IS_ODD; return SIMPLICITY_NO_ERROR; + case 21: *result = GEJ_IS_ON_CURVE; return SIMPLICITY_NO_ERROR; + case 22: *result = GE_IS_ON_CURVE; return SIMPLICITY_NO_ERROR; + case 23: *result = SCALAR_NORMALIZE; return SIMPLICITY_NO_ERROR; + case 24: *result = SCALAR_NEGATE; return SIMPLICITY_NO_ERROR; + case 25: *result = SCALAR_ADD; return SIMPLICITY_NO_ERROR; + case 26: *result = SCALAR_SQUARE; return SIMPLICITY_NO_ERROR; + case 27: *result = SCALAR_MULTIPLY; return SIMPLICITY_NO_ERROR; + case 28: *result = SCALAR_MULTIPLY_LAMBDA; return SIMPLICITY_NO_ERROR; + case 29: *result = SCALAR_INVERT; return SIMPLICITY_NO_ERROR; + case 30: *result = SCALAR_IS_ZERO; return SIMPLICITY_NO_ERROR; + case 35: *result = FE_NORMALIZE; return SIMPLICITY_NO_ERROR; + case 36: *result = FE_NEGATE; return SIMPLICITY_NO_ERROR; + case 37: *result = FE_ADD; return SIMPLICITY_NO_ERROR; + case 38: *result = FE_SQUARE; return SIMPLICITY_NO_ERROR; + case 39: *result = FE_MULTIPLY; return SIMPLICITY_NO_ERROR; + case 40: *result = FE_MULTIPLY_BETA; return SIMPLICITY_NO_ERROR; + case 41: *result = FE_INVERT; return SIMPLICITY_NO_ERROR; + case 42: *result = FE_SQUARE_ROOT; return SIMPLICITY_NO_ERROR; + case 43: *result = FE_IS_ZERO; return SIMPLICITY_NO_ERROR; + case 44: *result = FE_IS_ODD; return SIMPLICITY_NO_ERROR; + case 46: *result = HASH_TO_CURVE; return SIMPLICITY_NO_ERROR; + case 47: *result = SWU; return SIMPLICITY_NO_ERROR; + } + break; + case 5: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: *result = CHECK_SIG_VERIFY; return SIMPLICITY_NO_ERROR; + case 2: *result = BIP_0340_VERIFY; return SIMPLICITY_NO_ERROR; + } + break; + case 7: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: *result = PARSE_LOCK; return SIMPLICITY_NO_ERROR; + case 2: *result = PARSE_SEQUENCE; return SIMPLICITY_NO_ERROR; + case 3: *result = TAPDATA_INIT; return SIMPLICITY_NO_ERROR; + } + break; + } +} \ No newline at end of file diff --git a/deserialize.c b/deserialize.c index 699fc4a233..d65c0d5c5c 100644 --- a/deserialize.c +++ b/deserialize.c @@ -42,8 +42,8 @@ static simplicity_err getHash(sha256_midstate* result, bitstream* stream) { /* Decode a single node of a Simplicity dag from 'stream' into 'dag'['i']. * Returns 'SIMPLICITY_ERR_FAIL_CODE' if the encoding of a fail expression is encountered * (all fail subexpressions ought to have been pruned prior to serialization). - * Returns 'SIMPLICITY_ERR_STOP_CODE' if the encoding of a stop tag is encountered. - * Returns 'SIMPLICITY_ERR_HIDDEN' if the decoded node has illegal HIDDEN children. + * Returns 'SIMPLICITY_ERR_RESERVED_CODE' if a reserved codeword is encountered. + * Returns 'SIMPLICITY_ERR_HIDDEN' if the decoded node has a HIDDEN child in a position where it is not allowed. * Returns 'SIMPLICITY_ERR_DATA_OUT_OF_RANGE' if the node's child isn't a reference to one of the preceding nodes. * or some encoding for a non-existent jet is encountered * or the size of a WORD encoding is greater than 2^31 bits. @@ -114,7 +114,7 @@ static simplicity_err decodeNode(dag_node* dag, uint_fast32_t i, bitstream* stre case 0: dag[i].tag = IDEN; break; case 1: dag[i].tag = UNIT; break; case 2: return SIMPLICITY_ERR_FAIL_CODE; - case 3: return SIMPLICITY_ERR_STOP_CODE; + case 3: return SIMPLICITY_ERR_RESERVED_CODE; } break; case 3: @@ -143,8 +143,8 @@ static simplicity_err decodeNode(dag_node* dag, uint_fast32_t i, bitstream* stre * Returns 'SIMPLICITY_ERR_DATA_OUT_OF_RANGE' if some node's child isn't a reference to one of the preceding nodes. * Returns 'SIMPLICITY_ERR_FAIL_CODE' if the encoding of a fail expression is encountered * (all fail subexpressions ought to have been pruned prior to deserialization). - * Returns 'SIMPLICITY_ERR_STOP_CODE' if the encoding of a stop tag is encountered. - * Returns 'SIMPLICITY_ERR_HIDDEN' if there are illegal HIDDEN children in the DAG. + * Returns 'SIMPLICITY_ERR_RESERVED_CODE' if a reserved codeword is encountered. + * Returns 'SIMPLICITY_ERR_HIDDEN' if the decoded node has a HIDDEN child in a position where it is not allowed. * Returns 'SIMPLICITY_ERR_BITSTRING_EOF' if not enough bits are available in the 'stream'. * In the above error cases, 'dag' may be modified. * Returns 'SIMPLICITY_NO_ERROR' if successful. @@ -168,8 +168,8 @@ static simplicity_err decodeDag(dag_node* dag, const uint_fast32_t len, combinat * Returns 'SIMPLICITY_ERR_DATA_OUT_OF_RANGE' if some node's child isn't a reference to one of the preceding nodes. * Returns 'SIMPLICITY_ERR_FAIL_CODE' if the encoding of a fail expression is encountered * (all fail subexpressions ought to have been pruned prior to deserialization). - * Returns 'SIMPLICITY_ERR_STOP_CODE' if the encoding of a stop tag is encountered. - * Returns 'SIMPLICITY_ERR_HIDDEN' if there are illegal HIDDEN children in the DAG. + * Returns 'SIMPLICITY_ERR_RESERVED_CODE' if a reserved codeword is encountered. + * Returns 'SIMPLICITY_ERR_HIDDEN' if the decoded node has a HIDDEN child in a position where it is not allowed. * Returns 'SIMPLICITY_ERR_HIDDEN_ROOT' if the root of the DAG is a HIDDEN node. * Returns 'SIMPLICITY_ERR_BITSTRING_EOF' if not enough bits are available in the 'stream'. * Returns 'SIMPLICITY_ERR_DATA_OUT_OF_ORDER' if nodes are not serialized in the canonical order. diff --git a/deserialize.h b/deserialize.h index d0ebfb543e..d20561b011 100644 --- a/deserialize.h +++ b/deserialize.h @@ -11,8 +11,8 @@ * Returns 'SIMPLICITY_ERR_DATA_OUT_OF_RANGE' if some node's child isn't a reference to one of the preceding nodes. * Returns 'SIMPLICITY_ERR_FAIL_CODE' if the encoding of a fail expression is encountered * (all fail subexpressions ought to have been pruned prior to deserialization). - * Returns 'SIMPLICITY_ERR_STOP_CODE' if the encoding of a stop tag is encountered. - * Returns 'SIMPLICITY_ERR_HIDDEN' if there are illegal HIDDEN children in the DAG. + * Returns 'SIMPLICITY_ERR_RESERVED_CODE' if a reserved codeword is encountered. + * Returns 'SIMPLICITY_ERR_HIDDEN' if the decoded node has a HIDDEN child in a position where it is not allowed. * Returns 'SIMPLICITY_ERR_HIDDEN_ROOT' if the root of the DAG is a HIDDEN node. * Returns 'SIMPLICITY_ERR_BITSTRING_EOF' if not enough bits are available in the 'stream'. * Returns 'SIMPLICITY_ERR_MALLOC' if malloc fails. diff --git a/elements-sources.mk b/elements-sources.mk index 9c06c87a79..189a04983a 100644 --- a/elements-sources.mk +++ b/elements-sources.mk @@ -35,6 +35,7 @@ ELEMENTS_SIMPLICITY_LIB_HEADERS_INT += %reldir%/bitstream.h ELEMENTS_SIMPLICITY_LIB_HEADERS_INT += %reldir%/bitstring.h ELEMENTS_SIMPLICITY_LIB_HEADERS_INT += %reldir%/bounded.h ELEMENTS_SIMPLICITY_LIB_HEADERS_INT += %reldir%/dag.h +ELEMENTS_SIMPLICITY_LIB_HEADERS_INT += %reldir%/decodeCoreJets.inc ELEMENTS_SIMPLICITY_LIB_HEADERS_INT += %reldir%/deserialize.h ELEMENTS_SIMPLICITY_LIB_HEADERS_INT += %reldir%/eval.h ELEMENTS_SIMPLICITY_LIB_HEADERS_INT += %reldir%/frame.h @@ -88,6 +89,7 @@ ELEMENTS_SIMPLICITY_LIB_HEADERS_INT += %reldir%/secp256k1/secp256k1.h ELEMENTS_SIMPLICITY_LIB_HEADERS_INT += %reldir%/secp256k1/secp256k1_impl.h ELEMENTS_SIMPLICITY_LIB_HEADERS_INT += %reldir%/secp256k1/util.h +ELEMENTS_SIMPLICITY_LIB_HEADERS_INT += %reldir%/primitive/elements/decodeElementsJets.inc ELEMENTS_SIMPLICITY_LIB_HEADERS_INT += %reldir%/primitive/elements/elementsJets.h ELEMENTS_SIMPLICITY_LIB_HEADERS_INT += %reldir%/primitive/elements/ops.h ELEMENTS_SIMPLICITY_LIB_HEADERS_INT += %reldir%/primitive/elements/primitive.h diff --git a/hashBlock.c b/hashBlock.c index aea64c51b0..0839a5d109 100644 --- a/hashBlock.c +++ b/hashBlock.c @@ -180,8 +180,8 @@ const uint32_t hashBlock_cmr[] = { 0xa07dd7d8u, 0x22aed1adu, 0x40576a7au, 0x69fa1082u, 0x52d3dd89u, 0x539b1e4eu, 0x1f567851u, 0x9abf54e5u }; -/* The identity Merkle root of the above hashBlock Simplicity expression. */ -const uint32_t hashBlock_imr[] = { +/* The identity hash of the root of the above hashBlock Simplicity expression. */ +const uint32_t hashBlock_ihr[] = { 0x609cc145u, 0x9375db72u, 0x8f2172c9u, 0x62807e31u, 0x61df4cceu, 0xd6592d2cu, 0x4e594a77u, 0x79ab3175u }; diff --git a/hashBlock.h b/hashBlock.h index c2f7ec62fe..e4f7d57961 100644 --- a/hashBlock.h +++ b/hashBlock.h @@ -16,8 +16,8 @@ extern const size_t sizeof_hashBlock_witness; /* The commitment Merkle root of the above hashBlock Simplicity expression. */ extern const uint32_t hashBlock_cmr[]; -/* The identity Merkle root of the above hashBlock Simplicity expression. */ -extern const uint32_t hashBlock_imr[]; +/* The identity hash of the root of the above hashBlock Simplicity expression. */ +extern const uint32_t hashBlock_ihr[]; /* The annotated Merkle root of the above hashBlock Simplicity expression. */ extern const uint32_t hashBlock_amr[]; diff --git a/include/simplicity/elements/env.h b/include/simplicity/elements/env.h index 9d070c2310..e5c683f9f2 100644 --- a/include/simplicity/elements/env.h +++ b/include/simplicity/elements/env.h @@ -70,7 +70,8 @@ typedef struct rawInput { /* A structure representing data for an Elements transaction, including the TXO data of each output being redeemed. * - * Invariant: rawInput input[numInputs]; + * Invariant: unsigned char txid[32]; + * rawInput input[numInputs]; * rawOutput output[numOutputs]; */ typedef struct rawTransaction { @@ -86,13 +87,17 @@ typedef struct rawTransaction { /* A forward declaration for the structure containing a copy (and digest) of the rawTransaction data */ typedef struct transaction transaction; -/* Allocate and initialize a 'transaction' from a 'rawOutput', copying or hashing the data as needed. +/* Allocate and initialize a 'transaction' from a 'rawTransaction', copying or hashing the data as needed. * Returns NULL if malloc fails (or if malloc cannot be called because we require an allocation larger than SIZE_MAX). * * Precondition: NULL != rawTx */ extern transaction* simplicity_elements_mallocTransaction(const rawTransaction* rawTx); +/* Free a pointer to 'transaction'. + */ +extern void simplicity_elements_freeTransaction(transaction* tx); + /* A structure representing taproot spending data for an Elements transaction. * * Invariant: pathLen <= 128; @@ -114,4 +119,8 @@ typedef struct tapEnv tapEnv; * Precondition: *rawEnv is well-formed (i.e. rawEnv->pathLen <= 128.) */ extern tapEnv* simplicity_elements_mallocTapEnv(const rawTapEnv* rawEnv); + +/* Free a pointer to 'tapEnv'. + */ +extern void simplicity_elements_freeTapEnv(tapEnv* env); #endif diff --git a/include/simplicity/elements/exec.h b/include/simplicity/elements/exec.h index f083642f76..758df913a1 100644 --- a/include/simplicity/elements/exec.h +++ b/include/simplicity/elements/exec.h @@ -19,19 +19,20 @@ * * Otherwise '*error' is set to 'SIMPLICITY_NO_ERROR'. * - * If 'imr != NULL' and '*error' is set to 'SIMPLICITY_NO_ERROR', then the identity Merkle root of the decoded expression is written to 'imr'. - * Otherwise if 'imr != NULL' and '*error' is not set to 'SIMPLCITY_NO_ERROR', then 'imr' may or may not be written to. + * If 'ihr != NULL' and '*error' is set to 'SIMPLICITY_NO_ERROR', then the identity hash of the root of the decoded expression is written to 'ihr'. + * Otherwise if 'ihr != NULL' and '*error' is not set to 'SIMPLCITY_NO_ERROR', then 'ihr' may or may not be written to. * * Precondition: NULL != error; - * NULL != imr implies unsigned char imr[32] + * NULL != ihr implies unsigned char ihr[32] * NULL != tx; * NULL != taproot; * unsigned char genesisBlockHash[32] + * 0 <= budget; * NULL != amr implies unsigned char amr[32] * unsigned char program[program_len] * unsigned char witness[witness_len] */ -extern bool simplicity_elements_execSimplicity( simplicity_err* error, unsigned char* imr +extern bool simplicity_elements_execSimplicity( simplicity_err* error, unsigned char* ihr , const transaction* tx, uint_fast32_t ix, const tapEnv* taproot , const unsigned char* genesisBlockHash , int64_t budget diff --git a/include/simplicity/errorCodes.h b/include/simplicity/errorCodes.h index 8c1548e0e4..00ffee51c0 100644 --- a/include/simplicity/errorCodes.h +++ b/include/simplicity/errorCodes.h @@ -16,7 +16,7 @@ typedef enum { SIMPLICITY_ERR_DATA_OUT_OF_RANGE = -2, SIMPLICITY_ERR_DATA_OUT_OF_ORDER = -4, SIMPLICITY_ERR_FAIL_CODE = -6, - SIMPLICITY_ERR_STOP_CODE = -8, + SIMPLICITY_ERR_RESERVED_CODE = -8, SIMPLICITY_ERR_HIDDEN = -10, SIMPLICITY_ERR_BITSTREAM_EOF = -12, SIMPLICITY_ERR_BITSTREAM_TRAILING_BYTES = -14, @@ -62,10 +62,10 @@ static inline const char * SIMPLICITY_ERR_MSG(simplicity_err err) { return "Non-canonical order"; case SIMPLICITY_ERR_FAIL_CODE: return "Program has FAIL node"; - case SIMPLICITY_ERR_STOP_CODE: - return "Program has STOP node"; + case SIMPLICITY_ERR_RESERVED_CODE: + return "Program has reserved codeword"; case SIMPLICITY_ERR_HIDDEN: - return "Program has illegal HIDDEN child node"; + return "Program has node with a HIDDEN child in a position where it is not allowed"; case SIMPLICITY_ERR_BITSTREAM_EOF: return "Unexpected end of bitstream"; case SIMPLICITY_ERR_BITSTREAM_TRAILING_BYTES: diff --git a/primitive/elements/checkSigHashAllTx1.c b/primitive/elements/checkSigHashAllTx1.c index b32ef07b30..c22d6c861c 100644 --- a/primitive/elements/checkSigHashAllTx1.c +++ b/primitive/elements/checkSigHashAllTx1.c @@ -28,8 +28,8 @@ const uint32_t elementsCheckSigHashAllTx1_cmr[] = { 0xf3cd4537u, 0xd7ebb201u, 0x73220319u, 0x5b30b549u, 0xb8dc0c2cu, 0x6257b3a0u, 0xd53bedb0u, 0x8ea02874u }; -/* The identity Merkle root of the above elementsCheckSigHashAllTx1 Simplicity expression. */ -const uint32_t elementsCheckSigHashAllTx1_imr[] = { +/* The identity hash of the root of the above elementsCheckSigHashAllTx1 Simplicity expression. */ +const uint32_t elementsCheckSigHashAllTx1_ihr[] = { 0xd3a5130du, 0xf6abce06u, 0x51eb717au, 0x6dd04222u, 0xb7517651u, 0x9117ec5cu, 0x07bb9edbu, 0xac335e1bu }; diff --git a/primitive/elements/checkSigHashAllTx1.h b/primitive/elements/checkSigHashAllTx1.h index 75dd1eaa5c..b2bb7c5d9d 100644 --- a/primitive/elements/checkSigHashAllTx1.h +++ b/primitive/elements/checkSigHashAllTx1.h @@ -20,8 +20,8 @@ extern const size_t sizeof_elementsCheckSigHashAllTx1_witness; /* The commitment Merkle root of the above elementsCheckSigHashAllTx1 Simplicity expression. */ extern const uint32_t elementsCheckSigHashAllTx1_cmr[]; -/* The identity Merkle root of the above elementsCheckSigHashAllTx1 Simplicity expression. */ -extern const uint32_t elementsCheckSigHashAllTx1_imr[]; +/* The identity hash of the root of the above elementsCheckSigHashAllTx1 Simplicity expression. */ +extern const uint32_t elementsCheckSigHashAllTx1_ihr[]; /* The annotated Merkle root of the above elementsCheckSigHashAllTx1 Simplicity expression. */ extern const uint32_t elementsCheckSigHashAllTx1_amr[]; diff --git a/primitive/elements/decodeElementsJets.inc b/primitive/elements/decodeElementsJets.inc new file mode 100644 index 0000000000..b2478e45ae --- /dev/null +++ b/primitive/elements/decodeElementsJets.inc @@ -0,0 +1,136 @@ +/* This file has been automatically generated. */ + +{ + int32_t code; + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: *result = SIG_ALL_HASH; return SIMPLICITY_NO_ERROR; + case 2: *result = TX_HASH; return SIMPLICITY_NO_ERROR; + case 3: *result = TAP_ENV_HASH; return SIMPLICITY_NO_ERROR; + case 4: *result = OUTPUTS_HASH; return SIMPLICITY_NO_ERROR; + case 5: *result = INPUTS_HASH; return SIMPLICITY_NO_ERROR; + case 6: *result = ISSUANCES_HASH; return SIMPLICITY_NO_ERROR; + case 7: *result = INPUT_UTXOS_HASH; return SIMPLICITY_NO_ERROR; + case 8: *result = OUTPUT_HASH; return SIMPLICITY_NO_ERROR; + case 9: *result = OUTPUT_AMOUNTS_HASH; return SIMPLICITY_NO_ERROR; + case 10: *result = OUTPUT_SCRIPTS_HASH; return SIMPLICITY_NO_ERROR; + case 11: *result = OUTPUT_NONCES_HASH; return SIMPLICITY_NO_ERROR; + case 12: *result = OUTPUT_RANGE_PROOFS_HASH; return SIMPLICITY_NO_ERROR; + case 13: *result = OUTPUT_SURJECTION_PROOFS_HASH; return SIMPLICITY_NO_ERROR; + case 14: *result = INPUT_HASH; return SIMPLICITY_NO_ERROR; + case 15: *result = INPUT_OUTPOINTS_HASH; return SIMPLICITY_NO_ERROR; + case 16: *result = INPUT_SEQUENCES_HASH; return SIMPLICITY_NO_ERROR; + case 17: *result = INPUT_ANNEXES_HASH; return SIMPLICITY_NO_ERROR; + case 18: *result = INPUT_SCRIPT_SIGS_HASH; return SIMPLICITY_NO_ERROR; + case 19: *result = ISSUANCE_HASH; return SIMPLICITY_NO_ERROR; + case 20: *result = ISSUANCE_ASSET_AMOUNTS_HASH; return SIMPLICITY_NO_ERROR; + case 21: *result = ISSUANCE_TOKEN_AMOUNTS_HASH; return SIMPLICITY_NO_ERROR; + case 22: *result = ISSUANCE_RANGE_PROOFS_HASH; return SIMPLICITY_NO_ERROR; + case 23: *result = ISSUANCE_BLINDING_ENTROPY_HASH; return SIMPLICITY_NO_ERROR; + case 24: *result = INPUT_UTXO_HASH; return SIMPLICITY_NO_ERROR; + case 25: *result = INPUT_AMOUNTS_HASH; return SIMPLICITY_NO_ERROR; + case 26: *result = INPUT_SCRIPTS_HASH; return SIMPLICITY_NO_ERROR; + case 27: *result = TAPLEAF_HASH; return SIMPLICITY_NO_ERROR; + case 28: *result = TAPPATH_HASH; return SIMPLICITY_NO_ERROR; + case 29: *result = OUTPOINT_HASH; return SIMPLICITY_NO_ERROR; + case 30: *result = ASSET_AMOUNT_HASH; return SIMPLICITY_NO_ERROR; + case 31: *result = NONCE_HASH; return SIMPLICITY_NO_ERROR; + case 32: *result = ANNEX_HASH; return SIMPLICITY_NO_ERROR; + case 33: *result = BUILD_TAPLEAF_SIMPLICITY; return SIMPLICITY_NO_ERROR; + case 34: *result = BUILD_TAPBRANCH; return SIMPLICITY_NO_ERROR; + case 35: *result = BUILD_TAPTWEAK; return SIMPLICITY_NO_ERROR; + } + break; + case 2: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: *result = CHECK_LOCK_HEIGHT; return SIMPLICITY_NO_ERROR; + case 2: *result = CHECK_LOCK_TIME; return SIMPLICITY_NO_ERROR; + case 3: *result = CHECK_LOCK_DISTANCE; return SIMPLICITY_NO_ERROR; + case 4: *result = CHECK_LOCK_DURATION; return SIMPLICITY_NO_ERROR; + case 5: *result = TX_LOCK_HEIGHT; return SIMPLICITY_NO_ERROR; + case 6: *result = TX_LOCK_TIME; return SIMPLICITY_NO_ERROR; + case 7: *result = TX_LOCK_DISTANCE; return SIMPLICITY_NO_ERROR; + case 8: *result = TX_LOCK_DURATION; return SIMPLICITY_NO_ERROR; + case 9: *result = TX_IS_FINAL; return SIMPLICITY_NO_ERROR; + } + break; + case 3: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: *result = ISSUANCE; return SIMPLICITY_NO_ERROR; + case 2: *result = ISSUANCE_ASSET; return SIMPLICITY_NO_ERROR; + case 3: *result = ISSUANCE_TOKEN; return SIMPLICITY_NO_ERROR; + case 4: *result = ISSUANCE_ENTROPY; return SIMPLICITY_NO_ERROR; + case 5: *result = CALCULATE_ISSUANCE_ENTROPY; return SIMPLICITY_NO_ERROR; + case 6: *result = CALCULATE_ASSET; return SIMPLICITY_NO_ERROR; + case 7: *result = CALCULATE_EXPLICIT_TOKEN; return SIMPLICITY_NO_ERROR; + case 8: *result = CALCULATE_CONFIDENTIAL_TOKEN; return SIMPLICITY_NO_ERROR; + case 9: *result = LBTC_ASSET; return SIMPLICITY_NO_ERROR; + } + break; + case 4: + code = simplicity_decodeUptoMaxInt(stream); + if (code < 0) return (simplicity_err)code; + switch (code) { + case 1: *result = SCRIPT_CMR; return SIMPLICITY_NO_ERROR; + case 2: *result = INTERNAL_KEY; return SIMPLICITY_NO_ERROR; + case 3: *result = CURRENT_INDEX; return SIMPLICITY_NO_ERROR; + case 4: *result = NUM_INPUTS; return SIMPLICITY_NO_ERROR; + case 5: *result = NUM_OUTPUTS; return SIMPLICITY_NO_ERROR; + case 6: *result = LOCK_TIME; return SIMPLICITY_NO_ERROR; + case 7: *result = OUTPUT_ASSET; return SIMPLICITY_NO_ERROR; + case 8: *result = OUTPUT_AMOUNT; return SIMPLICITY_NO_ERROR; + case 9: *result = OUTPUT_NONCE; return SIMPLICITY_NO_ERROR; + case 10: *result = OUTPUT_SCRIPT_HASH; return SIMPLICITY_NO_ERROR; + case 11: *result = OUTPUT_NULL_DATUM; return SIMPLICITY_NO_ERROR; + case 12: *result = OUTPUT_IS_FEE; return SIMPLICITY_NO_ERROR; + case 13: *result = OUTPUT_SURJECTION_PROOF; return SIMPLICITY_NO_ERROR; + case 14: *result = OUTPUT_RANGE_PROOF; return SIMPLICITY_NO_ERROR; + case 15: *result = TOTAL_FEE; return SIMPLICITY_NO_ERROR; + case 16: *result = CURRENT_PEGIN; return SIMPLICITY_NO_ERROR; + case 17: *result = CURRENT_PREV_OUTPOINT; return SIMPLICITY_NO_ERROR; + case 18: *result = CURRENT_ASSET; return SIMPLICITY_NO_ERROR; + case 19: *result = CURRENT_AMOUNT; return SIMPLICITY_NO_ERROR; + case 20: *result = CURRENT_SCRIPT_HASH; return SIMPLICITY_NO_ERROR; + case 21: *result = CURRENT_SEQUENCE; return SIMPLICITY_NO_ERROR; + case 22: *result = CURRENT_ANNEX_HASH; return SIMPLICITY_NO_ERROR; + case 23: *result = CURRENT_SCRIPT_SIG_HASH; return SIMPLICITY_NO_ERROR; + case 24: *result = CURRENT_REISSUANCE_BLINDING; return SIMPLICITY_NO_ERROR; + case 25: *result = CURRENT_NEW_ISSUANCE_CONTRACT; return SIMPLICITY_NO_ERROR; + case 26: *result = CURRENT_REISSUANCE_ENTROPY; return SIMPLICITY_NO_ERROR; + case 27: *result = CURRENT_ISSUANCE_ASSET_AMOUNT; return SIMPLICITY_NO_ERROR; + case 28: *result = CURRENT_ISSUANCE_TOKEN_AMOUNT; return SIMPLICITY_NO_ERROR; + case 29: *result = CURRENT_ISSUANCE_ASSET_PROOF; return SIMPLICITY_NO_ERROR; + case 30: *result = CURRENT_ISSUANCE_TOKEN_PROOF; return SIMPLICITY_NO_ERROR; + case 31: *result = INPUT_PEGIN; return SIMPLICITY_NO_ERROR; + case 32: *result = INPUT_PREV_OUTPOINT; return SIMPLICITY_NO_ERROR; + case 33: *result = INPUT_ASSET; return SIMPLICITY_NO_ERROR; + case 34: *result = INPUT_AMOUNT; return SIMPLICITY_NO_ERROR; + case 35: *result = INPUT_SCRIPT_HASH; return SIMPLICITY_NO_ERROR; + case 36: *result = INPUT_SEQUENCE; return SIMPLICITY_NO_ERROR; + case 37: *result = INPUT_ANNEX_HASH; return SIMPLICITY_NO_ERROR; + case 38: *result = INPUT_SCRIPT_SIG_HASH; return SIMPLICITY_NO_ERROR; + case 39: *result = REISSUANCE_BLINDING; return SIMPLICITY_NO_ERROR; + case 40: *result = NEW_ISSUANCE_CONTRACT; return SIMPLICITY_NO_ERROR; + case 41: *result = REISSUANCE_ENTROPY; return SIMPLICITY_NO_ERROR; + case 42: *result = ISSUANCE_ASSET_AMOUNT; return SIMPLICITY_NO_ERROR; + case 43: *result = ISSUANCE_TOKEN_AMOUNT; return SIMPLICITY_NO_ERROR; + case 44: *result = ISSUANCE_ASSET_PROOF; return SIMPLICITY_NO_ERROR; + case 45: *result = ISSUANCE_TOKEN_PROOF; return SIMPLICITY_NO_ERROR; + case 46: *result = TAPLEAF_VERSION; return SIMPLICITY_NO_ERROR; + case 47: *result = TAPPATH; return SIMPLICITY_NO_ERROR; + case 48: *result = VERSION; return SIMPLICITY_NO_ERROR; + case 49: *result = GENESIS_BLOCK_HASH; return SIMPLICITY_NO_ERROR; + case 50: *result = TRANSACTION_ID; return SIMPLICITY_NO_ERROR; + } + break; + } +} \ No newline at end of file diff --git a/primitive/elements/env.c b/primitive/elements/env.c index 3c7adee254..e9f03ac6fd 100644 --- a/primitive/elements/env.c +++ b/primitive/elements/env.c @@ -305,7 +305,8 @@ static uint_fast32_t sumFees(sigOutput** feeOutputs, uint_fast32_t numFees) { return result + 1; } -/* Allocate and initialize a 'transaction' from a 'rawOutput', copying or hashing the data as needed. + +/* Allocate and initialize a 'transaction' from a 'rawTransaction', copying or hashing the data as needed. * Returns NULL if malloc fails (or if malloc cannot be called because we require an allocation larger than SIZE_MAX). * * Precondition: NULL != rawTx @@ -568,6 +569,12 @@ extern transaction* simplicity_elements_mallocTransaction(const rawTransaction* return tx; } +/* Free a pointer to 'transaction'. + */ +extern void simplicity_elements_freeTransaction(transaction* tx) { + simplicity_free(tx); +} + /* Allocate and initialize a 'tapEnv' from a 'rawTapEnv', copying or hashing the data as needed. * Returns NULL if malloc fails (or if malloc cannot be called because we require an allocation larger than SIZE_MAX). * @@ -639,6 +646,12 @@ extern tapEnv* simplicity_elements_mallocTapEnv(const rawTapEnv* rawEnv) { return env; } +/* Free a pointer to 'tapEnv'. + */ +extern void simplicity_elements_freeTapEnv(tapEnv* env) { + simplicity_free(env); +} + /* Contstruct a txEnv structure from its components. * This function will precompute any cached values. * diff --git a/primitive/elements/exec.c b/primitive/elements/exec.c index aaffd50565..e38c9ca41a 100644 --- a/primitive/elements/exec.c +++ b/primitive/elements/exec.c @@ -22,11 +22,11 @@ * * Otherwise '*error' is set to 'SIMPLICITY_NO_ERROR'. * - * If 'imr != NULL' and '*error' is set to 'SIMPLICITY_NO_ERROR', then the identity Merkle root of the decoded expression is written to 'imr'. - * Otherwise if 'imr != NULL' and '*error' is not set to 'SIMPLCITY_NO_ERROR', then 'imr' may or may not be written to. + * If 'ihr != NULL' and '*error' is set to 'SIMPLICITY_NO_ERROR', then the identity hash of the root of the decoded expression is written to 'ihr'. + * Otherwise if 'ihr != NULL' and '*error' is not set to 'SIMPLCITY_NO_ERROR', then 'ihr' may or may not be written to. * * Precondition: NULL != error; - * NULL != imr implies unsigned char imr[32] + * NULL != ihr implies unsigned char ihr[32] * NULL != tx; * NULL != taproot; * unsigned char genesisBlockHash[32] @@ -35,7 +35,7 @@ * unsigned char program[program_len] * unsigned char witness[witness_len] */ -extern bool simplicity_elements_execSimplicity( simplicity_err* error, unsigned char* imr +extern bool simplicity_elements_execSimplicity( simplicity_err* error, unsigned char* ihr , const transaction* tx, uint_fast32_t ix, const tapEnv* taproot , const unsigned char* genesisBlockHash , int64_t budget @@ -96,12 +96,9 @@ extern bool simplicity_elements_execSimplicity( simplicity_err* error, unsigned } } if (IS_OK(*error)) { - sha256_midstate imr_buf; - static_assert(DAG_LEN_MAX <= SIZE_MAX / sizeof(sha256_midstate), "imr_buf array too large."); - static_assert(1 <= DAG_LEN_MAX, "DAG_LEN_MAX is zero."); - static_assert(DAG_LEN_MAX - 1 <= UINT32_MAX, "imr_buf array index does nto fit in uint32_t."); - *error = simplicity_verifyNoDuplicateIdentityRoots(&imr_buf, dag, type_dag, (uint_fast32_t)dag_len); - if (IS_OK(*error) && imr) sha256_fromMidstate(imr, imr_buf.s); + sha256_midstate ihr_buf; + *error = simplicity_verifyNoDuplicateIdentityHashes(&ihr_buf, dag, type_dag, (uint_fast32_t)dag_len); + if (IS_OK(*error) && ihr) sha256_fromMidstate(ihr, ihr_buf.s); } if (IS_OK(*error) && amr) { static_assert(DAG_LEN_MAX <= SIZE_MAX / sizeof(analyses), "analysis array too large."); diff --git a/primitive/elements/primitive.c b/primitive/elements/primitive.c index f14c231967..da08b92094 100644 --- a/primitive/elements/primitive.c +++ b/primitive/elements/primitive.c @@ -71,1104 +71,11 @@ static simplicity_err decodePrimitive(jetName* result, bitstream* stream) { if (bit < 0) return (simplicity_err)bit; if (!bit) { /* Core jets */ - int32_t code = simplicity_decodeUptoMaxInt(stream); - int32_t code2; - if (code < 0) return (simplicity_err)code; - - switch (code) { - case 1: /* Word jets chapter */ - code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - switch (code) { - case 1: /* Verify */ - *result = VERIFY; return SIMPLICITY_NO_ERROR; - case 2: /* Low */ - code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - switch (code) { - case 1: *result = LOW_1; return SIMPLICITY_NO_ERROR; - case 3: *result = LOW_8; return SIMPLICITY_NO_ERROR; - case 4: *result = LOW_16; return SIMPLICITY_NO_ERROR; - case 5: *result = LOW_32; return SIMPLICITY_NO_ERROR; - case 6: *result = LOW_64; return SIMPLICITY_NO_ERROR; - } - break; - case 3: /* High */ - code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - switch (code) { - case 1: *result = HIGH_1; return SIMPLICITY_NO_ERROR; - case 3: *result = HIGH_8; return SIMPLICITY_NO_ERROR; - case 4: *result = HIGH_16; return SIMPLICITY_NO_ERROR; - case 5: *result = HIGH_32; return SIMPLICITY_NO_ERROR; - case 6: *result = HIGH_64; return SIMPLICITY_NO_ERROR; - } - break; - case 4: /* Complement */ - code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - switch (code) { - case 1: *result = COMPLEMENT_1; return SIMPLICITY_NO_ERROR; - case 3: *result = COMPLEMENT_8; return SIMPLICITY_NO_ERROR; - case 4: *result = COMPLEMENT_16; return SIMPLICITY_NO_ERROR; - case 5: *result = COMPLEMENT_32; return SIMPLICITY_NO_ERROR; - case 6: *result = COMPLEMENT_64; return SIMPLICITY_NO_ERROR; - } - break; - case 5: /* And */ - code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - switch (code) { - case 1: *result = AND_1; return SIMPLICITY_NO_ERROR; - case 3: *result = AND_8; return SIMPLICITY_NO_ERROR; - case 4: *result = AND_16; return SIMPLICITY_NO_ERROR; - case 5: *result = AND_32; return SIMPLICITY_NO_ERROR; - case 6: *result = AND_64; return SIMPLICITY_NO_ERROR; - } - break; - case 6: /* Or */ - code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - switch (code) { - case 1: *result = OR_1; return SIMPLICITY_NO_ERROR; - case 3: *result = OR_8; return SIMPLICITY_NO_ERROR; - case 4: *result = OR_16; return SIMPLICITY_NO_ERROR; - case 5: *result = OR_32; return SIMPLICITY_NO_ERROR; - case 6: *result = OR_64; return SIMPLICITY_NO_ERROR; - } - break; - case 7: /* Xor */ - code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - switch (code) { - case 1: *result = XOR_1; return SIMPLICITY_NO_ERROR; - case 3: *result = XOR_8; return SIMPLICITY_NO_ERROR; - case 4: *result = XOR_16; return SIMPLICITY_NO_ERROR; - case 5: *result = XOR_32; return SIMPLICITY_NO_ERROR; - case 6: *result = XOR_64; return SIMPLICITY_NO_ERROR; - } - break; - case 8: /* Maj */ - code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - switch (code) { - case 1: *result = MAJ_1; return SIMPLICITY_NO_ERROR; - case 3: *result = MAJ_8; return SIMPLICITY_NO_ERROR; - case 4: *result = MAJ_16; return SIMPLICITY_NO_ERROR; - case 5: *result = MAJ_32; return SIMPLICITY_NO_ERROR; - case 6: *result = MAJ_64; return SIMPLICITY_NO_ERROR; - } - break; - case 9: /* Xor_Xor */ - code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - switch (code) { - case 1: *result = XOR_XOR_1; return SIMPLICITY_NO_ERROR; - case 3: *result = XOR_XOR_8; return SIMPLICITY_NO_ERROR; - case 4: *result = XOR_XOR_16; return SIMPLICITY_NO_ERROR; - case 5: *result = XOR_XOR_32; return SIMPLICITY_NO_ERROR; - case 6: *result = XOR_XOR_64; return SIMPLICITY_NO_ERROR; - } - break; - case 10: /* Ch */ - code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - switch (code) { - case 1: *result = CH_1; return SIMPLICITY_NO_ERROR; - case 3: *result = CH_8; return SIMPLICITY_NO_ERROR; - case 4: *result = CH_16; return SIMPLICITY_NO_ERROR; - case 5: *result = CH_32; return SIMPLICITY_NO_ERROR; - case 6: *result = CH_64; return SIMPLICITY_NO_ERROR; - } - break; - case 11: /* Some */ - code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - switch (code) { - case 1: *result = SOME_1; return SIMPLICITY_NO_ERROR; - case 3: *result = SOME_8; return SIMPLICITY_NO_ERROR; - case 4: *result = SOME_16; return SIMPLICITY_NO_ERROR; - case 5: *result = SOME_32; return SIMPLICITY_NO_ERROR; - case 6: *result = SOME_64; return SIMPLICITY_NO_ERROR; - } - break; - case 12: /* All */ - code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - switch (code) { - case 3: *result = ALL_8; return SIMPLICITY_NO_ERROR; - case 4: *result = ALL_16; return SIMPLICITY_NO_ERROR; - case 5: *result = ALL_32; return SIMPLICITY_NO_ERROR; - case 6: *result = ALL_64; return SIMPLICITY_NO_ERROR; - } - break; - case 13: /* Eq */ - code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - switch (code) { - case 1: *result = EQ_1; return SIMPLICITY_NO_ERROR; - case 3: *result = EQ_8; return SIMPLICITY_NO_ERROR; - case 4: *result = EQ_16; return SIMPLICITY_NO_ERROR; - case 5: *result = EQ_32; return SIMPLICITY_NO_ERROR; - case 6: *result = EQ_64; return SIMPLICITY_NO_ERROR; - case 8: *result = EQ_256; return SIMPLICITY_NO_ERROR; - } - break; - case 14: /* FullLeftShift */ - code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - code2 = simplicity_decodeUptoMaxInt(stream); - if (code2 < 0) return (simplicity_err)code2; - switch (code) { - case 1: - switch (code2) { - case 3: *result = FULL_LEFT_SHIFT_8_1; return SIMPLICITY_NO_ERROR; - case 4: *result = FULL_LEFT_SHIFT_16_1; return SIMPLICITY_NO_ERROR; - case 5: *result = FULL_LEFT_SHIFT_32_1; return SIMPLICITY_NO_ERROR; - case 6: *result = FULL_LEFT_SHIFT_64_1; return SIMPLICITY_NO_ERROR; - } - break; - case 2: - switch (code2) { - case 2: *result = FULL_LEFT_SHIFT_8_2; return SIMPLICITY_NO_ERROR; - case 3: *result = FULL_LEFT_SHIFT_16_2; return SIMPLICITY_NO_ERROR; - case 4: *result = FULL_LEFT_SHIFT_32_2; return SIMPLICITY_NO_ERROR; - case 5: *result = FULL_LEFT_SHIFT_64_2; return SIMPLICITY_NO_ERROR; - } - break; - case 3: - switch (code2) { - case 1: *result = FULL_LEFT_SHIFT_8_4; return SIMPLICITY_NO_ERROR; - case 2: *result = FULL_LEFT_SHIFT_16_4; return SIMPLICITY_NO_ERROR; - case 3: *result = FULL_LEFT_SHIFT_32_4; return SIMPLICITY_NO_ERROR; - case 4: *result = FULL_LEFT_SHIFT_64_4; return SIMPLICITY_NO_ERROR; - } - break; - case 4: - switch (code2) { - case 1: *result = FULL_LEFT_SHIFT_16_8; return SIMPLICITY_NO_ERROR; - case 2: *result = FULL_LEFT_SHIFT_32_8; return SIMPLICITY_NO_ERROR; - case 3: *result = FULL_LEFT_SHIFT_64_8; return SIMPLICITY_NO_ERROR; - } - break; - case 5: - switch (code2) { - case 1: *result = FULL_LEFT_SHIFT_32_16; return SIMPLICITY_NO_ERROR; - case 2: *result = FULL_LEFT_SHIFT_64_16; return SIMPLICITY_NO_ERROR; - } - break; - case 6: - switch (code2) { - case 1: *result = FULL_LEFT_SHIFT_64_32; return SIMPLICITY_NO_ERROR; - } - break; - } - break; - case 15: /* FullRightShift */ - code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - code2 = simplicity_decodeUptoMaxInt(stream); - if (code2 < 0) return (simplicity_err)code2; - switch (code) { - case 1: - switch (code2) { - case 3: *result = FULL_RIGHT_SHIFT_8_1; return SIMPLICITY_NO_ERROR; - case 4: *result = FULL_RIGHT_SHIFT_16_1; return SIMPLICITY_NO_ERROR; - case 5: *result = FULL_RIGHT_SHIFT_32_1; return SIMPLICITY_NO_ERROR; - case 6: *result = FULL_RIGHT_SHIFT_64_1; return SIMPLICITY_NO_ERROR; - } - break; - case 2: - switch (code2) { - case 2: *result = FULL_RIGHT_SHIFT_8_2; return SIMPLICITY_NO_ERROR; - case 3: *result = FULL_RIGHT_SHIFT_16_2; return SIMPLICITY_NO_ERROR; - case 4: *result = FULL_RIGHT_SHIFT_32_2; return SIMPLICITY_NO_ERROR; - case 5: *result = FULL_RIGHT_SHIFT_64_2; return SIMPLICITY_NO_ERROR; - } - break; - case 3: - switch (code2) { - case 1: *result = FULL_RIGHT_SHIFT_8_4; return SIMPLICITY_NO_ERROR; - case 2: *result = FULL_RIGHT_SHIFT_16_4; return SIMPLICITY_NO_ERROR; - case 3: *result = FULL_RIGHT_SHIFT_32_4; return SIMPLICITY_NO_ERROR; - case 4: *result = FULL_RIGHT_SHIFT_64_4; return SIMPLICITY_NO_ERROR; - } - break; - case 4: - switch (code2) { - case 1: *result = FULL_RIGHT_SHIFT_16_8; return SIMPLICITY_NO_ERROR; - case 2: *result = FULL_RIGHT_SHIFT_32_8; return SIMPLICITY_NO_ERROR; - case 3: *result = FULL_RIGHT_SHIFT_64_8; return SIMPLICITY_NO_ERROR; - } - break; - case 5: - switch (code2) { - case 1: *result = FULL_RIGHT_SHIFT_32_16; return SIMPLICITY_NO_ERROR; - case 2: *result = FULL_RIGHT_SHIFT_64_16; return SIMPLICITY_NO_ERROR; - } - break; - case 6: - switch (code2) { - case 1: *result = FULL_RIGHT_SHIFT_64_32; return SIMPLICITY_NO_ERROR; - } - break; - } - break; - case 16: /* Leftmost */ - code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - code2 = simplicity_decodeUptoMaxInt(stream); - if (code2 < 0) return (simplicity_err)code2; - switch (code) { - case 1: - switch (code2) { - case 3: *result = LEFTMOST_8_1; return SIMPLICITY_NO_ERROR; - case 4: *result = LEFTMOST_16_1; return SIMPLICITY_NO_ERROR; - case 5: *result = LEFTMOST_32_1; return SIMPLICITY_NO_ERROR; - case 6: *result = LEFTMOST_64_1; return SIMPLICITY_NO_ERROR; - } - break; - case 2: - switch (code2) { - case 2: *result = LEFTMOST_8_2; return SIMPLICITY_NO_ERROR; - case 3: *result = LEFTMOST_16_2; return SIMPLICITY_NO_ERROR; - case 4: *result = LEFTMOST_32_2; return SIMPLICITY_NO_ERROR; - case 5: *result = LEFTMOST_64_2; return SIMPLICITY_NO_ERROR; - } - break; - case 3: - switch (code2) { - case 1: *result = LEFTMOST_8_4; return SIMPLICITY_NO_ERROR; - case 2: *result = LEFTMOST_16_4; return SIMPLICITY_NO_ERROR; - case 3: *result = LEFTMOST_32_4; return SIMPLICITY_NO_ERROR; - case 4: *result = LEFTMOST_64_4; return SIMPLICITY_NO_ERROR; - } - break; - case 4: - switch (code2) { - case 1: *result = LEFTMOST_16_8; return SIMPLICITY_NO_ERROR; - case 2: *result = LEFTMOST_32_8; return SIMPLICITY_NO_ERROR; - case 3: *result = LEFTMOST_64_8; return SIMPLICITY_NO_ERROR; - } - break; - case 5: - switch (code2) { - case 1: *result = LEFTMOST_32_16; return SIMPLICITY_NO_ERROR; - case 2: *result = LEFTMOST_64_16; return SIMPLICITY_NO_ERROR; - } - break; - case 6: - switch (code2) { - case 1: *result = LEFTMOST_64_32; return SIMPLICITY_NO_ERROR; - } - break; - } - break; - case 17: /* Rightmost */ - code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - code2 = simplicity_decodeUptoMaxInt(stream); - if (code2 < 0) return (simplicity_err)code2; - switch (code) { - case 1: - switch (code2) { - case 3: *result = RIGHTMOST_8_1; return SIMPLICITY_NO_ERROR; - case 4: *result = RIGHTMOST_16_1; return SIMPLICITY_NO_ERROR; - case 5: *result = RIGHTMOST_32_1; return SIMPLICITY_NO_ERROR; - case 6: *result = RIGHTMOST_64_1; return SIMPLICITY_NO_ERROR; - } - break; - case 2: - switch (code2) { - case 2: *result = RIGHTMOST_8_2; return SIMPLICITY_NO_ERROR; - case 3: *result = RIGHTMOST_16_2; return SIMPLICITY_NO_ERROR; - case 4: *result = RIGHTMOST_32_2; return SIMPLICITY_NO_ERROR; - case 5: *result = RIGHTMOST_64_2; return SIMPLICITY_NO_ERROR; - } - break; - case 3: - switch (code2) { - case 1: *result = RIGHTMOST_8_4; return SIMPLICITY_NO_ERROR; - case 2: *result = RIGHTMOST_16_4; return SIMPLICITY_NO_ERROR; - case 3: *result = RIGHTMOST_32_4; return SIMPLICITY_NO_ERROR; - case 4: *result = RIGHTMOST_64_4; return SIMPLICITY_NO_ERROR; - } - break; - case 4: - switch (code2) { - case 1: *result = RIGHTMOST_16_8; return SIMPLICITY_NO_ERROR; - case 2: *result = RIGHTMOST_32_8; return SIMPLICITY_NO_ERROR; - case 3: *result = RIGHTMOST_64_8; return SIMPLICITY_NO_ERROR; - } - break; - case 5: - switch (code2) { - case 1: *result = RIGHTMOST_32_16; return SIMPLICITY_NO_ERROR; - case 2: *result = RIGHTMOST_64_16; return SIMPLICITY_NO_ERROR; - } - break; - case 6: - switch (code2) { - case 1: *result = RIGHTMOST_64_32; return SIMPLICITY_NO_ERROR; - } - break; - } - break; - case 18: /* LeftPadLow */ - code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - code2 = simplicity_decodeUptoMaxInt(stream); - if (code2 < 0) return (simplicity_err)code2; - switch (code) { - case 1: - switch (code2) { - case 3: *result = LEFT_PAD_LOW_1_8; return SIMPLICITY_NO_ERROR; - case 4: *result = LEFT_PAD_LOW_1_16; return SIMPLICITY_NO_ERROR; - case 5: *result = LEFT_PAD_LOW_1_32; return SIMPLICITY_NO_ERROR; - case 6: *result = LEFT_PAD_LOW_1_64; return SIMPLICITY_NO_ERROR; - } - break; - case 4: - switch (code2) { - case 1: *result = LEFT_PAD_LOW_8_16; return SIMPLICITY_NO_ERROR; - case 2: *result = LEFT_PAD_LOW_8_32; return SIMPLICITY_NO_ERROR; - case 3: *result = LEFT_PAD_LOW_8_64; return SIMPLICITY_NO_ERROR; - } - break; - case 5: - switch (code2) { - case 1: *result = LEFT_PAD_LOW_16_32; return SIMPLICITY_NO_ERROR; - case 2: *result = LEFT_PAD_LOW_16_64; return SIMPLICITY_NO_ERROR; - } - break; - case 6: - switch (code2) { - case 1: *result = LEFT_PAD_LOW_32_64; return SIMPLICITY_NO_ERROR; - } - break; - } - break; - case 19: /* LeftPadHigh */ - code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - code2 = simplicity_decodeUptoMaxInt(stream); - if (code2 < 0) return (simplicity_err)code2; - switch (code) { - case 1: - switch (code2) { - case 3: *result = LEFT_PAD_HIGH_1_8; return SIMPLICITY_NO_ERROR; - case 4: *result = LEFT_PAD_HIGH_1_16; return SIMPLICITY_NO_ERROR; - case 5: *result = LEFT_PAD_HIGH_1_32; return SIMPLICITY_NO_ERROR; - case 6: *result = LEFT_PAD_HIGH_1_64; return SIMPLICITY_NO_ERROR; - } - break; - case 4: - switch (code2) { - case 1: *result = LEFT_PAD_HIGH_8_16; return SIMPLICITY_NO_ERROR; - case 2: *result = LEFT_PAD_HIGH_8_32; return SIMPLICITY_NO_ERROR; - case 3: *result = LEFT_PAD_HIGH_8_64; return SIMPLICITY_NO_ERROR; - } - break; - case 5: - switch (code2) { - case 1: *result = LEFT_PAD_HIGH_16_32; return SIMPLICITY_NO_ERROR; - case 2: *result = LEFT_PAD_HIGH_16_64; return SIMPLICITY_NO_ERROR; - } - break; - case 6: - switch (code2) { - case 1: *result = LEFT_PAD_HIGH_32_64; return SIMPLICITY_NO_ERROR; - } - break; - } - break; - case 20: /* LeftExtend */ - code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - code2 = simplicity_decodeUptoMaxInt(stream); - if (code2 < 0) return (simplicity_err)code2; - switch (code) { - case 1: - switch (code2) { - case 3: *result = LEFT_EXTEND_1_8; return SIMPLICITY_NO_ERROR; - case 4: *result = LEFT_EXTEND_1_16; return SIMPLICITY_NO_ERROR; - case 5: *result = LEFT_EXTEND_1_32; return SIMPLICITY_NO_ERROR; - case 6: *result = LEFT_EXTEND_1_64; return SIMPLICITY_NO_ERROR; - } - break; - case 4: - switch (code2) { - case 1: *result = LEFT_EXTEND_8_16; return SIMPLICITY_NO_ERROR; - case 2: *result = LEFT_EXTEND_8_32; return SIMPLICITY_NO_ERROR; - case 3: *result = LEFT_EXTEND_8_64; return SIMPLICITY_NO_ERROR; - } - break; - case 5: - switch (code2) { - case 1: *result = LEFT_EXTEND_16_32; return SIMPLICITY_NO_ERROR; - case 2: *result = LEFT_EXTEND_16_64; return SIMPLICITY_NO_ERROR; - } - break; - case 6: - switch (code2) { - case 1: *result = LEFT_EXTEND_32_64; return SIMPLICITY_NO_ERROR; - } - break; - } - break; - case 21: /* RightPadLow */ - code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - code2 = simplicity_decodeUptoMaxInt(stream); - if (code2 < 0) return (simplicity_err)code2; - switch (code) { - case 1: - switch (code2) { - case 3: *result = RIGHT_PAD_LOW_1_8; return SIMPLICITY_NO_ERROR; - case 4: *result = RIGHT_PAD_LOW_1_16; return SIMPLICITY_NO_ERROR; - case 5: *result = RIGHT_PAD_LOW_1_32; return SIMPLICITY_NO_ERROR; - case 6: *result = RIGHT_PAD_LOW_1_64; return SIMPLICITY_NO_ERROR; - } - break; - case 4: - switch (code2) { - case 1: *result = RIGHT_PAD_LOW_8_16; return SIMPLICITY_NO_ERROR; - case 2: *result = RIGHT_PAD_LOW_8_32; return SIMPLICITY_NO_ERROR; - case 3: *result = RIGHT_PAD_LOW_8_64; return SIMPLICITY_NO_ERROR; - } - break; - case 5: - switch (code2) { - case 1: *result = RIGHT_PAD_LOW_16_32; return SIMPLICITY_NO_ERROR; - case 2: *result = RIGHT_PAD_LOW_16_64; return SIMPLICITY_NO_ERROR; - } - break; - case 6: - switch (code2) { - case 1: *result = RIGHT_PAD_LOW_32_64; return SIMPLICITY_NO_ERROR; - } - break; - } - break; - case 22: /* RightPadHigh */ - code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - code2 = simplicity_decodeUptoMaxInt(stream); - if (code2 < 0) return (simplicity_err)code2; - switch (code) { - case 1: - switch (code2) { - case 3: *result = RIGHT_PAD_HIGH_1_8; return SIMPLICITY_NO_ERROR; - case 4: *result = RIGHT_PAD_HIGH_1_16; return SIMPLICITY_NO_ERROR; - case 5: *result = RIGHT_PAD_HIGH_1_32; return SIMPLICITY_NO_ERROR; - case 6: *result = RIGHT_PAD_HIGH_1_64; return SIMPLICITY_NO_ERROR; - } - break; - case 4: - switch (code2) { - case 1: *result = RIGHT_PAD_HIGH_8_16; return SIMPLICITY_NO_ERROR; - case 2: *result = RIGHT_PAD_HIGH_8_32; return SIMPLICITY_NO_ERROR; - case 3: *result = RIGHT_PAD_HIGH_8_64; return SIMPLICITY_NO_ERROR; - } - break; - case 5: - switch (code2) { - case 1: *result = RIGHT_PAD_HIGH_16_32; return SIMPLICITY_NO_ERROR; - case 2: *result = RIGHT_PAD_HIGH_16_64; return SIMPLICITY_NO_ERROR; - } - break; - case 6: - switch (code2) { - case 1: *result = RIGHT_PAD_HIGH_32_64; return SIMPLICITY_NO_ERROR; - } - break; - } - break; - case 23: /* RightExtend */ - code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - code2 = simplicity_decodeUptoMaxInt(stream); - if (code2 < 0) return (simplicity_err)code2; - switch (code) { - case 4: - switch (code2) { - case 1: *result = RIGHT_EXTEND_8_16; return SIMPLICITY_NO_ERROR; - case 2: *result = RIGHT_EXTEND_8_32; return SIMPLICITY_NO_ERROR; - case 3: *result = RIGHT_EXTEND_8_64; return SIMPLICITY_NO_ERROR; - } - break; - case 5: - switch (code2) { - case 1: *result = RIGHT_EXTEND_16_32; return SIMPLICITY_NO_ERROR; - case 2: *result = RIGHT_EXTEND_16_64; return SIMPLICITY_NO_ERROR; - } - break; - case 6: - switch (code2) { - case 1: *result = RIGHT_EXTEND_32_64; return SIMPLICITY_NO_ERROR; - } - break; - } - break; - case 24: /* LeftShiftWith */ - code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - switch (code) { - case 3: *result = LEFT_SHIFT_WITH_8; return SIMPLICITY_NO_ERROR; - case 4: *result = LEFT_SHIFT_WITH_16; return SIMPLICITY_NO_ERROR; - case 5: *result = LEFT_SHIFT_WITH_32; return SIMPLICITY_NO_ERROR; - case 6: *result = LEFT_SHIFT_WITH_64; return SIMPLICITY_NO_ERROR; - } - break; - case 25: /* RightShiftWith */ - code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - switch (code) { - case 3: *result = RIGHT_SHIFT_WITH_8; return SIMPLICITY_NO_ERROR; - case 4: *result = RIGHT_SHIFT_WITH_16; return SIMPLICITY_NO_ERROR; - case 5: *result = RIGHT_SHIFT_WITH_32; return SIMPLICITY_NO_ERROR; - case 6: *result = RIGHT_SHIFT_WITH_64; return SIMPLICITY_NO_ERROR; - } - break; - case 26: /* LeftShift */ - code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - switch (code) { - case 3: *result = LEFT_SHIFT_8; return SIMPLICITY_NO_ERROR; - case 4: *result = LEFT_SHIFT_16; return SIMPLICITY_NO_ERROR; - case 5: *result = LEFT_SHIFT_32; return SIMPLICITY_NO_ERROR; - case 6: *result = LEFT_SHIFT_64; return SIMPLICITY_NO_ERROR; - } - break; - case 27: /* RightShift */ - code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - switch (code) { - case 3: *result = RIGHT_SHIFT_8; return SIMPLICITY_NO_ERROR; - case 4: *result = RIGHT_SHIFT_16; return SIMPLICITY_NO_ERROR; - case 5: *result = RIGHT_SHIFT_32; return SIMPLICITY_NO_ERROR; - case 6: *result = RIGHT_SHIFT_64; return SIMPLICITY_NO_ERROR; - } - break; - case 28: /* LeftRotate */ - code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - switch (code) { - case 3: *result = LEFT_ROTATE_8; return SIMPLICITY_NO_ERROR; - case 4: *result = LEFT_ROTATE_16; return SIMPLICITY_NO_ERROR; - case 5: *result = LEFT_ROTATE_32; return SIMPLICITY_NO_ERROR; - case 6: *result = LEFT_ROTATE_64; return SIMPLICITY_NO_ERROR; - } - break; - case 29: /* RightRotate */ - code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - switch (code) { - case 3: *result = RIGHT_ROTATE_8; return SIMPLICITY_NO_ERROR; - case 4: *result = RIGHT_ROTATE_16; return SIMPLICITY_NO_ERROR; - case 5: *result = RIGHT_ROTATE_32; return SIMPLICITY_NO_ERROR; - case 6: *result = RIGHT_ROTATE_64; return SIMPLICITY_NO_ERROR; - } - break; - } - break; - case 2: /* Arith jets chapter */ - code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - - switch (code) { - case 1: /* One */ - code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - switch (code) { - case 3: *result = ONE_8; return SIMPLICITY_NO_ERROR; - case 4: *result = ONE_16; return SIMPLICITY_NO_ERROR; - case 5: *result = ONE_32; return SIMPLICITY_NO_ERROR; - case 6: *result = ONE_64; return SIMPLICITY_NO_ERROR; - } - break; - case 2: /* FullAdd */ - code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - switch (code) { - case 3: *result = FULL_ADD_8; return SIMPLICITY_NO_ERROR; - case 4: *result = FULL_ADD_16; return SIMPLICITY_NO_ERROR; - case 5: *result = FULL_ADD_32; return SIMPLICITY_NO_ERROR; - case 6: *result = FULL_ADD_64; return SIMPLICITY_NO_ERROR; - } - break; - case 3: /* Add */ - code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - switch (code) { - case 3: *result = ADD_8; return SIMPLICITY_NO_ERROR; - case 4: *result = ADD_16; return SIMPLICITY_NO_ERROR; - case 5: *result = ADD_32; return SIMPLICITY_NO_ERROR; - case 6: *result = ADD_64; return SIMPLICITY_NO_ERROR; - } - break; - case 4: /* FullIncrement */ - code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - switch (code) { - case 3: *result = FULL_INCREMENT_8; return SIMPLICITY_NO_ERROR; - case 4: *result = FULL_INCREMENT_16; return SIMPLICITY_NO_ERROR; - case 5: *result = FULL_INCREMENT_32; return SIMPLICITY_NO_ERROR; - case 6: *result = FULL_INCREMENT_64; return SIMPLICITY_NO_ERROR; - } - break; - case 5: /* Increment */ - code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - switch (code) { - case 3: *result = INCREMENT_8; return SIMPLICITY_NO_ERROR; - case 4: *result = INCREMENT_16; return SIMPLICITY_NO_ERROR; - case 5: *result = INCREMENT_32; return SIMPLICITY_NO_ERROR; - case 6: *result = INCREMENT_64; return SIMPLICITY_NO_ERROR; - } - break; - case 7: /* FullSubtract */ - code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - switch (code) { - case 3: *result = FULL_SUBTRACT_8; return SIMPLICITY_NO_ERROR; - case 4: *result = FULL_SUBTRACT_16; return SIMPLICITY_NO_ERROR; - case 5: *result = FULL_SUBTRACT_32; return SIMPLICITY_NO_ERROR; - case 6: *result = FULL_SUBTRACT_64; return SIMPLICITY_NO_ERROR; - } - break; - case 8: /* Subtract */ - code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - switch (code) { - case 3: *result = SUBTRACT_8; return SIMPLICITY_NO_ERROR; - case 4: *result = SUBTRACT_16; return SIMPLICITY_NO_ERROR; - case 5: *result = SUBTRACT_32; return SIMPLICITY_NO_ERROR; - case 6: *result = SUBTRACT_64; return SIMPLICITY_NO_ERROR; - } - break; - case 9: /* Negate */ - code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - switch (code) { - case 3: *result = NEGATE_8; return SIMPLICITY_NO_ERROR; - case 4: *result = NEGATE_16; return SIMPLICITY_NO_ERROR; - case 5: *result = NEGATE_32; return SIMPLICITY_NO_ERROR; - case 6: *result = NEGATE_64; return SIMPLICITY_NO_ERROR; - } - break; - case 10: /* FullDecrement */ - code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - switch (code) { - case 3: *result = FULL_DECREMENT_8; return SIMPLICITY_NO_ERROR; - case 4: *result = FULL_DECREMENT_16; return SIMPLICITY_NO_ERROR; - case 5: *result = FULL_DECREMENT_32; return SIMPLICITY_NO_ERROR; - case 6: *result = FULL_DECREMENT_64; return SIMPLICITY_NO_ERROR; - } - break; - case 11: /* Decrement */ - code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - switch (code) { - case 3: *result = DECREMENT_8; return SIMPLICITY_NO_ERROR; - case 4: *result = DECREMENT_16; return SIMPLICITY_NO_ERROR; - case 5: *result = DECREMENT_32; return SIMPLICITY_NO_ERROR; - case 6: *result = DECREMENT_64; return SIMPLICITY_NO_ERROR; - } - break; - case 12: /* FullMultiply */ - code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - switch (code) { - case 3: *result = FULL_MULTIPLY_8; return SIMPLICITY_NO_ERROR; - case 4: *result = FULL_MULTIPLY_16; return SIMPLICITY_NO_ERROR; - case 5: *result = FULL_MULTIPLY_32; return SIMPLICITY_NO_ERROR; - case 6: *result = FULL_MULTIPLY_64; return SIMPLICITY_NO_ERROR; - } - break; - case 13: /* Multiply */ - code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - switch (code) { - case 3: *result = MULTIPLY_8; return SIMPLICITY_NO_ERROR; - case 4: *result = MULTIPLY_16; return SIMPLICITY_NO_ERROR; - case 5: *result = MULTIPLY_32; return SIMPLICITY_NO_ERROR; - case 6: *result = MULTIPLY_64; return SIMPLICITY_NO_ERROR; - } - break; - case 14: /* IsZero */ - code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - switch (code) { - case 3: *result = IS_ZERO_8; return SIMPLICITY_NO_ERROR; - case 4: *result = IS_ZERO_16; return SIMPLICITY_NO_ERROR; - case 5: *result = IS_ZERO_32; return SIMPLICITY_NO_ERROR; - case 6: *result = IS_ZERO_64; return SIMPLICITY_NO_ERROR; - } - break; - case 15: /* IsOne */ - code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - switch (code) { - case 3: *result = IS_ONE_8; return SIMPLICITY_NO_ERROR; - case 4: *result = IS_ONE_16; return SIMPLICITY_NO_ERROR; - case 5: *result = IS_ONE_32; return SIMPLICITY_NO_ERROR; - case 6: *result = IS_ONE_64; return SIMPLICITY_NO_ERROR; - } - break; - case 16: /* Le */ - code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - switch (code) { - case 3: *result = LE_8; return SIMPLICITY_NO_ERROR; - case 4: *result = LE_16; return SIMPLICITY_NO_ERROR; - case 5: *result = LE_32; return SIMPLICITY_NO_ERROR; - case 6: *result = LE_64; return SIMPLICITY_NO_ERROR; - } - break; - case 17: /* Lt */ - code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - switch (code) { - case 3: *result = LT_8; return SIMPLICITY_NO_ERROR; - case 4: *result = LT_16; return SIMPLICITY_NO_ERROR; - case 5: *result = LT_32; return SIMPLICITY_NO_ERROR; - case 6: *result = LT_64; return SIMPLICITY_NO_ERROR; - } - break; - case 18: /* Min */ - code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - switch (code) { - case 3: *result = MIN_8; return SIMPLICITY_NO_ERROR; - case 4: *result = MIN_16; return SIMPLICITY_NO_ERROR; - case 5: *result = MIN_32; return SIMPLICITY_NO_ERROR; - case 6: *result = MIN_64; return SIMPLICITY_NO_ERROR; - } - break; - case 19: /* Max */ - code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - switch (code) { - case 3: *result = MAX_8; return SIMPLICITY_NO_ERROR; - case 4: *result = MAX_16; return SIMPLICITY_NO_ERROR; - case 5: *result = MAX_32; return SIMPLICITY_NO_ERROR; - case 6: *result = MAX_64; return SIMPLICITY_NO_ERROR; - } - break; - case 20: /* Median */ - code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - switch (code) { - case 3: *result = MEDIAN_8; return SIMPLICITY_NO_ERROR; - case 4: *result = MEDIAN_16; return SIMPLICITY_NO_ERROR; - case 5: *result = MEDIAN_32; return SIMPLICITY_NO_ERROR; - case 6: *result = MEDIAN_64; return SIMPLICITY_NO_ERROR; - } - break; - case 21: /* Div2n1n */ - code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - switch (code) { - case 6: *result = DIV_MOD_128_64; return SIMPLICITY_NO_ERROR; - } - break; - case 22: /* DivMod */ - code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - switch (code) { - case 3: *result = DIV_MOD_8; return SIMPLICITY_NO_ERROR; - case 4: *result = DIV_MOD_16; return SIMPLICITY_NO_ERROR; - case 5: *result = DIV_MOD_32; return SIMPLICITY_NO_ERROR; - case 6: *result = DIV_MOD_64; return SIMPLICITY_NO_ERROR; - } - break; - case 23: /* Divide */ - code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - switch (code) { - case 3: *result = DIVIDE_8; return SIMPLICITY_NO_ERROR; - case 4: *result = DIVIDE_16; return SIMPLICITY_NO_ERROR; - case 5: *result = DIVIDE_32; return SIMPLICITY_NO_ERROR; - case 6: *result = DIVIDE_64; return SIMPLICITY_NO_ERROR; - } - break; - case 24: /* Modulo */ - code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - switch (code) { - case 3: *result = MODULO_8; return SIMPLICITY_NO_ERROR; - case 4: *result = MODULO_16; return SIMPLICITY_NO_ERROR; - case 5: *result = MODULO_32; return SIMPLICITY_NO_ERROR; - case 6: *result = MODULO_64; return SIMPLICITY_NO_ERROR; - } - break; - case 25: /* Divides */ - code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - switch (code) { - case 3: *result = DIVIDES_8; return SIMPLICITY_NO_ERROR; - case 4: *result = DIVIDES_16; return SIMPLICITY_NO_ERROR; - case 5: *result = DIVIDES_32; return SIMPLICITY_NO_ERROR; - case 6: *result = DIVIDES_64; return SIMPLICITY_NO_ERROR; - } - break; - } - break; - case 3: /* Hash jets chapter */ - code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - switch (code) { - case 1: /* SHA-256 section */ - code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - switch (code) { - case 1: *result = SHA_256_BLOCK; return SIMPLICITY_NO_ERROR; - case 2: *result = SHA_256_IV; return SIMPLICITY_NO_ERROR; - case 3: /* SHA-256-CTX-8-ADD-n subsection */ - code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - switch (code) { - case 1: *result = SHA_256_CTX_8_ADD_1; return SIMPLICITY_NO_ERROR; - case 2: *result = SHA_256_CTX_8_ADD_2; return SIMPLICITY_NO_ERROR; - case 3: *result = SHA_256_CTX_8_ADD_4; return SIMPLICITY_NO_ERROR; - case 4: *result = SHA_256_CTX_8_ADD_8; return SIMPLICITY_NO_ERROR; - case 5: *result = SHA_256_CTX_8_ADD_16; return SIMPLICITY_NO_ERROR; - case 6: *result = SHA_256_CTX_8_ADD_32; return SIMPLICITY_NO_ERROR; - case 7: *result = SHA_256_CTX_8_ADD_64; return SIMPLICITY_NO_ERROR; - case 8: *result = SHA_256_CTX_8_ADD_128; return SIMPLICITY_NO_ERROR; - case 9: *result = SHA_256_CTX_8_ADD_256; return SIMPLICITY_NO_ERROR; - case 10: *result = SHA_256_CTX_8_ADD_512; return SIMPLICITY_NO_ERROR; - } - break; - case 4: *result = SHA_256_CTX_8_ADD_BUFFER_511; return SIMPLICITY_NO_ERROR; - case 5: *result = SHA_256_CTX_8_FINALIZE; return SIMPLICITY_NO_ERROR; - case 6: *result = SHA_256_CTX_8_INIT; return SIMPLICITY_NO_ERROR; - } - break; - } - break; - case 4: /* Secp256k1 jets chapter */ - code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - switch (code) { - case 1: /* point-verify */ - code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - switch (code) { - case 1: *result = POINT_VERIFY_1; return SIMPLICITY_NO_ERROR; - } - break; - case 2: *result = DECOMPRESS; return SIMPLICITY_NO_ERROR; - case 3: /* linear-verify */ - code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - switch (code) { - case 1: *result = LINEAR_VERIFY_1; return SIMPLICITY_NO_ERROR; - } - break; - case 4: /* linear-combination */ - code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - switch (code) { - case 1: *result = LINEAR_COMBINATION_1; return SIMPLICITY_NO_ERROR; - } - break; - case 5: *result = SCALE; return SIMPLICITY_NO_ERROR; - case 6: *result = GENERATE; return SIMPLICITY_NO_ERROR; - case 7: *result = GEJ_INFINITY; return SIMPLICITY_NO_ERROR; - case 8: *result = GEJ_NORMALIZE; return SIMPLICITY_NO_ERROR; - case 9: *result = GEJ_NEGATE; return SIMPLICITY_NO_ERROR; - case 10: *result = GE_NEGATE; return SIMPLICITY_NO_ERROR; - case 11: *result = GEJ_DOUBLE; return SIMPLICITY_NO_ERROR; - case 12: *result = GEJ_ADD; return SIMPLICITY_NO_ERROR; - case 13: *result = GEJ_GE_ADD_EX; return SIMPLICITY_NO_ERROR; - case 14: *result = GEJ_GE_ADD; return SIMPLICITY_NO_ERROR; - case 15: *result = GEJ_RESCALE; return SIMPLICITY_NO_ERROR; - case 16: *result = GEJ_IS_INFINITY; return SIMPLICITY_NO_ERROR; - case 17: *result = GEJ_EQUIV; return SIMPLICITY_NO_ERROR; - case 18: *result = GEJ_GE_EQUIV; return SIMPLICITY_NO_ERROR; - case 19: *result = GEJ_X_EQUIV; return SIMPLICITY_NO_ERROR; - case 20: *result = GEJ_Y_IS_ODD; return SIMPLICITY_NO_ERROR; - case 21: *result = GEJ_IS_ON_CURVE; return SIMPLICITY_NO_ERROR; - case 22: *result = GE_IS_ON_CURVE; return SIMPLICITY_NO_ERROR; - case 23: *result = SCALAR_NORMALIZE; return SIMPLICITY_NO_ERROR; - case 24: *result = SCALAR_NEGATE; return SIMPLICITY_NO_ERROR; - case 25: *result = SCALAR_ADD; return SIMPLICITY_NO_ERROR; - case 26: *result = SCALAR_SQUARE; return SIMPLICITY_NO_ERROR; - case 27: *result = SCALAR_MULTIPLY; return SIMPLICITY_NO_ERROR; - case 28: *result = SCALAR_MULTIPLY_LAMBDA; return SIMPLICITY_NO_ERROR; - case 29: *result = SCALAR_INVERT; return SIMPLICITY_NO_ERROR; - case 30: *result = SCALAR_IS_ZERO; return SIMPLICITY_NO_ERROR; - - case 35: *result = FE_NORMALIZE; return SIMPLICITY_NO_ERROR; - case 36: *result = FE_NEGATE; return SIMPLICITY_NO_ERROR; - case 37: *result = FE_ADD; return SIMPLICITY_NO_ERROR; - case 38: *result = FE_SQUARE; return SIMPLICITY_NO_ERROR; - case 39: *result = FE_MULTIPLY; return SIMPLICITY_NO_ERROR; - case 40: *result = FE_MULTIPLY_BETA; return SIMPLICITY_NO_ERROR; - case 41: *result = FE_INVERT; return SIMPLICITY_NO_ERROR; - case 42: *result = FE_SQUARE_ROOT; return SIMPLICITY_NO_ERROR; - case 43: *result = FE_IS_ZERO; return SIMPLICITY_NO_ERROR; - case 44: *result = FE_IS_ODD; return SIMPLICITY_NO_ERROR; - - case 46: *result = HASH_TO_CURVE; return SIMPLICITY_NO_ERROR; - case 47: *result = SWU; return SIMPLICITY_NO_ERROR; - } - break; - case 5: /* Signature jets chapter */ - code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - switch (code) { - case 1: *result = CHECK_SIG_VERIFY; return SIMPLICITY_NO_ERROR; - case 2: *result = BIP_0340_VERIFY; return SIMPLICITY_NO_ERROR; - } - break; - case 7: /* Bitcoin jets chapter */ - code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - switch (code) { - case 1: *result = PARSE_LOCK; return SIMPLICITY_NO_ERROR; - case 2: *result = PARSE_SEQUENCE; return SIMPLICITY_NO_ERROR; - case 3: *result = TAPDATA_INIT; return SIMPLICITY_NO_ERROR; - } - break; - } +#include "../../decodeCoreJets.inc" return SIMPLICITY_ERR_DATA_OUT_OF_RANGE; } else { /* Elements jets */ - int32_t code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - switch (code) { - case 1: /* SigHash jets chapter */ - code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - switch (code) { - case 1: *result = SIG_ALL_HASH; return SIMPLICITY_NO_ERROR; - case 2: *result = TX_HASH; return SIMPLICITY_NO_ERROR; - case 3: *result = TAP_ENV_HASH; return SIMPLICITY_NO_ERROR; - case 4: *result = OUTPUTS_HASH; return SIMPLICITY_NO_ERROR; - case 5: *result = INPUTS_HASH; return SIMPLICITY_NO_ERROR; - case 6: *result = ISSUANCES_HASH; return SIMPLICITY_NO_ERROR; - case 7: *result = INPUT_UTXOS_HASH; return SIMPLICITY_NO_ERROR; - case 8: *result = OUTPUT_HASH; return SIMPLICITY_NO_ERROR; - case 9: *result = OUTPUT_AMOUNTS_HASH; return SIMPLICITY_NO_ERROR; - case 10: *result = OUTPUT_SCRIPTS_HASH; return SIMPLICITY_NO_ERROR; - case 11: *result = OUTPUT_NONCES_HASH; return SIMPLICITY_NO_ERROR; - case 12: *result = OUTPUT_RANGE_PROOFS_HASH; return SIMPLICITY_NO_ERROR; - case 13: *result = OUTPUT_SURJECTION_PROOFS_HASH; return SIMPLICITY_NO_ERROR; - case 14: *result = INPUT_HASH; return SIMPLICITY_NO_ERROR; - case 15: *result = INPUT_OUTPOINTS_HASH; return SIMPLICITY_NO_ERROR; - case 16: *result = INPUT_SEQUENCES_HASH; return SIMPLICITY_NO_ERROR; - case 17: *result = INPUT_ANNEXES_HASH; return SIMPLICITY_NO_ERROR; - case 18: *result = INPUT_SCRIPT_SIGS_HASH; return SIMPLICITY_NO_ERROR; - case 19: *result = ISSUANCE_HASH; return SIMPLICITY_NO_ERROR; - case 20: *result = ISSUANCE_ASSET_AMOUNTS_HASH; return SIMPLICITY_NO_ERROR; - case 21: *result = ISSUANCE_TOKEN_AMOUNTS_HASH; return SIMPLICITY_NO_ERROR; - case 22: *result = ISSUANCE_RANGE_PROOFS_HASH; return SIMPLICITY_NO_ERROR; - case 23: *result = ISSUANCE_BLINDING_ENTROPY_HASH; return SIMPLICITY_NO_ERROR; - case 24: *result = INPUT_UTXO_HASH; return SIMPLICITY_NO_ERROR; - case 25: *result = INPUT_AMOUNTS_HASH; return SIMPLICITY_NO_ERROR; - case 26: *result = INPUT_SCRIPTS_HASH; return SIMPLICITY_NO_ERROR; - case 27: *result = TAPLEAF_HASH; return SIMPLICITY_NO_ERROR; - case 28: *result = TAPPATH_HASH; return SIMPLICITY_NO_ERROR; - case 29: *result = OUTPOINT_HASH; return SIMPLICITY_NO_ERROR; - case 30: *result = ASSET_AMOUNT_HASH; return SIMPLICITY_NO_ERROR; - case 31: *result = NONCE_HASH; return SIMPLICITY_NO_ERROR; - case 32: *result = ANNEX_HASH; return SIMPLICITY_NO_ERROR; - case 33: *result = BUILD_TAPLEAF_SIMPLICITY; return SIMPLICITY_NO_ERROR; - case 34: *result = BUILD_TAPBRANCH; return SIMPLICITY_NO_ERROR; - case 35: *result = BUILD_TAPTWEAK; return SIMPLICITY_NO_ERROR; - } - break; - case 2: /* Timelock jets chapter */ - code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - switch (code) { - case 1: *result = CHECK_LOCK_HEIGHT; return SIMPLICITY_NO_ERROR; - case 2: *result = CHECK_LOCK_TIME; return SIMPLICITY_NO_ERROR; - case 3: *result = CHECK_LOCK_DISTANCE; return SIMPLICITY_NO_ERROR; - case 4: *result = CHECK_LOCK_DURATION; return SIMPLICITY_NO_ERROR; - case 5: *result = TX_LOCK_HEIGHT; return SIMPLICITY_NO_ERROR; - case 6: *result = TX_LOCK_TIME; return SIMPLICITY_NO_ERROR; - case 7: *result = TX_LOCK_DISTANCE; return SIMPLICITY_NO_ERROR; - case 8: *result = TX_LOCK_DURATION; return SIMPLICITY_NO_ERROR; - case 9: *result = TX_IS_FINAL; return SIMPLICITY_NO_ERROR; - } - break; - case 3: /* Issuance jets chapter */ - code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - switch (code) { - case 1: *result = ISSUANCE; return SIMPLICITY_NO_ERROR; - case 2: *result = ISSUANCE_ASSET; return SIMPLICITY_NO_ERROR; - case 3: *result = ISSUANCE_TOKEN; return SIMPLICITY_NO_ERROR; - case 4: *result = ISSUANCE_ENTROPY; return SIMPLICITY_NO_ERROR; - case 5: *result = CALCULATE_ISSUANCE_ENTROPY; return SIMPLICITY_NO_ERROR; - case 6: *result = CALCULATE_ASSET; return SIMPLICITY_NO_ERROR; - case 7: *result = CALCULATE_EXPLICIT_TOKEN; return SIMPLICITY_NO_ERROR; - case 8: *result = CALCULATE_CONFIDENTIAL_TOKEN; return SIMPLICITY_NO_ERROR; - case 9: *result = LBTC_ASSET; return SIMPLICITY_NO_ERROR; - } - break; - case 4: /* Transaction jets chapter */ - code = simplicity_decodeUptoMaxInt(stream); - if (code < 0) return (simplicity_err)code; - switch (code) { - case 1: *result = SCRIPT_CMR; return SIMPLICITY_NO_ERROR; - case 2: *result = INTERNAL_KEY; return SIMPLICITY_NO_ERROR; - case 3: *result = CURRENT_INDEX; return SIMPLICITY_NO_ERROR; - case 4: *result = NUM_INPUTS; return SIMPLICITY_NO_ERROR; - case 5: *result = NUM_OUTPUTS; return SIMPLICITY_NO_ERROR; - case 6: *result = LOCK_TIME; return SIMPLICITY_NO_ERROR; - case 7: *result = OUTPUT_ASSET; return SIMPLICITY_NO_ERROR; - case 8: *result = OUTPUT_AMOUNT; return SIMPLICITY_NO_ERROR; - case 9: *result = OUTPUT_NONCE; return SIMPLICITY_NO_ERROR; - case 10: *result = OUTPUT_SCRIPT_HASH; return SIMPLICITY_NO_ERROR; - case 11: *result = OUTPUT_NULL_DATUM; return SIMPLICITY_NO_ERROR; - case 12: *result = OUTPUT_IS_FEE; return SIMPLICITY_NO_ERROR; - case 13: *result = OUTPUT_SURJECTION_PROOF; return SIMPLICITY_NO_ERROR; - case 14: *result = OUTPUT_RANGE_PROOF; return SIMPLICITY_NO_ERROR; - case 15: *result = TOTAL_FEE; return SIMPLICITY_NO_ERROR; - case 16: *result = CURRENT_PEGIN; return SIMPLICITY_NO_ERROR; - case 17: *result = CURRENT_PREV_OUTPOINT; return SIMPLICITY_NO_ERROR; - case 18: *result = CURRENT_ASSET; return SIMPLICITY_NO_ERROR; - case 19: *result = CURRENT_AMOUNT; return SIMPLICITY_NO_ERROR; - case 20: *result = CURRENT_SCRIPT_HASH; return SIMPLICITY_NO_ERROR; - case 21: *result = CURRENT_SEQUENCE; return SIMPLICITY_NO_ERROR; - case 22: *result = CURRENT_ANNEX_HASH; return SIMPLICITY_NO_ERROR; - case 23: *result = CURRENT_SCRIPT_SIG_HASH; return SIMPLICITY_NO_ERROR; - case 24: *result = CURRENT_REISSUANCE_BLINDING; return SIMPLICITY_NO_ERROR; - case 25: *result = CURRENT_NEW_ISSUANCE_CONTRACT; return SIMPLICITY_NO_ERROR; - case 26: *result = CURRENT_REISSUANCE_ENTROPY; return SIMPLICITY_NO_ERROR; - case 27: *result = CURRENT_ISSUANCE_ASSET_AMOUNT; return SIMPLICITY_NO_ERROR; - case 28: *result = CURRENT_ISSUANCE_TOKEN_AMOUNT; return SIMPLICITY_NO_ERROR; - case 29: *result = CURRENT_ISSUANCE_ASSET_PROOF; return SIMPLICITY_NO_ERROR; - case 30: *result = CURRENT_ISSUANCE_TOKEN_PROOF; return SIMPLICITY_NO_ERROR; - case 31: *result = INPUT_PEGIN; return SIMPLICITY_NO_ERROR; - case 32: *result = INPUT_PREV_OUTPOINT; return SIMPLICITY_NO_ERROR; - case 33: *result = INPUT_ASSET; return SIMPLICITY_NO_ERROR; - case 34: *result = INPUT_AMOUNT; return SIMPLICITY_NO_ERROR; - case 35: *result = INPUT_SCRIPT_HASH; return SIMPLICITY_NO_ERROR; - case 36: *result = INPUT_SEQUENCE; return SIMPLICITY_NO_ERROR; - case 37: *result = INPUT_ANNEX_HASH; return SIMPLICITY_NO_ERROR; - case 38: *result = INPUT_SCRIPT_SIG_HASH; return SIMPLICITY_NO_ERROR; - case 39: *result = REISSUANCE_BLINDING; return SIMPLICITY_NO_ERROR; - case 40: *result = NEW_ISSUANCE_CONTRACT; return SIMPLICITY_NO_ERROR; - case 41: *result = REISSUANCE_ENTROPY; return SIMPLICITY_NO_ERROR; - case 42: *result = ISSUANCE_ASSET_AMOUNT; return SIMPLICITY_NO_ERROR; - case 43: *result = ISSUANCE_TOKEN_AMOUNT; return SIMPLICITY_NO_ERROR; - case 44: *result = ISSUANCE_ASSET_PROOF; return SIMPLICITY_NO_ERROR; - case 45: *result = ISSUANCE_TOKEN_PROOF; return SIMPLICITY_NO_ERROR; - case 46: *result = TAPLEAF_VERSION; return SIMPLICITY_NO_ERROR; - case 47: *result = TAPPATH; return SIMPLICITY_NO_ERROR; - case 48: *result = VERSION; return SIMPLICITY_NO_ERROR; - case 49: *result = GENESIS_BLOCK_HASH; return SIMPLICITY_NO_ERROR; - case 50: *result = TRANSACTION_ID; return SIMPLICITY_NO_ERROR; - } - break; - } +#include "decodeElementsJets.inc" return SIMPLICITY_ERR_DATA_OUT_OF_RANGE; } } diff --git a/schnorr0.c b/schnorr0.c index 9064f31330..bf0a475342 100644 --- a/schnorr0.c +++ b/schnorr0.c @@ -29,8 +29,8 @@ const uint32_t schnorr0_cmr[] = { 0x8a9e9767u, 0x6b24be77u, 0x97d9ee0bu, 0xf32dd76bu, 0xcd78028eu, 0x973025f7u, 0x85eae8dcu, 0x91c8a0dau }; -/* The identity Merkle root of the above schnorr0 Simplicity expression. */ -const uint32_t schnorr0_imr[] = { +/* The identity hash of the root of the above schnorr0 Simplicity expression. */ +const uint32_t schnorr0_ihr[] = { 0xad7c38b1u, 0x6b912964u, 0x6dc89b52u, 0xcff144deu, 0x94a80e38u, 0x3c4983b5u, 0x3de65e35u, 0x75abcf38u }; diff --git a/schnorr0.h b/schnorr0.h index 6ead60e508..1513d31dd9 100644 --- a/schnorr0.h +++ b/schnorr0.h @@ -20,8 +20,8 @@ extern const size_t sizeof_schnorr0_witness; /* The commitment Merkle root of the above schnorr0 Simplicity expression. */ extern const uint32_t schnorr0_cmr[]; -/* The identity Merkle root of the above schnorr0 Simplicity expression. */ -extern const uint32_t schnorr0_imr[]; +/* The identity hash of the root of the above schnorr0 Simplicity expression. */ +extern const uint32_t schnorr0_ihr[]; /* The annotated Merkle root of the above schnorr0 Simplicity expression. */ extern const uint32_t schnorr0_amr[]; diff --git a/schnorr6.c b/schnorr6.c index d02059d2af..9b6a11d339 100644 --- a/schnorr6.c +++ b/schnorr6.c @@ -29,8 +29,8 @@ const uint32_t schnorr6_cmr[] = { 0x83b6b5bcu, 0xc9bdc956u, 0xaf326376u, 0xf201aa7au, 0x2e65bb9eu, 0xedca6a06u, 0x65976452u, 0x5203cf68u }; -/* The identity Merkle root of the above schnorr6 Simplicity expression. */ -const uint32_t schnorr6_imr[] = { +/* The identity hash of the root of the above schnorr6 Simplicity expression. */ +const uint32_t schnorr6_ihr[] = { 0x53acece2u, 0xa5e61e36u, 0xd6c57f92u, 0x4cff9c45u, 0x0a283badu, 0x853aab59u, 0xebdf384du, 0x26264fefu }; diff --git a/schnorr6.h b/schnorr6.h index a90bbd690e..8ad66a7bdb 100644 --- a/schnorr6.h +++ b/schnorr6.h @@ -20,8 +20,8 @@ extern const size_t sizeof_schnorr6_witness; /* The commitment Merkle root of the above schnorr6 Simplicity expression. */ extern const uint32_t schnorr6_cmr[]; -/* The identity Merkle root of the above schnorr6 Simplicity expression. */ -extern const uint32_t schnorr6_imr[]; +/* The identity hash of the root of the above schnorr6 Simplicity expression. */ +extern const uint32_t schnorr6_ihr[]; /* The annotated Merkle root of the above schnorr6 Simplicity expression. */ extern const uint32_t schnorr6_amr[]; diff --git a/secp256k1/int128_struct.h b/secp256k1/int128_struct.h index 6156f82cc2..e835062a95 100644 --- a/secp256k1/int128_struct.h +++ b/secp256k1/int128_struct.h @@ -4,7 +4,7 @@ #include #include "util.h" -typedef struct { +typedef struct secp256k1_uint128 { uint64_t lo; uint64_t hi; } secp256k1_uint128; diff --git a/secp256k1/modinv64.h b/secp256k1/modinv64.h index dda494f0bd..fc263edf4c 100644 --- a/secp256k1/modinv64.h +++ b/secp256k1/modinv64.h @@ -16,11 +16,11 @@ /* A signed 62-bit limb representation of integers. * * Its value is sum(v[i] * 2^(62*i), i=0..4). */ -typedef struct { +typedef struct secp256k1_modinv64_signed62 { int64_t v[5]; } secp256k1_modinv64_signed62; -typedef struct { +typedef struct secp256k1_modinv64_modinfo { /* The modulus in signed62 notation, must be odd and in [3, 2^256]. */ secp256k1_modinv64_signed62 modulus; @@ -28,6 +28,18 @@ typedef struct { uint64_t modulus_inv62; } secp256k1_modinv64_modinfo; +static inline void secp256k1_modinv64_signed62_assign(secp256k1_modinv64_signed62 *dst, const secp256k1_modinv64_signed62 *src) { +#ifdef VST + dst->v[0] = src->v[0]; + dst->v[1] = src->v[1]; + dst->v[2] = src->v[2]; + dst->v[3] = src->v[3]; + dst->v[4] = src->v[4]; +#else + *dst = *src; +#endif +} + /* Replace x with its modular inverse mod modinfo->modulus. x must be in range [0, modulus). * If x is zero, the result will be zero as well. If not, the inverse must exist (i.e., the gcd of * x and modulus must be 1). These rules are automatically satisfied if the modulus is prime. diff --git a/secp256k1/modinv64_impl.h b/secp256k1/modinv64_impl.h index 13e2c693e5..191de31f17 100644 --- a/secp256k1/modinv64_impl.h +++ b/secp256k1/modinv64_impl.h @@ -22,7 +22,7 @@ * t = [ u v ] * [ q r ] */ -typedef struct { +typedef struct secp256k1_modinv64_trans2x2 { int64_t u, v, q, r; } secp256k1_modinv64_trans2x2; @@ -651,8 +651,10 @@ static void secp256k1_modinv64_var(secp256k1_modinv64_signed62 *x, const secp256 /* Start with d=0, e=1, f=modulus, g=x, eta=-1. */ secp256k1_modinv64_signed62 d = {{0, 0, 0, 0, 0}}; secp256k1_modinv64_signed62 e = {{1, 0, 0, 0, 0}}; - secp256k1_modinv64_signed62 f = modinfo->modulus; - secp256k1_modinv64_signed62 g = *x; + secp256k1_modinv64_signed62 f, g; + secp256k1_modinv64_signed62_assign(&(f), &(modinfo->modulus)); + secp256k1_modinv64_signed62_assign(&(g), &(*x)); + #ifdef VERIFY int i = 0; #endif @@ -723,7 +725,7 @@ static void secp256k1_modinv64_var(secp256k1_modinv64_signed62 *x, const secp256 /* Optionally negate d, normalize to [0,modulus), and return it. */ secp256k1_modinv64_normalize_62(&d, f.v[len - 1], modinfo); - *x = d; + secp256k1_modinv64_signed62_assign(&(*x), &(d)); } #if 0 diff --git a/secp256k1/precomputed_ecmult.h b/secp256k1/precomputed_ecmult.h index d04a45c3d0..a80bc49827 100644 --- a/secp256k1/precomputed_ecmult.h +++ b/secp256k1/precomputed_ecmult.h @@ -18,7 +18,9 @@ # error Cannot compile precomputed_ecmult.c in exhaustive test mode #endif /* EXHAUSTIVE_TEST_ORDER */ #define WINDOW_G ECMULT_WINDOW_SIZE -static const secp256k1_ge_storage secp256k1_pre_g[ECMULT_TABLE_SIZE(WINDOW_G)] = { +static const secp256k1_ge_storage secp256k1_pre_g[ECMULT_TABLE_SIZE(WINDOW_G)] +#ifndef VST + = { S(79be667e,f9dcbbac,55a06295,ce870b07,29bfcdb,2dce28d9,59f2815b,16f81798,483ada77,26a3c465,5da4fbfc,e1108a8,fd17b448,a6855419,9c47d08f,fb10d4b8) #if WINDOW_G > 2 ,S(f9308a01,9258c310,49344f85,f89d5229,b531c845,836f99b0,8601f113,bce036f9,388f7b0f,632de814,fe337e6,2a37f356,6500a999,34c2231b,6cb9fd75,84b8e672) @@ -8237,8 +8239,12 @@ static const secp256k1_ge_storage secp256k1_pre_g[ECMULT_TABLE_SIZE(WINDOW_G)] = ,S(20990660,f1055420,b885fb0a,38824740,3b141c37,5aa20dce,8a29191a,e77bbb16,7d434476,9e302e38,9e14c02e,f5fd8a5c,64cfcf3d,e9813f1c,f53bc6d3,4da93559) ,S(1e70619c,381a6adc,e5d925e0,c9c74f97,3c02ff64,ff2662d7,34efc485,d2bce895,c923f771,f543ffed,42935c28,8474aaaf,80a46ad4,3c579ce0,bb5e663d,668b24b3) #endif -}; -static const secp256k1_ge_storage secp256k1_pre_g_128[ECMULT_TABLE_SIZE(WINDOW_G)] = { +} +#endif +; +static const secp256k1_ge_storage secp256k1_pre_g_128[ECMULT_TABLE_SIZE(WINDOW_G)] +#ifndef VST + = { S(8f68b9d2,f63b5f33,9239c1ad,981f162e,e88c5678,723ea335,1b7b444c,9ec4c0da,662a9f2d,ba063986,de1d90c2,b6be215d,bbea2cfe,95510bfd,f23cbf79,501fff82) #if WINDOW_G > 2 ,S(38381dbe,2e509f22,8ba93363,f2451f08,fd845cb3,51d954be,18e2b8ed,d23809fa,e4a32d0a,fb917dc,b09405a5,520eb1cc,3681fccb,32d8f24d,bd707518,331fed52) @@ -16457,7 +16463,9 @@ static const secp256k1_ge_storage secp256k1_pre_g_128[ECMULT_TABLE_SIZE(WINDOW_G ,S(15a1ae40,b4fc51dc,554b75d4,db0c2bfd,62dfbbfc,dede18e1,4edbb689,91525cff,4f0453b7,e4e0e99d,9663e5c6,bb018007,b52c8e14,d78a28d,c4a888e4,8c4326c2) ,S(1b9a142f,fc4d03ea,4b079f2d,b05fad98,8ddb2d32,b359967f,c173801f,63320825,59bda7ed,5b691c20,4fc8f8ac,f53be298,ae628954,a8134d0f,dd097e67,be9ff9b6) #endif -}; +} +#endif +; #undef S #endif /* SECP256K1_PRECOMPUTED_ECMULT_H */ diff --git a/test.c b/test.c index b5033bd5e7..445b572678 100644 --- a/test.c +++ b/test.c @@ -127,13 +127,13 @@ static void test_hashBlock(void) { } } { - sha256_midstate imr; - if (IS_OK(simplicity_verifyNoDuplicateIdentityRoots(&imr, dag, type_dag, (uint_fast32_t)len)) && - 0 == memcmp(hashBlock_imr, imr.s, sizeof(uint32_t[8]))) { + sha256_midstate ihr; + if (IS_OK(simplicity_verifyNoDuplicateIdentityHashes(&ihr, dag, type_dag, (uint_fast32_t)len)) && + 0 == memcmp(hashBlock_ihr, ihr.s, sizeof(uint32_t[8]))) { successes++; } else { failures++; - printf("Unexpected IMR of hashblock\n"); + printf("Unexpected IHR of hashblock\n"); } } @@ -187,7 +187,7 @@ static void test_hashBlock(void) { static void test_program(char* name, const unsigned char* program, size_t program_len, const unsigned char* witness, size_t witness_len, simplicity_err expectedResult, const uint32_t* expectedCMR, - const uint32_t* expectedIMR, const uint32_t* expectedAMR, const ubounded *expectedCost) { + const uint32_t* expectedIHR, const uint32_t* expectedAMR, const ubounded *expectedCost) { printf("Test %s\n", name); dag_node* dag; combinator_counters census; @@ -253,13 +253,13 @@ static void test_program(char* name, const unsigned char* program, size_t progra } } { - sha256_midstate imr; - if (IS_OK(simplicity_verifyNoDuplicateIdentityRoots(&imr, dag, type_dag, (uint_fast32_t)len)) && - (!expectedIMR || 0 == memcmp(expectedIMR, imr.s, sizeof(uint32_t[8])))) { + sha256_midstate ihr; + if (IS_OK(simplicity_verifyNoDuplicateIdentityHashes(&ihr, dag, type_dag, (uint_fast32_t)len)) && + (!expectedIHR || 0 == memcmp(expectedIHR, ihr.s, sizeof(uint32_t[8])))) { successes++; } else { failures++; - printf("Unexpected IMR.\n"); + printf("Unexpected IHR.\n"); } } if (expectedCost) { @@ -404,15 +404,15 @@ static void test_elements(void) { } } { - unsigned char imrResult[32]; - if (simplicity_elements_execSimplicity(&execResult, imrResult, tx1, 0, taproot, genesisHash, (elementsCheckSigHashAllTx1_cost + 999)/1000, amr, elementsCheckSigHashAllTx1, sizeof_elementsCheckSigHashAllTx1, elementsCheckSigHashAllTx1_witness, sizeof_elementsCheckSigHashAllTx1_witness) && IS_OK(execResult)) { - sha256_midstate imr; - sha256_toMidstate(imr.s, imrResult); - if (0 == memcmp(imr.s, elementsCheckSigHashAllTx1_imr, sizeof(uint32_t[8]))) { + unsigned char ihrResult[32]; + if (simplicity_elements_execSimplicity(&execResult, ihrResult, tx1, 0, taproot, genesisHash, (elementsCheckSigHashAllTx1_cost + 999)/1000, amr, elementsCheckSigHashAllTx1, sizeof_elementsCheckSigHashAllTx1, elementsCheckSigHashAllTx1_witness, sizeof_elementsCheckSigHashAllTx1_witness) && IS_OK(execResult)) { + sha256_midstate ihr; + sha256_toMidstate(ihr.s, ihrResult); + if (0 == memcmp(ihr.s, elementsCheckSigHashAllTx1_ihr, sizeof(uint32_t[8]))) { successes++; } else { failures++; - printf("Unexpected IMR of elementsCheckSigHashAllTx1\n"); + printf("Unexpected IHR of elementsCheckSigHashAllTx1\n"); } } else { failures++; @@ -421,7 +421,7 @@ static void test_elements(void) { if (elementsCheckSigHashAllTx1_cost){ /* test the same transaction without adequate budget. */ simplicity_assert(elementsCheckSigHashAllTx1_cost); - if (simplicity_elements_execSimplicity(&execResult, imrResult, tx1, 0, taproot, genesisHash, (elementsCheckSigHashAllTx1_cost - 1)/1000, amr, elementsCheckSigHashAllTx1, sizeof_elementsCheckSigHashAllTx1, elementsCheckSigHashAllTx1_witness, sizeof_elementsCheckSigHashAllTx1_witness) && SIMPLICITY_ERR_EXEC_BUDGET == execResult) { + if (simplicity_elements_execSimplicity(&execResult, ihrResult, tx1, 0, taproot, genesisHash, (elementsCheckSigHashAllTx1_cost - 1)/1000, amr, elementsCheckSigHashAllTx1, sizeof_elementsCheckSigHashAllTx1, elementsCheckSigHashAllTx1_witness, sizeof_elementsCheckSigHashAllTx1_witness) && SIMPLICITY_ERR_EXEC_BUDGET == execResult) { successes++; } else { failures++; @@ -445,7 +445,7 @@ static void test_elements(void) { printf("mallocTransaction(&rawTx1) failed\n"); failures++; } - simplicity_free(tx1); + simplicity_elements_freeTransaction(tx1); } /* test a modified transaction with the same signature. */ { @@ -494,9 +494,9 @@ static void test_elements(void) { printf("mallocTransaction(&testTx2) failed\n"); failures++; } - simplicity_free(tx2); + simplicity_elements_freeTransaction(tx2); } - simplicity_free(taproot); + simplicity_elements_freeTapEnv(taproot); } static sha256_midstate hashint(uint_fast32_t n) { @@ -664,16 +664,16 @@ int main(int argc, char **argv) { test_hasDuplicates("hasDuplicates one duplicate testcase", 1, rsort_one_duplicate, 10000); test_hasDuplicates("hasDuplicates diagonal testcase", 0, rsort_diagonal, 33); - test_program("ctx8Pruned", ctx8Pruned, sizeof_ctx8Pruned, ctx8Pruned_witness, sizeof_ctx8Pruned_witness, SIMPLICITY_NO_ERROR, ctx8Pruned_cmr, ctx8Pruned_imr, ctx8Pruned_amr, &ctx8Pruned_cost); - test_program("ctx8Unpruned", ctx8Unpruned, sizeof_ctx8Unpruned, ctx8Unpruned_witness, sizeof_ctx8Unpruned_witness, SIMPLICITY_ERR_ANTIDOS, ctx8Unpruned_cmr, ctx8Unpruned_imr, ctx8Unpruned_amr, &ctx8Unpruned_cost); + test_program("ctx8Pruned", ctx8Pruned, sizeof_ctx8Pruned, ctx8Pruned_witness, sizeof_ctx8Pruned_witness, SIMPLICITY_NO_ERROR, ctx8Pruned_cmr, ctx8Pruned_ihr, ctx8Pruned_amr, &ctx8Pruned_cost); + test_program("ctx8Unpruned", ctx8Unpruned, sizeof_ctx8Unpruned, ctx8Unpruned_witness, sizeof_ctx8Unpruned_witness, SIMPLICITY_ERR_ANTIDOS, ctx8Unpruned_cmr, ctx8Unpruned_ihr, ctx8Unpruned_amr, &ctx8Unpruned_cost); if (0 == memcmp(ctx8Pruned_cmr, ctx8Unpruned_cmr, sizeof(uint32_t[8]))) { successes++; } else { failures++; printf("Pruned and Unpruned CMRs are not the same.\n"); } - test_program("schnorr0", schnorr0, sizeof_schnorr0, schnorr0_witness, sizeof_schnorr0_witness, SIMPLICITY_NO_ERROR, schnorr0_cmr, schnorr0_imr, schnorr0_amr, &schnorr0_cost); - test_program("schnorr6", schnorr6, sizeof_schnorr6, schnorr6_witness, sizeof_schnorr6_witness, SIMPLICITY_ERR_EXEC_JET, schnorr6_cmr, schnorr6_imr, schnorr6_amr, &schnorr0_cost); + test_program("schnorr0", schnorr0, sizeof_schnorr0, schnorr0_witness, sizeof_schnorr0_witness, SIMPLICITY_NO_ERROR, schnorr0_cmr, schnorr0_ihr, schnorr0_amr, &schnorr0_cost); + test_program("schnorr6", schnorr6, sizeof_schnorr6, schnorr6_witness, sizeof_schnorr6_witness, SIMPLICITY_ERR_EXEC_JET, schnorr6_cmr, schnorr6_ihr, schnorr6_amr, &schnorr0_cost); test_program("typeSkipTest", typeSkipTest, sizeof_typeSkipTest, typeSkipTest_witness, sizeof_typeSkipTest_witness, SIMPLICITY_NO_ERROR, NULL, NULL, NULL, NULL); test_elements(); regression_tests(); diff --git a/typeSkipTest.c b/typeSkipTest.c index 1a8ac83a63..0629f1645a 100644 --- a/typeSkipTest.c +++ b/typeSkipTest.c @@ -48,8 +48,8 @@ const uint32_t typeSkipTest_cmr[] = { 0x2a791cd8u, 0xf1e2beeau, 0x883e53f2u, 0xce36db2bu, 0x246b3156u, 0xcc40f91bu, 0xb2f59059u, 0xb601ac4au }; -/* The identity Merkle root of the above typeSkipTest Simplicity expression. */ -const uint32_t typeSkipTest_imr[] = { +/* The identity hash of the root of the above typeSkipTest Simplicity expression. */ +const uint32_t typeSkipTest_ihr[] = { 0xbadac773u, 0x19e9cabau, 0x7fe49174u, 0x54d0e25eu, 0x7d4c4a7eu, 0x4867c392u, 0x20bf409au, 0xc6e6bf10u }; diff --git a/typeSkipTest.h b/typeSkipTest.h index 73b308b59a..61230c1060 100644 --- a/typeSkipTest.h +++ b/typeSkipTest.h @@ -38,8 +38,8 @@ extern const size_t sizeof_typeSkipTest_witness; /* The commitment Merkle root of the above typeSkipTest Simplicity expression. */ extern const uint32_t typeSkipTest_cmr[]; -/* The identity Merkle root of the above typeSkipTest Simplicity expression. */ -extern const uint32_t typeSkipTest_imr[]; +/* The identity hash of the root of the above typeSkipTest Simplicity expression. */ +extern const uint32_t typeSkipTest_ihr[]; /* The annotated Merkle root of the above typeSkipTest Simplicity expression. */ extern const uint32_t typeSkipTest_amr[]; From 31d94775b3254b88cce6131067c8884a4a4b40af Mon Sep 17 00:00:00 2001 From: Russell O'Connor Date: Fri, 31 Jan 2025 07:35:25 -0500 Subject: [PATCH 04/22] Update to latest Simplicity The main difference is that there is now explicit simplicity deallocation functions to go with the allocation functions in the API. There are some minor changes to error message text. The deserialization code is now automatically generated. The are some other minor internal changes. --- src/script/interpreter.cpp | 4 ++-- src/script/interpreter.h | 2 +- src/script/script_error.cpp | 4 ++-- src/script/script_error.h | 2 +- src/test/script_tests.cpp | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index 1f24c69c1f..de5a3c499a 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -3124,7 +3124,7 @@ bool GenericTransactionSignatureChecker::CheckSimplicity(const valtype& progr if (!simplicity_elements_execSimplicity(&error, 0, txdata->m_simplicity_tx_data, nIn, simplicityTapEnv, txdata->m_hash_genesis_block.data(), budget, 0, program.data(), program.size(), witness.data(), witness.size())) { assert(!"simplicity_elements_execSimplicity internal error"); } - free(simplicityTapEnv); + simplicity_elements_freeTapEnv(simplicityTapEnv); switch (error) { case SIMPLICITY_NO_ERROR: return set_success(serror); case SIMPLICITY_ERR_MALLOC: @@ -3134,7 +3134,7 @@ bool GenericTransactionSignatureChecker::CheckSimplicity(const valtype& progr case SIMPLICITY_ERR_DATA_OUT_OF_RANGE: return set_error(serror, SCRIPT_ERR_SIMPLICITY_DATA_OUT_OF_RANGE); case SIMPLICITY_ERR_DATA_OUT_OF_ORDER: return set_error(serror, SCRIPT_ERR_SIMPLICITY_DATA_OUT_OF_ORDER); case SIMPLICITY_ERR_FAIL_CODE: return set_error(serror, SCRIPT_ERR_SIMPLICITY_FAIL_CODE); - case SIMPLICITY_ERR_STOP_CODE: return set_error(serror, SCRIPT_ERR_SIMPLICITY_STOP_CODE); + case SIMPLICITY_ERR_RESERVED_CODE: return set_error(serror, SCRIPT_ERR_SIMPLICITY_RESERVED_CODE); case SIMPLICITY_ERR_HIDDEN: return set_error(serror, SCRIPT_ERR_SIMPLICITY_HIDDEN); case SIMPLICITY_ERR_BITSTREAM_EOF: return set_error(serror, SCRIPT_ERR_SIMPLICITY_BITSTREAM_EOF); case SIMPLICITY_ERR_BITSTREAM_TRAILING_BYTES: return set_error(serror, SCRIPT_ERR_SIMPLICITY_BITSTREAM_TRAILING_BYTES); diff --git a/src/script/interpreter.h b/src/script/interpreter.h index 4881b74651..e317a3aad5 100644 --- a/src/script/interpreter.h +++ b/src/script/interpreter.h @@ -222,7 +222,7 @@ struct PrecomputedTransactionData template explicit PrecomputedTransactionData(const T& tx); ~PrecomputedTransactionData() { - free(m_simplicity_tx_data); + simplicity_elements_freeTransaction(m_simplicity_tx_data); } }; diff --git a/src/script/script_error.cpp b/src/script/script_error.cpp index b7be7b2139..a50888dd8f 100644 --- a/src/script/script_error.cpp +++ b/src/script/script_error.cpp @@ -140,8 +140,8 @@ std::string ScriptErrorString(const ScriptError serror) return SIMPLICITY_ERR_MSG(SIMPLICITY_ERR_DATA_OUT_OF_ORDER); case SCRIPT_ERR_SIMPLICITY_FAIL_CODE: return SIMPLICITY_ERR_MSG(SIMPLICITY_ERR_FAIL_CODE); - case SCRIPT_ERR_SIMPLICITY_STOP_CODE: - return SIMPLICITY_ERR_MSG(SIMPLICITY_ERR_STOP_CODE); + case SCRIPT_ERR_SIMPLICITY_RESERVED_CODE: + return SIMPLICITY_ERR_MSG(SIMPLICITY_ERR_RESERVED_CODE); case SCRIPT_ERR_SIMPLICITY_HIDDEN: return SIMPLICITY_ERR_MSG(SIMPLICITY_ERR_HIDDEN); case SCRIPT_ERR_SIMPLICITY_BITSTREAM_EOF: diff --git a/src/script/script_error.h b/src/script/script_error.h index db137937f2..8fac6496d0 100644 --- a/src/script/script_error.h +++ b/src/script/script_error.h @@ -102,7 +102,7 @@ typedef enum ScriptError_t SCRIPT_ERR_SIMPLICITY_DATA_OUT_OF_RANGE, SCRIPT_ERR_SIMPLICITY_DATA_OUT_OF_ORDER, SCRIPT_ERR_SIMPLICITY_FAIL_CODE, - SCRIPT_ERR_SIMPLICITY_STOP_CODE, + SCRIPT_ERR_SIMPLICITY_RESERVED_CODE, SCRIPT_ERR_SIMPLICITY_HIDDEN, SCRIPT_ERR_SIMPLICITY_BITSTREAM_EOF, SCRIPT_ERR_SIMPLICITY_BITSTREAM_TRAILING_BYTES, diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index 3ddf915f3a..37e6f77c36 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -121,7 +121,7 @@ static ScriptErrorDesc script_errors[]={ {SCRIPT_ERR_SIMPLICITY_DATA_OUT_OF_RANGE, "SIMPLICITY_DATA_OUT_OF_RANGE"}, {SCRIPT_ERR_SIMPLICITY_DATA_OUT_OF_ORDER, "SIMPLICITY_DATA_OUT_OF_ORDER"}, {SCRIPT_ERR_SIMPLICITY_FAIL_CODE, "SIMPLICITY_FAIL_CODE"}, - {SCRIPT_ERR_SIMPLICITY_STOP_CODE, "SIMPLICITY_STOP_CODE"}, + {SCRIPT_ERR_SIMPLICITY_RESERVED_CODE, "SIMPLICITY_RESERVED_CODE"}, {SCRIPT_ERR_SIMPLICITY_HIDDEN, "SIMPLICITY_HIDDEN"}, {SCRIPT_ERR_SIMPLICITY_BITSTREAM_EOF, "SIMPLICITY_BITSTREAM_EOF"}, {SCRIPT_ERR_SIMPLICITY_BITSTREAM_TRAILING_BYTES, "SIMPLICITY_BITSTREAM_TRAILING_BYTES"}, From 00399aa1177dfaebaf16a3d62e2b92140158f45a Mon Sep 17 00:00:00 2001 From: Russell O'Connor Date: Tue, 4 Feb 2025 11:48:18 -0500 Subject: [PATCH 05/22] Enable coverage for simplicity/secp256k1 While the bitcoin/elements project testing isn't trying to gain coverage of the regular libsecp256k1 library, in our case we do want our (fuzz) testing to cover simplicity's own copy of libsecp256k1, which has been specifically trimmed down to only include functionality needed by simplicity's jets. --- Makefile.am | 1 - 1 file changed, 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index c76e7dd55e..59fb949699 100644 --- a/Makefile.am +++ b/Makefile.am @@ -195,7 +195,6 @@ LCOV_FILTER_PATTERN = \ -p "src/crypto/ctaes" \ -p "src/minisketch" \ -p "src/secp256k1" \ - -p "src/simplicity/secp256k1" \ -p "depends" DIR_FUZZ_SEED_CORPUS ?= qa-assets/fuzz_seed_corpus From a3b7e71a3d8d063b70e05cc0914643433e105fee Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Sun, 26 Jan 2025 15:33:19 +0000 Subject: [PATCH 06/22] transaction: refuse to deserialize TxOuts with null values In Bitcoin Core the notion of a "null" amount (and therefore a "null" txout) is one which cannot be serialized or deserialized. In Core this is implemented using a value of -1. In Elements we use the CT notion of "nullness" which is that the flag on the confidential value is 0. See d53479c9ffff80e889f6072b13e83b13c7a53026 which implemented this. This is reasonable, but because we don't have checks on deserialization, we can deserialize objects that cannot be reserialized. In particular, in coins.h, we deserialize a coin by deserializing its txout. When reserializing we assert that !out.IsNull(). This assertion is hit by the `coins_deserialize` fuzztest. There are a few potential fixes here: * Remove the assertion from coins.h, which is there to catch logic bugs in Core, on the assumption that if they have no bugs then we don't either. This seems like a bad idea. * Change "nullness" for amounts to be an encoding of -1, like in Core. This seems dangerous because we call `GetAmount` all over the place, and if this could return the -1 amount, this will likely blow something up. Probably this is safe for the same reason it is in Core -- that is, we never create null txouts except as sentinel values. But do you wanna bet that this is true now? That it'll always be true? * Same as above, but assert that the amount is not null. This is safer than just blindly hoping that no overflows will occur but still not obviously safe. * Refuse to deserialize null CT objects. This is impossible because we use null nonce values in txouts. * Refuse to deserialize null CT values. Similarly, this is impossible because we use null values in null asset issuances, which are legal. * Refused to deserialize CTxOuts with null values or assets. We are going with the latter solution, because it is narrowly scoped, does not increase the "crash surface" (we throw an exception, and we already throw exceptions for other kinds of invalid serializations), and is very unlikely to cause bugs (null values are invalid on the network anyway; this is the first check in VerifyAmounts) (so are null assets for that matter, which we maybe also should refuse to deserialize). --- src/primitives/confidential.h | 5 +++++ src/primitives/transaction.h | 3 +++ 2 files changed, 8 insertions(+) diff --git a/src/primitives/confidential.h b/src/primitives/confidential.h index a85703cca0..12d72f52c7 100644 --- a/src/primitives/confidential.h +++ b/src/primitives/confidential.h @@ -135,6 +135,11 @@ public: CConfidentialValue() { SetNull(); } CConfidentialValue(CAmount nAmount) { SetToAmount(nAmount); } + template + inline void Unserialize(Stream& s) { + CConfidentialCommitment::Unserialize(s); + } + /* An explicit value is called an amount. The first byte indicates it is * an explicit value, and the remaining 8 bytes is the value serialized as * a 64-bit big-endian integer. */ diff --git a/src/primitives/transaction.h b/src/primitives/transaction.h index 6b7ecaf69f..00f509454b 100644 --- a/src/primitives/transaction.h +++ b/src/primitives/transaction.h @@ -295,6 +295,9 @@ public: s >> nAsset; s >> nValue; s >> nNonce; + if (nAsset.IsNull() || nValue.IsNull()) { + throw std::ios_base::failure("Confidential values may not be null"); + } } else { CAmount value; s >> value; From ff6482fc2918888a22e8ec765fcd44cbd2124725 Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Sun, 26 Jan 2025 16:51:10 +0000 Subject: [PATCH 07/22] fuzz: add SelectParams to rbf.cpp We cannot fuzz RBF (or do anything mempool-related, really) without chainparams. This has been true since 2019 at least. I suspect this fuzz test has never really been run. --- src/test/fuzz/rbf.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/test/fuzz/rbf.cpp b/src/test/fuzz/rbf.cpp index 8dcaa609b5..a3828b51f8 100644 --- a/src/test/fuzz/rbf.cpp +++ b/src/test/fuzz/rbf.cpp @@ -15,7 +15,13 @@ #include #include -FUZZ_TARGET(rbf) +void initialize_rbf(void) { + // ELEMENTS: our mempool needs Params() to be set for multiple reasons -- to check + // the discount CT rate, to figure out pegin policy, etc + SelectParams(CBaseChainParams::LIQUID1); +} + +FUZZ_TARGET_INIT(rbf, initialize_rbf) { FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); SetMockTime(ConsumeTime(fuzzed_data_provider)); From 74cae2d9ec28c2f77b5272c643235f7233cb58f4 Mon Sep 17 00:00:00 2001 From: Pablo Greco Date: Mon, 27 Jan 2025 17:29:44 -0800 Subject: [PATCH 08/22] CI: use default wallet name in wallet_elements_21million --- test/functional/wallet_elements_21million.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/functional/wallet_elements_21million.py b/test/functional/wallet_elements_21million.py index f9faafdbea..ea6b34dd6f 100755 --- a/test/functional/wallet_elements_21million.py +++ b/test/functional/wallet_elements_21million.py @@ -50,8 +50,8 @@ class WalletTest(BitcoinTestFramework): assert_equal(self.nodes[1].getbalance()[asset], 22_000_000) # unload/load wallet - self.nodes[1].unloadwallet("") - self.nodes[1].loadwallet("") + self.nodes[1].unloadwallet(self.default_wallet_name) + self.nodes[1].loadwallet(self.default_wallet_name) assert_equal(self.nodes[1].getbalance()[asset], 22_000_000) # send more than 45 million of that asset @@ -62,8 +62,8 @@ class WalletTest(BitcoinTestFramework): assert_equal(self.nodes[2].getbalance()[asset], 46_000_000) # unload/load wallet - self.nodes[2].unloadwallet("") - self.nodes[2].loadwallet("") + self.nodes[2].unloadwallet(self.default_wallet_name) + self.nodes[2].loadwallet(self.default_wallet_name) assert_equal(self.nodes[2].getbalance()[asset], 46_000_000) # send some policy asset to node 1 for fees @@ -86,8 +86,8 @@ class WalletTest(BitcoinTestFramework): assert_equal(self.nodes[2].getbalance()[asset], 200_000_000) # unload/load wallet - self.nodes[2].unloadwallet("") - self.nodes[2].loadwallet("") + self.nodes[2].unloadwallet(self.default_wallet_name) + self.nodes[2].loadwallet(self.default_wallet_name) assert_equal(self.nodes[2].getbalance()[asset], 200_000_000) if __name__ == '__main__': From 1ecd5821e8154bb2c07d20d2ba81d42b86902dda Mon Sep 17 00:00:00 2001 From: Pablo Greco Date: Mon, 27 Jan 2025 17:29:19 -0800 Subject: [PATCH 09/22] CI: wallet_elements_regression_1263 uses getpeginaddress, disable for descriptor wallets --- test/functional/wallet_elements_regression_1263.py | 1 + 1 file changed, 1 insertion(+) diff --git a/test/functional/wallet_elements_regression_1263.py b/test/functional/wallet_elements_regression_1263.py index c4f713c8e3..2f5ce36ebe 100755 --- a/test/functional/wallet_elements_regression_1263.py +++ b/test/functional/wallet_elements_regression_1263.py @@ -19,6 +19,7 @@ class RegressionTest(BitcoinTestFramework): def skip_test_if_missing_module(self): self.skip_if_no_wallet() + self.skip_if_no_bdb() def run_test(self): self.log.info("Start in Bitcoin regtest mode") From 6991cf7960b55ebd70698a0e1fa82f33a1f6d74b Mon Sep 17 00:00:00 2001 From: Pablo Greco Date: Mon, 27 Jan 2025 17:27:53 -0800 Subject: [PATCH 10/22] CI: trim_headers test uses combineblocksigs, disable for descriptor wallets --- test/functional/feature_trim_headers.py | 1 + 1 file changed, 1 insertion(+) diff --git a/test/functional/feature_trim_headers.py b/test/functional/feature_trim_headers.py index 8d44ee92a9..93926c752f 100755 --- a/test/functional/feature_trim_headers.py +++ b/test/functional/feature_trim_headers.py @@ -39,6 +39,7 @@ def make_signblockscript(num_nodes, required_signers, keys): class TrimHeadersTest(BitcoinTestFramework): def skip_test_if_missing_module(self): self.skip_if_no_wallet() + self.skip_if_no_bdb() # Dynamically generate N keys to be used for block signing. def init_keys(self, num_keys): From e3c318b2b8bd6672756e34d287857b625b28b990 Mon Sep 17 00:00:00 2001 From: Pablo Greco Date: Mon, 27 Jan 2025 17:24:35 -0800 Subject: [PATCH 11/22] CI: discounttests use initialfreecoins, disable for descriptor wallets --- test/functional/feature_discount_ct.py | 1 + test/functional/feature_discount_ct_ordering.py | 1 + 2 files changed, 2 insertions(+) diff --git a/test/functional/feature_discount_ct.py b/test/functional/feature_discount_ct.py index 84e2c096b1..0c949ba27e 100755 --- a/test/functional/feature_discount_ct.py +++ b/test/functional/feature_discount_ct.py @@ -36,6 +36,7 @@ class CTTest(BitcoinTestFramework): def skip_test_if_missing_module(self): self.skip_if_no_wallet() + self.skip_if_no_bdb() def run_test(self): feerate = 1.0 diff --git a/test/functional/feature_discount_ct_ordering.py b/test/functional/feature_discount_ct_ordering.py index aed8a1f0db..2b9e1554e2 100755 --- a/test/functional/feature_discount_ct_ordering.py +++ b/test/functional/feature_discount_ct_ordering.py @@ -33,6 +33,7 @@ class CTTest(BitcoinTestFramework): def skip_test_if_missing_module(self): self.skip_if_no_wallet() + self.skip_if_no_bdb() def run_test(self): From 87808101be489d0fda86706dc8c1ce881e51de85 Mon Sep 17 00:00:00 2001 From: Pablo Greco Date: Mon, 27 Jan 2025 17:25:29 -0800 Subject: [PATCH 12/22] CI: feature_taphash_pegins_issuances test uses initialfreecoins, disable for descriptor wallets --- test/functional/feature_taphash_pegins_issuances.py | 1 + 1 file changed, 1 insertion(+) diff --git a/test/functional/feature_taphash_pegins_issuances.py b/test/functional/feature_taphash_pegins_issuances.py index e4716e8ebc..21ad004948 100755 --- a/test/functional/feature_taphash_pegins_issuances.py +++ b/test/functional/feature_taphash_pegins_issuances.py @@ -41,6 +41,7 @@ class TapHashPeginTest(BitcoinTestFramework): def skip_test_if_missing_module(self): self.skip_if_no_wallet() + self.skip_if_no_bdb() def setup_network(self, split=False): self.setup_nodes() From a33ceacdbca66f466b81e13b05d45e6ed5932cb3 Mon Sep 17 00:00:00 2001 From: Pablo Greco Date: Mon, 27 Jan 2025 17:26:12 -0800 Subject: [PATCH 13/22] CI: feature_tapscript_opcodes test uses initialfreecoins, disable for descriptor wallets --- test/functional/feature_tapscript_opcodes.py | 1 + 1 file changed, 1 insertion(+) diff --git a/test/functional/feature_tapscript_opcodes.py b/test/functional/feature_tapscript_opcodes.py index 8772a08d72..5dbb62bc69 100755 --- a/test/functional/feature_tapscript_opcodes.py +++ b/test/functional/feature_tapscript_opcodes.py @@ -45,6 +45,7 @@ class TapHashPeginTest(BitcoinTestFramework): def skip_test_if_missing_module(self): self.skip_if_no_wallet() + self.skip_if_no_bdb() def setup_network(self, split=False): self.setup_nodes() From e6aa6e773e464eb4e9ebca741dda5c3fc7299bfa Mon Sep 17 00:00:00 2001 From: Pablo Greco Date: Mon, 27 Jan 2025 16:39:17 -0800 Subject: [PATCH 14/22] CI: example_elements_code_tutorial test test uses initialfreecoins, disable for descriptor wallets --- test/functional/example_elements_code_tutorial.py | 1 + 1 file changed, 1 insertion(+) diff --git a/test/functional/example_elements_code_tutorial.py b/test/functional/example_elements_code_tutorial.py index feb645f1f1..138750ec53 100755 --- a/test/functional/example_elements_code_tutorial.py +++ b/test/functional/example_elements_code_tutorial.py @@ -25,6 +25,7 @@ class WalletTest(BitcoinTestFramework): def skip_test_if_missing_module(self): self.skip_if_no_wallet() + self.skip_if_no_bdb() def run_test(self): self.generate(self.nodes[0], COINBASE_MATURITY + 1) From daf8ddc7d28322db8e7ce680cfb8f33d59415acd Mon Sep 17 00:00:00 2001 From: Pablo Greco Date: Mon, 27 Jan 2025 09:47:35 -0800 Subject: [PATCH 15/22] CI: Use RockyLinux 8 instead of CentOS Stream 8 --- .cirrus.yml | 4 ++-- ci/test/00_setup_env_i686_centos.sh | 2 +- ci/test/04_install.sh | 2 +- ci/test/05_before_script.sh | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.cirrus.yml b/.cirrus.yml index 79c10048e3..7bb1029a85 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -186,10 +186,10 @@ task: FILE_ENV: "./ci/test/00_setup_env_win64.sh" task: - name: '32-bit + dash [gui] [CentOS 8]' + name: '32-bit + dash [gui] [Rocky 8]' << : *GLOBAL_TASK_TEMPLATE container: - image: quay.io/centos/centos:stream8 + image: quay.io/rockylinux/rockylinux:8 env: << : *CIRRUS_EPHEMERAL_WORKER_TEMPLATE_ENV PACKAGE_MANAGER_INSTALL: "yum install -y" diff --git a/ci/test/00_setup_env_i686_centos.sh b/ci/test/00_setup_env_i686_centos.sh index 8f1cc8af29..28583c6e63 100755 --- a/ci/test/00_setup_env_i686_centos.sh +++ b/ci/test/00_setup_env_i686_centos.sh @@ -8,7 +8,7 @@ export LC_ALL=C.UTF-8 export HOST=i686-pc-linux-gnu export CONTAINER_NAME=ci_i686_centos -export DOCKER_NAME_TAG=quay.io/centos/centos:stream8 +export DOCKER_NAME_TAG=quay.io/rockylinux/rockylinux:8 export DOCKER_PACKAGES="gcc-c++ glibc-devel.x86_64 libstdc++-devel.x86_64 glibc-devel.i686 libstdc++-devel.i686 ccache libtool make git python3 python3-zmq which patch lbzip2 xz procps-ng dash rsync coreutils bison" export GOAL="install" export BITCOIN_CONFIG="--enable-zmq --with-gui=qt5 --enable-reduce-exports" diff --git a/ci/test/04_install.sh b/ci/test/04_install.sh index 01cb9d1be8..99cf68576c 100755 --- a/ci/test/04_install.sh +++ b/ci/test/04_install.sh @@ -64,7 +64,7 @@ if [ -n "$DPKG_ADD_ARCH" ]; then CI_EXEC dpkg --add-architecture "$DPKG_ADD_ARCH" fi -if [[ $DOCKER_NAME_TAG == *centos* ]]; then +if [[ $DOCKER_NAME_TAG == *centos* ]] || [[ $DOCKER_NAME_TAG == *rocky* ]]; then ${CI_RETRY_EXE} CI_EXEC dnf -y install epel-release ${CI_RETRY_EXE} CI_EXEC dnf -y --allowerasing install "$DOCKER_PACKAGES" "$PACKAGES" elif [ "$CI_USE_APT_INSTALL" != "no" ]; then diff --git a/ci/test/05_before_script.sh b/ci/test/05_before_script.sh index 8f75fbd1fa..b1cb1e300f 100755 --- a/ci/test/05_before_script.sh +++ b/ci/test/05_before_script.sh @@ -44,7 +44,7 @@ if [[ ${USE_MEMORY_SANITIZER} == "true" ]]; then fi if [ -z "$NO_DEPENDS" ]; then - if [[ $DOCKER_NAME_TAG == *centos* ]]; then + if [[ $DOCKER_NAME_TAG == *centos* ]] || [[ $DOCKER_NAME_TAG == *rocky* ]]; then # CentOS has problems building the depends if the config shell is not explicitly set # (i.e. for libevent a Makefile with an empty SHELL variable is generated, leading to # an error as the first command is executed) From 5194a623931a9ad4525c9248f8c0f92c53cf82e6 Mon Sep 17 00:00:00 2001 From: Pablo Greco Date: Sun, 2 Feb 2025 11:03:17 -0800 Subject: [PATCH 16/22] Win64 native: disable psbt_wallet_test just like in Makefile --- build_msvc/test_bitcoin/test_bitcoin.vcxproj | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/build_msvc/test_bitcoin/test_bitcoin.vcxproj b/build_msvc/test_bitcoin/test_bitcoin.vcxproj index 3fa2e16bf1..e53e057e28 100644 --- a/build_msvc/test_bitcoin/test_bitcoin.vcxproj +++ b/build_msvc/test_bitcoin/test_bitcoin.vcxproj @@ -15,7 +15,18 @@ - + + + + + + + + + + + + From 0b40e25bebbdebf09dddc85ab0a3cd76f501abcf Mon Sep 17 00:00:00 2001 From: Pablo Greco Date: Sat, 1 Feb 2025 11:01:04 -0800 Subject: [PATCH 17/22] Win64 native: fix build before simplicity --- .../libbitcoin_wallet.vcxproj.in | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/build_msvc/libbitcoin_wallet/libbitcoin_wallet.vcxproj.in b/build_msvc/libbitcoin_wallet/libbitcoin_wallet.vcxproj.in index 39bb696c78..c425b1b6cb 100644 --- a/build_msvc/libbitcoin_wallet/libbitcoin_wallet.vcxproj.in +++ b/build_msvc/libbitcoin_wallet/libbitcoin_wallet.vcxproj.in @@ -9,22 +9,40 @@ + + + + + + + + + + + + + + + + + + @@ -36,6 +54,9 @@ {bb493552-3b8c-4a8c-bf69-a6e7a51d2ea6} + + {18430fef-6b61-4c53-b396-718e02850f1b} + From d1a9ff34788e28ff6e5239521c28b598b7eb7a46 Mon Sep 17 00:00:00 2001 From: Pablo Greco Date: Fri, 7 Feb 2025 06:38:46 -0800 Subject: [PATCH 18/22] Win64 native: fix build with simplicity --- build_msvc/libbitcoin_wallet/libbitcoin_wallet.vcxproj.in | 3 +++ build_msvc/libbitcoinconsensus/libbitcoinconsensus.vcxproj | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/build_msvc/libbitcoin_wallet/libbitcoin_wallet.vcxproj.in b/build_msvc/libbitcoin_wallet/libbitcoin_wallet.vcxproj.in index c425b1b6cb..14614ebdfa 100644 --- a/build_msvc/libbitcoin_wallet/libbitcoin_wallet.vcxproj.in +++ b/build_msvc/libbitcoin_wallet/libbitcoin_wallet.vcxproj.in @@ -57,6 +57,9 @@ {18430fef-6b61-4c53-b396-718e02850f1b} + + {abae25f0-d700-46e1-9ef6-5d6ddfcf8b26} + diff --git a/build_msvc/libbitcoinconsensus/libbitcoinconsensus.vcxproj b/build_msvc/libbitcoinconsensus/libbitcoinconsensus.vcxproj index 47ba9a75c1..943934ac40 100644 --- a/build_msvc/libbitcoinconsensus/libbitcoinconsensus.vcxproj +++ b/build_msvc/libbitcoinconsensus/libbitcoinconsensus.vcxproj @@ -34,6 +34,11 @@ + + + {abae25f0-d700-46e1-9ef6-5d6ddfcf8b26} + + From cad37df99f20b020b90b626d4ec8f954bdfd58d9 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Thu, 13 Jun 2024 13:25:37 +0000 Subject: [PATCH 19/22] upnp: add compatibility for miniupnpc 2.2.8 See: https://github.com/miniupnp/miniupnp/commit/c0a50ce33e3b99ce8a96fd43049bb5b53ffac62f The return value of 2 now indicates: "A valid connected IGD has been found but its IP address is reserved (non routable)" We continue to ignore any return value other than 1. (cherry picked from commit 8acdf66540834b9f9cf28f16d389e8b6a48516d5) --- src/mapport.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/mapport.cpp b/src/mapport.cpp index 42ca366089..af983a2c5b 100644 --- a/src/mapport.cpp +++ b/src/mapport.cpp @@ -168,8 +168,11 @@ static bool ProcessUpnp() struct UPNPUrls urls; struct IGDdatas data; int r; - +#if MINIUPNPC_API_VERSION <= 17 r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr)); +#else + r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr), nullptr, 0); +#endif if (r == 1) { if (fDiscover) { From 871e9d2ea239293c11169fd13d08add0a294ac3e Mon Sep 17 00:00:00 2001 From: Pablo Greco Date: Fri, 7 Feb 2025 13:33:59 -0800 Subject: [PATCH 20/22] Update boost to 1.81, manually picked from e8b4201ba2fd7745edc26543704d2b4a51dbb151 --- depends/packages/boost.mk | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/depends/packages/boost.mk b/depends/packages/boost.mk index 563848c398..938e9971ba 100644 --- a/depends/packages/boost.mk +++ b/depends/packages/boost.mk @@ -1,8 +1,8 @@ package=boost -$(package)_version=1.77.0 -$(package)_download_path=https://boostorg.jfrog.io/artifactory/main/release/$($(package)_version)/source/ -$(package)_file_name=boost_$(subst .,_,$($(package)_version)).tar.bz2 -$(package)_sha256_hash=fc9f85fc030e233142908241af7a846e60630aa7388de9a5fafb1f3a26840854 +$(package)_version=1.81.0 +$(package)_download_path=https://archives.boost.io/release/$($(package)_version)/source/ +$(package)_file_name=boost_$(subst .,_,$($(package)_version)).tar.gz +$(package)_sha256_hash=205666dea9f6a7cfed87c7a6dfbeb52a2c1b9de55712c9c1a87735d7181452b6 define $(package)_stage_cmds mkdir -p $($(package)_staging_prefix_dir)/include && \ From 7f10cd11c18270f008b74bdc6a9aa42dcaae4f67 Mon Sep 17 00:00:00 2001 From: Pablo Greco Date: Fri, 7 Feb 2025 13:34:50 -0800 Subject: [PATCH 21/22] Update xcb_proto to 1.15.2, manually picked from 7cb88c8b46723d306b96953a6a60c90a4ab211e3 --- depends/packages/xcb_proto.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/depends/packages/xcb_proto.mk b/depends/packages/xcb_proto.mk index 9be822506d..6e1c5a10a8 100644 --- a/depends/packages/xcb_proto.mk +++ b/depends/packages/xcb_proto.mk @@ -1,8 +1,8 @@ package=xcb_proto -$(package)_version=1.14.1 +$(package)_version=1.15.2 $(package)_download_path=https://xorg.freedesktop.org/archive/individual/proto $(package)_file_name=xcb-proto-$($(package)_version).tar.xz -$(package)_sha256_hash=f04add9a972ac334ea11d9d7eb4fc7f8883835da3e4859c9afa971efdf57fcc3 +$(package)_sha256_hash=7072beb1f680a2fe3f9e535b797c146d22528990c72f63ddb49d2f350a3653ed define $(package)_config_cmds $($(package)_autoconf) From 06b72ec82c53c09b39ffb45a408bbd2dfeb0e043 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Tue, 15 Mar 2022 18:49:00 +0100 Subject: [PATCH 22/22] ci: Temporarily use clang-13 to work around clang-14 TSan bug Github-Pull: bitcoin#24572 Rebased-From: fa43933 --- ci/test/00_setup_env_native_tsan.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ci/test/00_setup_env_native_tsan.sh b/ci/test/00_setup_env_native_tsan.sh index 0036255caf..ae942d892b 100755 --- a/ci/test/00_setup_env_native_tsan.sh +++ b/ci/test/00_setup_env_native_tsan.sh @@ -8,7 +8,7 @@ export LC_ALL=C.UTF-8 export CONTAINER_NAME=ci_native_tsan export DOCKER_NAME_TAG=ubuntu:22.04 -export PACKAGES="clang llvm libc++abi-dev libc++-dev python3-zmq" -export DEP_OPTS="CC=clang CXX='clang++ -stdlib=libc++'" +export PACKAGES="clang-13 llvm-13 libc++abi-13-dev libc++-13-dev python3-zmq" +export DEP_OPTS="CC=clang-13 CXX='clang++-13 -stdlib=libc++'" export GOAL="install" -export BITCOIN_CONFIG="--enable-zmq CPPFLAGS='-DARENA_DEBUG -DDEBUG_LOCKORDER' CXXFLAGS='-g' --with-sanitizers=thread CC=clang CXX='clang++ -stdlib=libc++'" +export BITCOIN_CONFIG="--enable-zmq CPPFLAGS='-DARENA_DEBUG -DDEBUG_LOCKORDER' CXXFLAGS='-g' --with-sanitizers=thread CC=clang-13 CXX='clang++-13 -stdlib=libc++'"