Skip to content

Commit 3059d42

Browse files
Add GenPrimitive --bitcoin option
This option builds include files for bitcoin rather than elements.
1 parent 0af901e commit 3059d42

File tree

10 files changed

+4385
-3
lines changed

10 files changed

+4385
-3
lines changed

C/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
CORE_OBJS := bitstream.o dag.o deserialize.o eval.o frame.o jets.o jets-secp256k1.o rsort.o sha256.o type.o typeInference.o
2-
BITCOIN_OBJS := bitcoin/env.o bitcoin/ops.o bitcoin/bitcoinJets.o bitcoin/txEnv.o
2+
BITCOIN_OBJS := bitcoin/env.o bitcoin/ops.o bitcoin/bitcoinJets.o bitcoin/primitive.o bitcoin/txEnv.o
33
ELEMENTS_OBJS := elements/env.o elements/exec.o elements/ops.o elements/elementsJets.o elements/primitive.o elements/cmr.o elements/txEnv.o
44
TEST_OBJS := test.o ctx8Pruned.o ctx8Unpruned.o hashBlock.o regression4.o schnorr0.o schnorr6.o typeSkipTest.o elements/checkSigHashAllTx1.o
55

C/bitcoin/decodeBitcoinJets.inc

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
/* This file has been automatically generated. */
2+
3+
{
4+
int32_t code;
5+
code = simplicity_decodeUptoMaxInt(stream);
6+
if (code < 0) return (simplicity_err)code;
7+
switch (code) {
8+
case 1:
9+
code = simplicity_decodeUptoMaxInt(stream);
10+
if (code < 0) return (simplicity_err)code;
11+
switch (code) {
12+
case 1: *result = SIG_ALL_HASH; return SIMPLICITY_NO_ERROR;
13+
case 2: *result = TX_HASH; return SIMPLICITY_NO_ERROR;
14+
case 3: *result = TAP_ENV_HASH; return SIMPLICITY_NO_ERROR;
15+
case 4: *result = OUTPUTS_HASH; return SIMPLICITY_NO_ERROR;
16+
case 5: *result = INPUTS_HASH; return SIMPLICITY_NO_ERROR;
17+
case 6: *result = INPUT_UTXOS_HASH; return SIMPLICITY_NO_ERROR;
18+
case 7: *result = OUTPUT_HASH; return SIMPLICITY_NO_ERROR;
19+
case 8: *result = OUTPUT_VALUES_HASH; return SIMPLICITY_NO_ERROR;
20+
case 9: *result = OUTPUT_SCRIPTS_HASH; return SIMPLICITY_NO_ERROR;
21+
case 10: *result = INPUT_HASH; return SIMPLICITY_NO_ERROR;
22+
case 11: *result = INPUT_OUTPOINTS_HASH; return SIMPLICITY_NO_ERROR;
23+
case 12: *result = INPUT_SEQUENCES_HASH; return SIMPLICITY_NO_ERROR;
24+
case 13: *result = INPUT_ANNEXES_HASH; return SIMPLICITY_NO_ERROR;
25+
case 14: *result = INPUT_SCRIPT_SIGS_HASH; return SIMPLICITY_NO_ERROR;
26+
case 15: *result = INPUT_UTXO_HASH; return SIMPLICITY_NO_ERROR;
27+
case 16: *result = INPUT_VALUES_HASH; return SIMPLICITY_NO_ERROR;
28+
case 17: *result = INPUT_SCRIPTS_HASH; return SIMPLICITY_NO_ERROR;
29+
case 18: *result = TAPLEAF_HASH; return SIMPLICITY_NO_ERROR;
30+
case 19: *result = TAPPATH_HASH; return SIMPLICITY_NO_ERROR;
31+
case 20: *result = OUTPOINT_HASH; return SIMPLICITY_NO_ERROR;
32+
case 21: *result = ANNEX_HASH; return SIMPLICITY_NO_ERROR;
33+
case 22: *result = BUILD_TAPLEAF_SIMPLICITY; return SIMPLICITY_NO_ERROR;
34+
case 23: *result = BUILD_TAPBRANCH; return SIMPLICITY_NO_ERROR;
35+
case 24: *result = BUILD_TAPTWEAK; return SIMPLICITY_NO_ERROR;
36+
}
37+
break;
38+
case 2:
39+
code = simplicity_decodeUptoMaxInt(stream);
40+
if (code < 0) return (simplicity_err)code;
41+
switch (code) {
42+
case 1: *result = CHECK_LOCK_HEIGHT; return SIMPLICITY_NO_ERROR;
43+
case 2: *result = CHECK_LOCK_TIME; return SIMPLICITY_NO_ERROR;
44+
case 3: *result = CHECK_LOCK_DISTANCE; return SIMPLICITY_NO_ERROR;
45+
case 4: *result = CHECK_LOCK_DURATION; return SIMPLICITY_NO_ERROR;
46+
case 5: *result = TX_LOCK_HEIGHT; return SIMPLICITY_NO_ERROR;
47+
case 6: *result = TX_LOCK_TIME; return SIMPLICITY_NO_ERROR;
48+
case 7: *result = TX_LOCK_DISTANCE; return SIMPLICITY_NO_ERROR;
49+
case 8: *result = TX_LOCK_DURATION; return SIMPLICITY_NO_ERROR;
50+
case 9: *result = TX_IS_FINAL; return SIMPLICITY_NO_ERROR;
51+
}
52+
break;
53+
case 3:
54+
code = simplicity_decodeUptoMaxInt(stream);
55+
if (code < 0) return (simplicity_err)code;
56+
switch (code) {
57+
case 1: *result = SCRIPT_CMR; return SIMPLICITY_NO_ERROR;
58+
case 2: *result = INTERNAL_KEY; return SIMPLICITY_NO_ERROR;
59+
case 3: *result = CURRENT_INDEX; return SIMPLICITY_NO_ERROR;
60+
case 4: *result = NUM_INPUTS; return SIMPLICITY_NO_ERROR;
61+
case 5: *result = NUM_OUTPUTS; return SIMPLICITY_NO_ERROR;
62+
case 6: *result = LOCK_TIME; return SIMPLICITY_NO_ERROR;
63+
case 7: *result = FEE; return SIMPLICITY_NO_ERROR;
64+
case 8: *result = OUTPUT_VALUE; return SIMPLICITY_NO_ERROR;
65+
case 9: *result = OUTPUT_SCRIPT_HASH; return SIMPLICITY_NO_ERROR;
66+
case 10: *result = TOTAL_OUTPUT_VALUE; return SIMPLICITY_NO_ERROR;
67+
case 11: *result = CURRENT_PREV_OUTPOINT; return SIMPLICITY_NO_ERROR;
68+
case 12: *result = CURRENT_VALUE; return SIMPLICITY_NO_ERROR;
69+
case 13: *result = CURRENT_SCRIPT_HASH; return SIMPLICITY_NO_ERROR;
70+
case 14: *result = CURRENT_SEQUENCE; return SIMPLICITY_NO_ERROR;
71+
case 15: *result = CURRENT_ANNEX_HASH; return SIMPLICITY_NO_ERROR;
72+
case 16: *result = CURRENT_SCRIPT_SIG_HASH; return SIMPLICITY_NO_ERROR;
73+
case 17: *result = INPUT_PREV_OUTPOINT; return SIMPLICITY_NO_ERROR;
74+
case 18: *result = INPUT_VALUE; return SIMPLICITY_NO_ERROR;
75+
case 19: *result = INPUT_SCRIPT_HASH; return SIMPLICITY_NO_ERROR;
76+
case 20: *result = INPUT_SEQUENCE; return SIMPLICITY_NO_ERROR;
77+
case 21: *result = INPUT_ANNEX_HASH; return SIMPLICITY_NO_ERROR;
78+
case 22: *result = INPUT_SCRIPT_SIG_HASH; return SIMPLICITY_NO_ERROR;
79+
case 23: *result = TOTAL_INPUT_VALUE; return SIMPLICITY_NO_ERROR;
80+
case 24: *result = TAPLEAF_VERSION; return SIMPLICITY_NO_ERROR;
81+
case 25: *result = TAPPATH; return SIMPLICITY_NO_ERROR;
82+
case 26: *result = VERSION; return SIMPLICITY_NO_ERROR;
83+
case 27: *result = TRANSACTION_ID; return SIMPLICITY_NO_ERROR;
84+
}
85+
break;
86+
}
87+
}

C/bitcoin/primitive.c

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
/* This module implements the 'primitive.h' interface for the Bitcoin application of Simplicity.
2+
*/
3+
#include "primitive.h"
4+
5+
#include "bitcoinJets.h"
6+
#include "../limitations.h"
7+
#include "../simplicity_alloc.h"
8+
#include "../simplicity_assert.h"
9+
10+
/* An enumeration of all the types we need to construct to specify the input and output types of all jets created by 'decodeJet'. */
11+
enum TypeNamesForJets {
12+
#include "primitiveEnumTy.inc"
13+
NumberOfTypeNames
14+
};
15+
16+
/* Allocate a fresh set of unification variables bound to at least all the types necessary
17+
* for all the jets that can be created by 'decodeJet', and also the type 'TWO^256',
18+
* and also allocate space for 'extra_var_len' many unification variables.
19+
* Return the number of non-trivial bindings created.
20+
*
21+
* However, if malloc fails, then return 0.
22+
*
23+
* Precondition: NULL != bound_var;
24+
* NULL != word256_ix;
25+
* NULL != extra_var_start;
26+
* extra_var_len <= 6*DAG_LEN_MAX;
27+
*
28+
* Postcondition: Either '*bound_var == NULL' and the function returns 0
29+
* or 'unification_var (*bound_var)[*extra_var_start + extra_var_len]' is an array of unification variables
30+
* such that for any 'jet : A |- B' there is some 'i < *extra_var_start' and 'j < *extra_var_start' such that
31+
* '(*bound_var)[i]' is bound to 'A' and '(*bound_var)[j]' is bound to 'B'
32+
* and, '*word256_ix < *extra_var_start' and '(*bound_var)[*word256_ix]' is bound the type 'TWO^256'
33+
*/
34+
size_t simplicity_bitcoin_mallocBoundVars(unification_var** bound_var, size_t* word256_ix, size_t* extra_var_start, size_t extra_var_len) {
35+
static_assert(1 <= NumberOfTypeNames, "Missing TypeNamesForJets.");
36+
static_assert(NumberOfTypeNames <= NUMBER_OF_TYPENAMES_MAX, "Too many TypeNamesForJets.");
37+
static_assert(DAG_LEN_MAX <= (SIZE_MAX - NumberOfTypeNames) / 6, "NumberOfTypeNames + 6*DAG_LEN_MAX doesn't fit in size_t");
38+
static_assert(NumberOfTypeNames + 6*DAG_LEN_MAX <= SIZE_MAX/sizeof(unification_var) , "bound_var array too large");
39+
static_assert(NumberOfTypeNames + 6*DAG_LEN_MAX - 1 <= UINT32_MAX, "bound_var array index doesn't fit in uint32_t");
40+
simplicity_assert(extra_var_len <= 6*DAG_LEN_MAX);
41+
*bound_var = simplicity_malloc((NumberOfTypeNames + extra_var_len) * sizeof(unification_var));
42+
if (!(*bound_var)) return 0;
43+
#include "primitiveInitTy.inc"
44+
*word256_ix = ty_w256;
45+
*extra_var_start = NumberOfTypeNames;
46+
47+
/* 'ty_u' is a trivial binding, so we made 'NumberOfTypeNames - 1' non-trivial bindings. */
48+
return NumberOfTypeNames - 1;
49+
};
50+
51+
/* An enumeration of the names of Bitcoin specific jets and primitives. */
52+
typedef enum jetName
53+
{
54+
#include "primitiveEnumJet.inc"
55+
NUMBER_OF_JET_NAMES
56+
} jetName;
57+
58+
/* Decode an Bitcoin specific jet name from 'stream' into 'result'.
59+
* All jets begin with a bit prefix of '1' which needs to have already been consumed from the 'stream'.
60+
* Returns 'SIMPLICITY_ERR_DATA_OUT_OF_RANGE' if the stream's prefix doesn't match any valid code for a jet.
61+
* Returns 'SIMPLICITY_ERR_BITSTRING_EOF' if not enough bits are available in the 'stream'.
62+
* In the above error cases, 'result' may be modified.
63+
* Returns 'SIMPLICITY_NO_ERROR' if successful.
64+
*
65+
* Precondition: NULL != result
66+
* NULL != stream
67+
*/
68+
static simplicity_err decodePrimitive(jetName* result, bitstream* stream) {
69+
int32_t bit = read1Bit(stream);
70+
if (bit < 0) return (simplicity_err)bit;
71+
if (!bit) {
72+
/* Core jets */
73+
#include "../decodeCoreJets.inc"
74+
return SIMPLICITY_ERR_DATA_OUT_OF_RANGE;
75+
} else {
76+
/* Bitcoin jets */
77+
#include "decodeBitcoinJets.inc"
78+
return SIMPLICITY_ERR_DATA_OUT_OF_RANGE;
79+
}
80+
}
81+
82+
/* Return a copy of the Simplicity node corresponding to the given Bitcoin specific jet 'name'. */
83+
static dag_node jetNode(jetName name) {
84+
static const dag_node jet_node[] = {
85+
#include "primitiveJetNode.inc"
86+
};
87+
88+
return jet_node[name];
89+
}
90+
91+
/* Decode a Bitcoin specific jet from 'stream' into 'node'.
92+
* All jets begin with a bit prefix of '1' which needs to have already been consumed from the 'stream'.
93+
* Returns 'SIMPLICITY_ERR_DATA_OUT_OF_RANGE' if the stream's prefix doesn't match any valid code for a jet.
94+
* Returns 'SIMPLICITY_ERR_BITSTRING_EOF' if not enough bits are available in the 'stream'.
95+
* In the above error cases, 'dag' may be modified.
96+
* Returns 'SIMPLICITY_NO_ERR' if successful.
97+
*
98+
* Precondition: NULL != node
99+
* NULL != stream
100+
*/
101+
simplicity_err simplicity_bitcoin_decodeJet(dag_node* node, bitstream* stream) {
102+
jetName name;
103+
simplicity_err error = decodePrimitive(&name, stream);
104+
if (!IS_OK(error)) return error;
105+
*node = jetNode(name);
106+
return SIMPLICITY_NO_ERROR;
107+
}

C/bitcoin/primitive.h

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/* Implements the primitive.h interface for the Bitcoin Simplicity application.
2+
*/
3+
#ifndef SIMPLICITY_BITCOIN_PRIMITIVE_H
4+
#define SIMPLICITY_BITCOIN_PRIMITIVE_H
5+
6+
#include "../bitstream.h"
7+
#include "../typeInference.h"
8+
#include "txEnv.h"
9+
10+
/* Allocate a fresh set of unification variables bound to at least all the types necessary
11+
* for all the jets that can be created by 'decodeJet', and also the type 'TWO^256',
12+
* and also allocate space for 'extra_var_len' many unification variables.
13+
* Return the number of non-trivial bindings created.
14+
*
15+
* However, if malloc fails, then return 0.
16+
*
17+
* Precondition: NULL != bound_var;
18+
* NULL != word256_ix;
19+
* NULL != extra_var_start;
20+
* extra_var_len <= 6*DAG_LEN_MAX;
21+
*
22+
* Postcondition: Either '*bound_var == NULL' and the function returns 0
23+
* or 'unification_var (*bound_var)[*extra_var_start + extra_var_len]' is an array of unification variables
24+
* such that for any 'jet : A |- B' there is some 'i < *extra_var_start' and 'j < *extra_var_start' such that
25+
* '(*bound_var)[i]' is bound to 'A' and '(*bound_var)[j]' is bound to 'B'
26+
* and, '*word256_ix < *extra_var_start' and '(*bound_var)[*word256_ix]' is bound the type 'TWO^256'
27+
*/
28+
size_t simplicity_bitcoin_mallocBoundVars(unification_var** bound_var, size_t* word256_ix, size_t* extra_var_start, size_t extra_var_len);
29+
30+
/* Decode a Bitcoin specific jet from 'stream' into 'node'.
31+
* All jets begin with a bit prefix of '1' which needs to have already been consumed from the 'stream'.
32+
* Returns 'SIMPLICITY_ERR_DATA_OUT_OF_RANGE' if the stream's prefix doesn't match any valid code for a jet.
33+
* Returns 'SIMPLICITY_ERR_BITSTRING_EOF' if not enough bits are available in the 'stream'.
34+
* In the above error cases, 'dag' may be modified.
35+
* Returns 'SIMPLICITY_NO_ERROR' if successful.
36+
*
37+
* Precondition: NULL != node
38+
* NULL != stream
39+
*/
40+
simplicity_err simplicity_bitcoin_decodeJet(dag_node* node, bitstream* stream);
41+
42+
#endif

0 commit comments

Comments
 (0)