<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE article PUBLIC "-//NLM//DTD Journal Publishing DTD v2.3 20070202//EN" "journalpublishing.dtd">
<article article-type="research-article" dtd-version="2.3" xml:lang="EN" xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:xlink="http://www.w3.org/1999/xlink">
<front>
<journal-meta>
<journal-id journal-id-type="publisher-id">Front. Blockchain</journal-id>
<journal-title>Frontiers in Blockchain</journal-title>
<abbrev-journal-title abbrev-type="pubmed">Front. Blockchain</abbrev-journal-title>
<issn pub-type="epub">2624-7852</issn>
<publisher>
<publisher-name>Frontiers Media S.A.</publisher-name>
</publisher>
</journal-meta>
<article-meta>
<article-id pub-id-type="publisher-id">770503</article-id>
<article-id pub-id-type="doi">10.3389/fbloc.2021.770503</article-id>
<article-categories>
<subj-group subj-group-type="heading">
<subject>Blockchain</subject>
<subj-group>
<subject>Original Research</subject>
</subj-group>
</subj-group>
</article-categories>
<title-group>
<article-title>Is it Possible to Verify if a Transaction is Spendable?</article-title>
<alt-title alt-title-type="left-running-head">Arenas et&#x20;al.</alt-title>
<alt-title alt-title-type="right-running-head">Is a Transaction Spendable?</alt-title>
</title-group>
<contrib-group>
<contrib contrib-type="author" corresp="yes">
<name>
<surname>Arenas</surname>
<given-names>Marcelo</given-names>
</name>
<xref ref-type="aff" rid="aff1">
<sup>1</sup>
</xref>
<xref ref-type="aff" rid="aff2">
<sup>2</sup>
</xref>
<xref ref-type="aff" rid="aff3">
<sup>3</sup>
</xref>
<xref ref-type="corresp" rid="c001">&#x2a;</xref>
<uri xlink:href="https://loop.frontiersin.org/people/1465408/overview"/>
</contrib>
<contrib contrib-type="author">
<name>
<surname>Reisenegger</surname>
<given-names>Thomas</given-names>
</name>
<xref ref-type="aff" rid="aff1">
<sup>1</sup>
</xref>
<xref ref-type="aff" rid="aff3">
<sup>3</sup>
</xref>
</contrib>
<contrib contrib-type="author">
<name>
<surname>Reutter</surname>
<given-names>Juan</given-names>
</name>
<xref ref-type="aff" rid="aff1">
<sup>1</sup>
</xref>
<xref ref-type="aff" rid="aff2">
<sup>2</sup>
</xref>
<xref ref-type="aff" rid="aff3">
<sup>3</sup>
</xref>
<uri xlink:href="https://loop.frontiersin.org/people/1498510/overview"/>
</contrib>
<contrib contrib-type="author">
<name>
<surname>Vrgo&#x10d;</surname>
<given-names>Domagoj</given-names>
</name>
<xref ref-type="aff" rid="aff1">
<sup>1</sup>
</xref>
<xref ref-type="aff" rid="aff2">
<sup>2</sup>
</xref>
<xref ref-type="aff" rid="aff3">
<sup>3</sup>
</xref>
</contrib>
</contrib-group>
<aff id="aff1">
<label>
<sup>1</sup>
</label>Department of Computer Science, Universidad Catolica de Chile, <addr-line>Santiago</addr-line>, <country>Chile</country>
</aff>
<aff id="aff2">
<label>
<sup>2</sup>
</label>Institute for Mathematical and Computational Engineering, Universidad Catolica de Chile, <addr-line>Santiago</addr-line>, <country>Chile</country>
</aff>
<aff id="aff3">
<label>
<sup>3</sup>
</label>IMFD Chile, <addr-line>Santiago</addr-line>, <country>Chile</country>
</aff>
<author-notes>
<fn fn-type="edited-by">
<p>
<bold>Edited by:</bold> <ext-link ext-link-type="uri" xlink:href="https://loop.frontiersin.org/people/254972/overview">Cosimo Laneve</ext-link>, University of Bologna, Italy</p>
</fn>
<fn fn-type="edited-by">
<p>
<bold>Reviewed by:</bold> <ext-link ext-link-type="uri" xlink:href="https://loop.frontiersin.org/people/574226/overview">Roberto Zunino</ext-link>, University of Trento, Italy</p>
<p>
<ext-link ext-link-type="uri" xlink:href="https://loop.frontiersin.org/people/580326/overview">Francesco Tiezzi</ext-link>, University of Camerino, Italy</p>
</fn>
<corresp id="c001">&#x2a;Correspondence: Marcelo Arenas, <email>marenas@ing.puc.cl</email>
</corresp>
<fn fn-type="other">
<p>This article was submitted to Smart Contracts, a section of the journal Frontiers in Blockchain</p>
</fn>
</author-notes>
<pub-date pub-type="epub">
<day>14</day>
<month>12</month>
<year>2021</year>
</pub-date>
<pub-date pub-type="collection">
<year>2021</year>
</pub-date>
<volume>4</volume>
<elocation-id>770503</elocation-id>
<history>
<date date-type="received">
<day>03</day>
<month>09</month>
<year>2021</year>
</date>
<date date-type="accepted">
<day>15</day>
<month>10</month>
<year>2021</year>
</date>
</history>
<permissions>
<copyright-statement>Copyright &#xa9; 2021 Arenas, Reisenegger, Reutter and Vrgo&#x10d;.</copyright-statement>
<copyright-year>2021</copyright-year>
<copyright-holder>Arenas, Reisenegger, Reutter and Vrgo&#x10d;</copyright-holder>
<license xlink:href="http://creativecommons.org/licenses/by/4.0/">
<p>This is an open-access article distributed under the terms of the Creative Commons Attribution License (CC BY). The use, distribution or reproduction in other forums is permitted, provided the original author(s) and the copyright owner(s) are credited and that the original publication in this journal is cited, in accordance with accepted academic practice. No use, distribution or reproduction is permitted which does not comply with these&#x20;terms.</p>
</license>
</permissions>
<abstract>
<p>With the popularity of Bitcoin, there is a growing need to understand the functionality, security, and performance of various mechanisms that comprise it. In this paper, we analyze Bitcoin&#x2019;s scripting language, Script, that is one of the main building blocks of Bitcoin transactions. We formally define the semantics of Script, and study the problem of determining whether a user-defined script is well-formed; that is, whether it can be unlocked, or whether it contains errors that would prevent this from happening.</p>
</abstract>
<kwd-group>
<kwd>bitcoin</kwd>
<kwd>script</kwd>
<kwd>static analysis</kwd>
<kwd>unlockability</kwd>
<kwd>script transaction</kwd>
</kwd-group>
<contract-sponsor id="cn001">Fondo Nacional de Desarrollo Cient&#xed;fico y Tecnol&#xf3;gico<named-content content-type="fundref-id">10.13039/501100002850</named-content>
</contract-sponsor>
</article-meta>
</front>
<body>
<sec id="s1">
<title>1 Introduction</title>
<p>Bitcoin (<xref ref-type="bibr" rid="B16">Nakamoto, 2008</xref>; <xref ref-type="bibr" rid="B10">Bonneau et&#x20;al., 2015</xref>; <xref ref-type="bibr" rid="B17">Narayanan et&#x20;al., 2016</xref>; <xref ref-type="bibr" rid="B2">Antonopoulos, 2017</xref>) is a decentralized cryptocurrency protocol proposed in 2008 by a person or a group of people under the pseudonym Satoshi Nakamoto. As a currency, Bitcoin allows for transactions between users, and can be used for instance as a way of transferring money between individuals in a secure way, and without depending on any bank or centralized institution. But there are several other advantages of using Bitcoin to transfer currency. The subject of this article is a feature called &#x201c;smart contracts&#x201d;, which, in Bitcoin, work by specifying certain requirements that must be satisfied by transactions before this money can be spent<xref ref-type="fn" rid="FN1">
<sup>1</sup>
</xref>. These contracts are issued using <italic>Script</italic>, a language specifically designed for this task, and that is integrated into the Bitcoin protocol.</p>
<p>The Bitcoin protocol and its Script language permit the design of different forms of smart contracts, and currently we have a variety of pre-designed contracts, and several formal models to understand the correctness of contracts, their semantics or their power [see e.g. (<xref ref-type="bibr" rid="B8">Bartoletti and Zunino, 2019</xref>)]. However, there are still lower-level complexity questions that remain unanswered about Script. In this paper, we focus on the complexity of processing scripts, and, more importantly, of verifying whether a smart contract is <italic>valid</italic>, in the sense that the requirements posed by the contract are actually possible to satisfy. In order to dig deeper on Bitcoin&#x2019;s smart contracts, we start by pointing out some of the differences that exist between a common bank transaction and a Bitcoin transaction.</p>
<p>First, there is no concept of account in the Bitcoin protocol. Assume that person <italic>A</italic> wants to transfer <italic>X</italic> amount of money to person <italic>B</italic>. <italic>A</italic> does not have an account with a balance that determines how much money he/she can transfer. Instead, <italic>A</italic> must point to one or more transactions of which he/she is the recipient, and whose sum must be at least <italic>X</italic>. Clearly, the system must address the problem of determining which transaction outputs have been spent and which have not. In the case of Bitcoin, instead of inspecting the whole ledger to determine whether a certain transaction output has been spent, the nodes in the network keep a record of all of the unspent transaction outputs (UTXOs).</p>
<p>The second main difference between bank and Bitcoin transactions is that the Bitcoin protocol was designed to allow for more complex spending requirements. In other words, instead of just indicating a recipient for a transaction, the sender states certain requirements that need to be met by the recipient in order to spend the transferred money. For example, one could wish to forbid the money from being spent before a certain date, or to require multiple people to agree to spend the money. The tool that is used to establish these requirements is Script, which is a non-Turing-complete scripting language designed specifically for this purpose (<xref ref-type="bibr" rid="B18">O&#x2019;Connor, 2017</xref>; <xref ref-type="bibr" rid="B15">Klomp and Bracciali, 2018</xref>; <xref ref-type="bibr" rid="B14">Jansen et&#x20;al., 2019</xref>).</p>
<p>Script was designed to disallow infinite loops from being created, so that the nodes in the network could not be tricked into executing a never-ending program. However, the requirements that can be represented through it can be complex, and this is why these requirements can be understood as smart contracts.</p>
<p>In practice, the protocol for spending requirements associates each transaction output with a locking script, which corresponds to a sequence of Script operators. Afterwards, when creating a new transaction, in addition to pointing to an unspent transaction output, the sender must provide an unlocking script that fulfills the requirements established through the locking script associated with such an output. Specifically, to determine if the unlocking script is valid, the nodes that receive these transactions append the locking script to the unlocking script, execute the resulting construction and determine whether the execution is successful. An execution is considered successful if it does not raise any errors and results in a structure that represents the Boolean value&#x20;<italic>true</italic>.</p>
<p>Script provides enough freedom to easily create a locking script for which there does not exist any valid unlocking script. This can be done on purpose, and there is even a specific operator <italic>OP</italic>_<italic>RETURN</italic> that automatically flags the locking script as invalid. In practice, this is used to store information in the blockchain, so that there is a verifiable proof that said information was available to the sender on a certain date. However, locking scripts that cannot be unlocked can also be created by mistake.</p>
<p>This causes problems at the individual and collective level. On the one hand, a person simply loses money if he/she creates a transaction with a locking script that cannot be unlocked. In fact, there is no possible way of accessing funds that have been locked in this manner. On the other hand, these unspent transactions are accumulated in the pool of UTXOs, occupying memory and resources on all the nodes that have received it. Given that these outputs cannot be spent, the resources used to manage them cannot be&#x20;freed.</p>
<p>Our goal is to understand the complexity of determining whether the output of a transaction is spendable or not, by looking at how its associated locking script is constructed. As a first necessary contribution for tackling this goal, we propose a simple and direct formalization of a fragment of Script, which provides a suitable setting to define and study the aforementioned unlockability problem. We use our formalization to prove that there is no efficient algorithm for detecting unspendable transaction outputs in the considered fragment of Script (unless Ptime &#x3d; NP), which immediately implies that no such an algorithm can exists for the entire language. Interestingly, we also use our formalization to provide a mathematical proof for the folklore fact that processing a script is in Ptime.</p>
<p>Our formalization of Script is similar to the one presented in (<xref ref-type="bibr" rid="B15">Klomp and Bracciali, 2018</xref>); in particular, they are both based on a notion of configuration, or state, that is updated when a Script operator is executed. A state is defined in (<xref ref-type="bibr" rid="B15">Klomp and Bracciali, 2018</xref>) as a single main stack together with some extra components like pointers to the head and bottom elements of the stack, and the semantics of Script is defined by a set of structural operation semantics rules. On the other hand, the notion of configuration in our formalization consists of the main and alternate stacks used in Script, and a control stack needed to define <italic>if</italic> statements. We diverted from the definition in (<xref ref-type="bibr" rid="B15">Klomp and Bracciali, 2018</xref>) to have a more appropriate formalization to study the unlockability problem, which also includes the alternate stack of Script. A comprehensive description of different formalizations and extensions of Script can be found in (<xref ref-type="bibr" rid="B7">Bartoletti and Zunino, 2018</xref>). These works have focused on proposing executable semantics of Script, and some extensions of it, and on enabling the formal verification of some properties of protocols defined in this language (<xref ref-type="bibr" rid="B1">Andrychowicz et&#x20;al., 2014</xref>; <xref ref-type="bibr" rid="B18">O&#x2019;Connor, 2017</xref>; <xref ref-type="bibr" rid="B6">Atzei et&#x20;al., 2018b</xref>; <xref ref-type="bibr" rid="B5">Atzei et&#x20;al., 2018a</xref>; <xref ref-type="bibr" rid="B8">Bartoletti and Zunino, 2019</xref>; <xref ref-type="bibr" rid="B19">Singh et&#x20;al., 2020</xref>). In this sense, our definition of Script follows a different direction, guided by the need to study the unlockability problem, which, to the best of our knowledge, has not been considered in previous&#x20;works.</p>
</sec>
<sec id="s2">
<title>2 How Script Works</title>
<p>Transactions are at the core of Bitcoin. Simply put, they specify which coins are spent and to whom they are transferred. On a technological level, each Bitcoin transaction can have multiple inputs, each of which is an output of a previous transaction. Conceptually, for a transaction to be accepted, each input that is used requires a digital signature that corresponds to the public key specified by the transaction where this input was generated<xref ref-type="fn" rid="FN2">
<sup>2</sup>
</xref>. We depict this dependence graphically in <xref ref-type="fig" rid="F1">Figure&#x20;1</xref>. Besides, the list of all transactions (grouped into blocks) is kept by a peer-to-peer network &#x201c;running&#x201d; Bitcoin, so that we are able to check if the transaction inputs have already been spent. The only transactions that differ from this template are the coinbase transactions in which new &#x201c;coins&#x201d; are minted, and that have no inputs. These appear once per block, and only specify who can spend the newly created &#x201c;coins&#x201d;.</p>
<fig id="F1" position="float">
<label>FIGURE 1</label>
<caption>
<p>The input to one transaction is the output of a previous transaction. Here Bob confirms with his digital signature that he is the owner of the private key corresponding to the public key used when specifying the recipient of the funds in the previous transaction. Transactions reference each other <italic>via</italic> their hash (i.e. 0xffaa in this case).</p>
</caption>
<graphic xlink:href="fbloc-04-770503-g001.tif"/>
</fig>
<p>In reality, the process of signing a transaction input is more complicated and depends on Bitcoin&#x2019;s scripting language, Script. More precisely, each transaction output specifies a part of a script written in this language, called the locking script. In order to spend this output, the transaction using it as an input must provide another sequence of Script commands, called the unlocking script, such that the script obtained by concatenating the two executes correctly. Given that stack-based languages operate &#x201c;in-reverse&#x201d;, the two scripts are also concatenated in this order, namely, the locking script is appended to the unlocking script spending it. We depict this process graphically in <xref ref-type="fig" rid="F2">Figure&#x20;2</xref>.</p>
<fig id="F2" position="float">
<label>FIGURE 2</label>
<caption>
<p>Interaction between the locking and unlocking scripts.</p>
</caption>
<graphic xlink:href="fbloc-04-770503-g002.tif"/>
</fig>
<p>When Script was conceived, the process of executing the combination of both scripts was done by literally concatenating them together, and then executing the resulting script. However, for safety concerns this procedure has been modified, so that the execution of the concatenation is performed by first executing the unlocking script while checking that it was properly constructed, and then executing the locking script with the final state of the execution of the unlocking script as its initial state (<xref ref-type="bibr" rid="B13">Github, 2010</xref>). This distinction is irrelevant in the analysis of the most commonly used locking scripts. However, it will become important in the later sections of this document, when laying out proofs about the inner workings of Script.</p>
<p>Script (<xref ref-type="bibr" rid="B9">Bitcoin Wiki, 2021</xref>) is a simple stack-based language which allows to push elements to a stack, and manipulate its content using basic arithmetic, logical operations, if-else statements, and cryptographic primitives such as hashing and signature verification. Script is designed to be loop-free and is, therefore, not Turing-complete (<xref ref-type="bibr" rid="B18">O&#x2019;Connor, 2017</xref>), which allows it to be more secure, and to be implemented efficiently. In spite of this, Script still allows to express an array of complicated conditions, giving rise to what is known as &#x201c;smart contracts&#x201d;, which are nothing more than non trivial Script programs that specify how an output of a previous transaction can be unlocked. In what follows, we briefly recap the main commands of Script, and explain the problems we study in this setting.</p>
<p>Script evaluation relies on a stack in order to store some elements, perform simple operations on them, and later compare them for equality. Instructions of Script can be grouped as follows:<list list-type="simple">
<list-item>
<p>&#x2022; Data (256 bit numbers), which are pushed onto the stack when encountered.</p>
</list-item>
<list-item>
<p>&#x2022; Stack operations (push, pop, &#x2026;).</p>
</list-item>
<list-item>
<p>&#x2022; Logical operations (and, or, &#x2026;).</p>
</list-item>
<list-item>
<p>&#x2022; Arithmetical operations on numbers.</p>
</list-item>
<list-item>
<p>&#x2022; Cryptographic primitives (hashing and signature verification).</p>
</list-item>
</list>
</p>
<p>We show how basic Script commands work, by illustrating how a basic transaction to transfer funds from one address to another works. This is called pay to public-key hash (or P2PKH for short) script, and is one of the simplest scripts that can be expressed.<xref ref-type="fn" rid="FN3">
<sup>3</sup>
</xref> As stated previously, each input to a transaction has an associated locking script. In the case of P2PKH, this locking script is as follows:</p>
<p>
<sans-serif>OP</sans-serif>_<sans-serif>DUP</sans-serif> <sans-serif>OP</sans-serif>_<sans-serif>HASH160</sans-serif> <sans-serif>pubKeyData</sans-serif> <sans-serif>OP</sans-serif>_<sans-serif>EQUALVERIFY</sans-serif> <sans-serif>OP</sans-serif>_<sans-serif>CHECKSIG</sans-serif>.</p>
<p>To unlock this output, we need to provide a set of Script commands, which, when executed prior to executing the locking script, result in a stack with a nonzero element at the top. A correct unlocking script in this case would&#x20;be</p>
<p>
<sans-serif>signature</sans-serif> <sans-serif>pubKeyData</sans-serif>.</p>
<p>Intuitively, the unlocking script provides us the signature <sans-serif>signature</sans-serif> and the public key <sans-serif>pubKeyData</sans-serif> corresponding to this signature, and then the locking script checks its validity. Namely, the locking script duplicates the top item on the stack (<italic>via</italic> <sans-serif>OP</sans-serif>_<sans-serif>DUP</sans-serif>), hashes this element (with a combination of ripeMD160 and SHA-256 hash functions), pushes an item onto the stack, pushes the public key data onto the stack, checks that the provided public key and the one specified in the script match, and finally verifies the signature.</p>
<p>This example already shows how locking scripts can specify complex conditions. While it is easy to construct the unlocking script for the locking script above, provided we have the required private key needed to produce the signature, this is not necessarily always the case. For instance, the locking script.</p>
<p>
<sans-serif>OP</sans-serif>_<sans-serif>DUP</sans-serif> <sans-serif>OP</sans-serif>_<sans-serif>ADD</sans-serif> 7&#x20;<sans-serif>OP</sans-serif>_<sans-serif>EQUALVERIFY</sans-serif>
</p>
<p>can never be unlocked since it is asking for an integer number <italic>n</italic> such that 2<italic>n</italic>&#x20;&#x3d; 7. This can of course be very problematic if funds are locked behind such a locking script. A good Bitcoin wallet should try to prohibit such transactions, or at least try to warn the user that his/her output will become unspendable due to the locking script condition. This is known as the unlockability problem, and it is the main subject of study of this paper. More precisely, we provide a formalization of a fragment of the language Script in <xref ref-type="sec" rid="s3">Section 3</xref>. Then we use this formalization in <xref ref-type="sec" rid="s4">Section 4</xref> to provide a definition of the unlockability problem, and to prove that this problem is NP-hard. Finally, a discussion of the consequences of this intractability result are given in <xref ref-type="sec" rid="s5">Section&#x20;5</xref>.</p>
</sec>
<sec id="s3">
<title>3 Formalizing Script</title>
<p>In this section, we develop a formalization for Script that allows us to study the computational complexity of some problems related to the evaluation or unlocking of scripts. Besides, this formalization enables us to fix the notation used throughout the paper. Given that Script is a stack-based language, we begin with a formal definition of the stacks that are used by this language. We then focus on the operators of Script, defining their semantics in terms of stack operations.</p>
<sec id="s3-1">
<title>3.1 The Stacks in Script</title>
<p>For an arbitrary nonempty set <italic>M</italic>, we denote the concatenation of two elements <italic>A</italic>, <italic>B</italic>&#x20;&#x2208; <italic>M</italic> as <italic>A</italic>&#x20;&#x22c5; <italic>B</italic>, and naturally extend this notion to any finite number of elements. By <italic>M</italic>&#x2217; we denote all finite concatenations of elements of <italic>M</italic>, including the empty string <italic>&#x25b;</italic>, and with <italic>M</italic>
<sup>&#x2b;</sup> we denote <italic>M</italic>&#x2217; without <italic>&#x25b;</italic>. A stack over <italic>M</italic> is any element <italic>A</italic>
<sub>0</sub> &#x22c5; <italic>A</italic>
<sub>1</sub>&#x22ef;<italic>A</italic>
<sub>
<italic>k</italic>
</sub> &#x2208; <italic>M</italic>&#x2217;. Intuitively, this string over <italic>M</italic> represents a stack containing <italic>A</italic>
<sub>0</sub> as the top element, <italic>A</italic>
<sub>1</sub> as the element below the top one, etc. Notice that we allow the empty stack, which is denoted by the empty string <italic>&#x25b;</italic>.</p>
<p>Script has two stacks at its disposal: the main stack, denoted by <italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>, and an alternate stack, denoted by <italic>&#x3c6;</italic>
<sub>
<italic>A</italic>
</sub>, that can be accessed by a few of the operators. Hence, the stacks of Script shall be denoted as the pair (<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>, <italic>&#x3c6;</italic>
<sub>
<italic>A</italic>
</sub>). To manipulate these stacks, we use functions <italic>top</italic> and <italic>tail</italic>, defined as follows: <italic>top</italic>: <italic>M</italic>
<sup>&#x2b;</sup> &#x2192; <italic>M</italic> is used to return the top of the stack, that is <italic>top</italic>(<italic>A</italic>
<sub>0</sub>&#x22c5;<italic>A</italic>
<sub>1</sub>&#x22c5;&#x2026;&#x22c5;<italic>A</italic>
<sub>
<italic>k</italic>
</sub>) &#x3d; <italic>A</italic>
<sub>0</sub>, while <italic>tail</italic>: <italic>M</italic>
<sup>&#x2b;</sup> &#x2192; <italic>M</italic>&#x2217; is used to return the stack below the first element, that is, <italic>tail</italic>(<italic>A</italic>
<sub>0</sub>&#x22c5;<italic>A</italic>
<sub>1</sub>&#x22c5;&#x2026;&#x22c5;<italic>A</italic>
<sub>
<italic>k</italic>
</sub>) &#x3d; <italic>A</italic>
<sub>1</sub>&#x22c5;&#x2026;&#x22c5;<italic>A</italic>
<sub>
<italic>k</italic>
</sub>. Notice that the result of <italic>tail</italic> can be the empty stack <italic>&#x25b;</italic>.</p>
</sec>
<sec id="s3-2">
<title>3.2 Script Operators</title>
<p>For simplicity, we assume that data items in Script come from the set <inline-formula id="inf1">
<mml:math id="m1">
<mml:mi mathvariant="double-struck">Z</mml:mi>
</mml:math>
</inline-formula>.<xref ref-type="fn" rid="FN4">
<sup>4</sup>
</xref> This is a natural generalization when studying the complexity of the unlockability problem for Script.</p>
<p>Script has a precisely defined set of allowed operations (<xref ref-type="bibr" rid="B9">Bitcoin Wiki, 2021</xref>), which can be thought of as transforming the two stacks, or giving an error that terminates the execution. We denote the set of Script operators with <italic>O</italic>. Formally, every Script command <italic>f</italic>, apart from those used for flow control (see <xref ref-type="sec" rid="s3-2-3">Section 3.2.3</xref>), can be understood as a function which takes the main and the alternate stack as its inputs, and transforms them in some way, or produces an error (denoted by &#x25a1;):<disp-formula id="e1">
<mml:math id="m2">
<mml:mi>f</mml:mi>
<mml:mo>:</mml:mo>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msup>
<mml:mrow>
<mml:mi mathvariant="double-struck">Z</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mo>&#x2217;</mml:mo>
</mml:mrow>
</mml:msup>
<mml:mo>&#xd7;</mml:mo>
<mml:msup>
<mml:mrow>
<mml:mi mathvariant="double-struck">Z</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mo>&#x2217;</mml:mo>
</mml:mrow>
</mml:msup>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x222a;</mml:mo>
<mml:mrow>
<mml:mo stretchy="false">{</mml:mo>
<mml:mrow>
<mml:mo>&#x25a1;</mml:mo>
</mml:mrow>
<mml:mo stretchy="false">}</mml:mo>
</mml:mrow>
<mml:mo>&#x2192;</mml:mo>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msup>
<mml:mrow>
<mml:mi mathvariant="double-struck">Z</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mo>&#x2217;</mml:mo>
</mml:mrow>
</mml:msup>
<mml:mo>&#xd7;</mml:mo>
<mml:msup>
<mml:mrow>
<mml:mi mathvariant="double-struck">Z</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mo>&#x2217;</mml:mo>
</mml:mrow>
</mml:msup>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x222a;</mml:mo>
<mml:mrow>
<mml:mo stretchy="false">{</mml:mo>
<mml:mrow>
<mml:mo>&#x25a1;</mml:mo>
</mml:mrow>
<mml:mo stretchy="false">}</mml:mo>
</mml:mrow>
<mml:mo>.</mml:mo>
</mml:math>
<label>(1)</label>
</disp-formula>
</p>
<p>Thus, scripts&#x2013;as functions&#x2013;can be composed, which naturally allows us to define the semantics of a sequence of operators. In particular, to handle errors, we impose the restriction that all of Script operators return an error when the input is an error itself, that is, <italic>f</italic>(&#x25a1;) &#x3d; &#x25a1;.</p>
<p>With this notation at hand, we define how each operator <italic>f</italic>&#x20;&#x2208; <italic>O</italic> works. We start by introducing in <xref ref-type="sec" rid="s3-2-1">Section 3.2.1</xref> a group of basic operators, and defining how a sequence of them is executed. Then we describe in <xref ref-type="sec" rid="s3-2-2">Section 3.2.2</xref> how the operators associated with cryptographic primitives work. Finally, we introduce in <xref ref-type="sec" rid="s3-2-3">Section 3.2.3</xref> the <italic>flow control</italic> operators and the control stack, which determine when an operator should or should not be executed. A summary of the operators used in this paper, without including the control flow operators, is given in <xref ref-type="table" rid="T1">Table&#x20;1</xref>. Readers familiar with the Script syntax as given in (<xref ref-type="bibr" rid="B9">Bitcoin Wiki, 2021</xref>) may note that a small number of the operators are not included in this table. For space reasons we have left out several operators that are similar to or can be simulated by applying instead a constant number of other operators. This includes, as explained bellow, merging all push operators into a single family of operators, arithmetic operators <sans-serif>OP_1ADD</sans-serif> and <sans-serif>OP_1SUB</sans-serif> for adding or subtracting one from the top of the stack, <sans-serif>OP_NEGATE</sans-serif> to flip the sign of the top of the stack, <sans-serif>OP_ABS</sans-serif> for the absolute value, binary operations <sans-serif>OP_NOT</sans-serif>, <sans-serif>OP_0NOTEQUAL</sans-serif>, <sans-serif>OP_BOOLAND</sans-serif> and <sans-serif>OP_BOOLOR</sans-serif>, number comparison operators <sans-serif>OP_NUMEQUAL</sans-serif>, <sans-serif>OP_NUMEQUALVERIFY</sans-serif>, <sans-serif>OP_NUMNOTEQUAL</sans-serif>, which are not useful under the assumption that elements in the stack are numbers, and comparison operators <sans-serif>OP_LESSTHAN</sans-serif>, <sans-serif>OP_GREATERTHAN</sans-serif>, <sans-serif>OP_LESSTHANOREQUAL</sans-serif>, <sans-serif>OP_GREATERTHANOREQUAL</sans-serif>, <sans-serif>OP_MIN</sans-serif>, <sans-serif>OP_MAX</sans-serif> and <sans-serif>OP_WITHIN</sans-serif>. Reserved words are not included because they immediately make transactions invalid, and similarly for pseudo words <sans-serif>OP_PUBKEYHASH</sans-serif>, <sans-serif>OP_PUBKEY</sans-serif> and <sans-serif>OP_INVALIDOPCODE</sans-serif>. An operator-by-operator check allows one to verify that none of these operators alter the results presented in this paper, and in particular the PTIME upper bound shown later on in the paper continues to hold. Furthermore, we have also left out locktime-related operators <sans-serif>OP_CHECKLOCKTIMEVERIFY</sans-serif> and <sans-serif>OP_CHECKSEQUENCEVERIFY</sans-serif>, because they require checking the <sans-serif>nLockTime</sans-serif> field of transactions and this is not part of our model. Finally, we will comment on the cryptographic operators on <xref ref-type="sec" rid="s3-2-2">Section 3.2.2</xref>; we have also left out some of them but once again the complexity analysis does not change.</p>
<table-wrap id="T1" position="float">
<label>TABLE 1</label>
<caption>
<p>Semantics of Script commands. We assume that <italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub> &#x3d; <italic>A</italic>
<sub>0</sub> &#x22c5; <italic>A</italic>
<sub>1</sub>&#x22ef;<italic>A</italic>
<sub>
<italic>k</italic>
</sub> whenever &#x7c;<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>&#x7c; &#x3e; 0. The condition column states the requirement that needs to be met for each operator not to return an error. Formally, if the condition for operator <italic>f</italic> is not met by (<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>, <italic>&#x3c6;</italic>
<sub>
<italic>A</italic>
</sub>), then <italic>f</italic>(<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>, <italic>&#x3c6;</italic>
<sub>
<italic>A</italic>
</sub>) &#x3d; &#x25a1;. The function <italic>hash</italic> corresponds to using SHA-256 and RIPEMD-160 hashing algorithms in succession. The function <italic>chksig</italic> corresponds to the verification algorithm of the ECDSA protocol for the string comprised of the transaction information, the first input as the public key and the second input as the signature. Computing the transaction information is a non-trivial process in Bitcoin. Since the main focus in this paper is to study the properties of Script itself, we do not model this process in our formalization.</p>
</caption>
<table>
<thead valign="top">
<tr>
<th align="center">Operator</th>
<th align="center">Condition</th>
<th align="center">Semantics</th>
</tr>
</thead>
<tbody valign="top">
<tr>
<td align="left">
<italic>OP</italic>_<italic>PUSH</italic>
<sub>
<italic>C</italic>
</sub>
</td>
<td align="left">None</td>
<td align="left">
<italic>OP</italic>_<italic>PUSH</italic>
<sub>
<italic>C</italic>
</sub>(<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>, <italic>&#x3c6;</italic>
<sub>
<italic>A</italic>
</sub>) &#x3d; (<italic>C</italic>&#x20;&#x22c5; <italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>, <italic>&#x3c6;</italic>
<sub>
<italic>A</italic>
</sub>)</td>
</tr>
<tr>
<td align="left">
<italic>OP</italic>_<italic>DROP</italic>
</td>
<td align="left">&#x7c;<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>&#x7c;&#x2265; 1</td>
<td align="left">
<italic>OP</italic>_<italic>DROP</italic>(<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>, <italic>&#x3c6;</italic>
<sub>
<italic>A</italic>
</sub>) &#x3d; (<italic>tail</italic>(<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>), <italic>&#x3c6;</italic>
<sub>
<italic>A</italic>
</sub>)</td>
</tr>
<tr>
<td align="left">
<italic>OP</italic>_<italic>DUP</italic>
</td>
<td align="left">&#x7c;<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>&#x7c;&#x2265; 1</td>
<td align="left">
<italic>OP</italic>_<italic>DUP</italic>(<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>, <italic>&#x3c6;</italic>
<sub>
<italic>A</italic>
</sub>) &#x3d; (<italic>top</italic>(<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>) &#x22c5; <italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>, <italic>&#x3c6;</italic>
<sub>
<italic>A</italic>
</sub>)</td>
</tr>
<tr>
<td align="left">
<italic>OP</italic>_<italic>TOALTSTACK</italic>
</td>
<td align="left">&#x7c;<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>&#x7c;&#x2265; 1</td>
<td align="left">
<italic>OP</italic>_<italic>TOALTSTACK</italic>(<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>, <italic>&#x3c6;</italic>
<sub>
<italic>A</italic>
</sub>) &#x3d; (<italic>tail</italic>(<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>), <italic>top</italic>(<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>)&#x22c5;<italic>&#x3c6;</italic>
<sub>
<italic>A</italic>
</sub>)</td>
</tr>
<tr>
<td align="left">
<italic>OP</italic>_<italic>FROMALTSTACK</italic>
</td>
<td align="left">&#x7c;<italic>&#x3c6;</italic>
<sub>
<italic>A</italic>
</sub>&#x7c;&#x2265; 1</td>
<td align="left">
<italic>OP</italic>_<italic>FROMALTSTACK</italic>(<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>, <italic>&#x3c6;</italic>
<sub>
<italic>A</italic>
</sub>) &#x3d; (<italic>top</italic>(<italic>&#x3c6;</italic>
<sub>
<italic>A</italic>
</sub>)&#x22c5;<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>, <italic>tail</italic>(<italic>&#x3c6;</italic>
<sub>
<italic>A</italic>
</sub>))</td>
</tr>
<tr>
<td align="left">
<italic>OP</italic>_<italic>VERIFY</italic>
</td>
<td align="left">&#x7c;<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>&#x7c;&#x2265; 1 &#x2227;<italic>top</italic>(<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>) &#x2260; 0</td>
<td align="left">
<italic>OP</italic>_<italic>VERIFY</italic>(<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>, <italic>&#x3c6;</italic>
<sub>
<italic>A</italic>
</sub>) &#x3d; (<italic>tail</italic>(<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>), <italic>&#x3c6;</italic>
<sub>
<italic>A</italic>
</sub>)</td>
</tr>
<tr>
<td align="left">
<italic>OP</italic>_<italic>IFDUP</italic>
</td>
<td align="left">&#x7c;<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>&#x7c;&#x2265; 1</td>
<td align="left">
<inline-formula id="inf2">
<mml:math id="m3">
<mml:mtext mathvariant="sans-serif">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:mtext mathvariant="sans-serif">IFDUP</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x3d;</mml:mo>
<mml:mfenced open="{" close="">
<mml:mrow>
<mml:mtable class="matrix">
<mml:mtr>
<mml:mtd columnalign="center">
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:mtd>
<mml:mtd columnalign="center">
<mml:mtext>if</mml:mtext>
</mml:mtd>
<mml:mtd columnalign="center">
<mml:mtext mathvariant="sans-serif">top</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x3d;</mml:mo>
<mml:mn>0</mml:mn>
</mml:mtd>
</mml:mtr>
<mml:mtr>
<mml:mtd columnalign="center">
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mtext mathvariant="sans-serif">top</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x22c5;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:mtd>
<mml:mtd columnalign="center">
<mml:mtext>if</mml:mtext>
</mml:mtd>
<mml:mtd columnalign="center">
<mml:mtext mathvariant="sans-serif">top</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x2260;</mml:mo>
<mml:mn>0</mml:mn>
</mml:mtd>
</mml:mtr>
</mml:mtable>
</mml:mrow>
</mml:mfenced>
</mml:math>
</inline-formula>
</td>
</tr>
<tr>
<td align="left">
<italic>OP</italic>_<italic>NIP</italic>
</td>
<td align="left">&#x7c;<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>&#x7c;&#x2265; 2</td>
<td align="left">
<italic>OP</italic>_<italic>NIP</italic>(<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>, <italic>&#x3c6;</italic>
<sub>
<italic>A</italic>
</sub>) &#x3d; (<italic>A</italic>
<sub>0</sub>&#x22c5;<italic>A</italic>
<sub>2</sub>&#x22c5;&#x2026;&#x22c5;<italic>A</italic>
<sub>
<italic>k</italic>
</sub>, <italic>&#x3c6;</italic>
<sub>
<italic>A</italic>
</sub>)</td>
</tr>
<tr>
<td align="left">
<italic>OP</italic>_<italic>OVER</italic>
</td>
<td align="left">&#x7c;<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>&#x7c;&#x2265; 2</td>
<td align="left">
<italic>OP</italic>_<italic>OVER</italic>(<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>, <italic>&#x3c6;</italic>
<sub>
<italic>A</italic>
</sub>) &#x3d; (<italic>A</italic>
<sub>1</sub> &#x22c5; <italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>, <italic>&#x3c6;</italic>
<sub>
<italic>A</italic>
</sub>)</td>
</tr>
<tr>
<td align="left">
<italic>OP</italic>_<italic>ROT</italic>
</td>
<td align="left">&#x7c;<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>&#x7c;&#x2265; 3</td>
<td align="left">
<italic>OP</italic>_<italic>ROT</italic>(<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>, <italic>&#x3c6;</italic>
<sub>
<italic>A</italic>
</sub>) &#x3d; (<italic>A</italic>
<sub>2</sub>&#x22c5;<italic>A</italic>
<sub>0</sub>&#x22c5;<italic>A</italic>
<sub>1</sub>&#x22c5;<italic>A</italic>
<sub>3</sub>&#x22c5;&#x2026;&#x22c5;<italic>A</italic>
<sub>
<italic>k</italic>
</sub>, <italic>&#x3c6;</italic>
<sub>
<italic>A</italic>
</sub>)</td>
</tr>
<tr>
<td align="left">
<italic>OP</italic>_<italic>SWAP</italic>
</td>
<td align="left">&#x7c;<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>&#x7c;&#x2265; 2</td>
<td align="left">
<italic>OP</italic>_<italic>SWAP</italic>(<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>, <italic>&#x3c6;</italic>
<sub>
<italic>A</italic>
</sub>) &#x3d; (<italic>A</italic>
<sub>1</sub>&#x22c5;<italic>A</italic>
<sub>0</sub>&#x22c5;<italic>A</italic>
<sub>2</sub>&#x22c5;&#x2026;&#x22c5;<italic>A</italic>
<sub>
<italic>k</italic>
</sub>, <italic>&#x3c6;</italic>
<sub>
<italic>A</italic>
</sub>)</td>
</tr>
<tr>
<td align="left">
<italic>OP</italic>_<italic>TUCK</italic>
</td>
<td align="left">&#x7c;<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>&#x7c;&#x2265; 2</td>
<td align="left">
<italic>OP</italic>_<italic>TUCK</italic>(<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>, <italic>&#x3c6;</italic>
<sub>
<italic>A</italic>
</sub>) &#x3d; (<italic>A</italic>
<sub>0</sub>&#x22c5;<italic>A</italic>
<sub>1</sub>&#x22c5;<italic>A</italic>
<sub>0</sub>&#x22c5;<italic>A</italic>
<sub>2</sub>&#x22c5;&#x2026;&#x22c5;<italic>A</italic>
<sub>
<italic>k</italic>
</sub>, <italic>&#x3c6;</italic>
<sub>
<italic>A</italic>
</sub>)</td>
</tr>
<tr>
<td align="left">
<italic>OP</italic>_2<italic>DROP</italic>
</td>
<td align="left">&#x7c;<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>&#x7c;&#x2265; 2</td>
<td align="left">
<italic>OP</italic>_2<italic>DROP</italic>(<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>, <italic>&#x3c6;</italic>
<sub>
<italic>A</italic>
</sub>) &#x3d; (<italic>tail</italic>(<italic>tail</italic>(<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>)), <italic>&#x3c6;</italic>
<sub>
<italic>A</italic>
</sub>)</td>
</tr>
<tr>
<td align="left">
<italic>OP</italic>_2<italic>DUP</italic>
</td>
<td align="left">&#x7c;<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>&#x7c;&#x2265; 2</td>
<td align="left">
<italic>OP</italic>_2<italic>DUP</italic>(<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>, <italic>&#x3c6;</italic>
<sub>
<italic>A</italic>
</sub>) &#x3d; (<italic>A</italic>
<sub>0</sub> &#x22c5; <italic>A</italic>
<sub>1</sub> &#x22c5; <italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>, <italic>&#x3c6;</italic>
<sub>
<italic>A</italic>
</sub>)</td>
</tr>
<tr>
<td align="left">
<italic>OP</italic>_3<italic>DUP</italic>
</td>
<td align="left">&#x7c;<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>&#x7c;&#x2265; 3</td>
<td align="left">
<italic>OP</italic>_2<italic>DUP</italic>(<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>, <italic>&#x3c6;</italic>
<sub>
<italic>A</italic>
</sub>) &#x3d; (<italic>A</italic>
<sub>0</sub> &#x22c5; <italic>A</italic>
<sub>1</sub> &#x22c5; <italic>A</italic>
<sub>2</sub> &#x22c5; <italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>, <italic>&#x3c6;</italic>
<sub>
<italic>A</italic>
</sub>)</td>
</tr>
<tr>
<td align="left">
<italic>OP</italic>_2<italic>OVER</italic>
</td>
<td align="left">&#x7c;<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>&#x7c;&#x2265; 4</td>
<td align="left">
<italic>OP</italic>_2<italic>OVER</italic>(<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>, <italic>&#x3c6;</italic>
<sub>
<italic>A</italic>
</sub>) &#x3d; (<italic>A</italic>
<sub>2</sub> &#x22c5; <italic>A</italic>
<sub>3</sub> &#x22c5; <italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>, <italic>&#x3c6;</italic>
<sub>
<italic>A</italic>
</sub>)</td>
</tr>
<tr>
<td align="left">
<italic>OP</italic>_2<italic>ROT</italic>
</td>
<td align="left">&#x7c;<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>&#x7c;&#x2265; 6</td>
<td align="left">
<italic>OP</italic>_2<italic>ROT</italic>(<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>, <italic>&#x3c6;</italic>
<sub>
<italic>A</italic>
</sub>) &#x3d; (<italic>A</italic>
<sub>4</sub>&#x22c5;<italic>A</italic>
<sub>5</sub>&#x22c5;<italic>A</italic>
<sub>0</sub>&#x22c5;<italic>A</italic>
<sub>1</sub>&#x22c5;<italic>A</italic>
<sub>2</sub>&#x22c5;<italic>A</italic>
<sub>3</sub>&#x22c5;<italic>A</italic>
<sub>6</sub>&#x22c5;&#x2026;&#x22c5;<italic>A</italic>
<sub>
<italic>k</italic>
</sub>, <italic>&#x3c6;</italic>
<sub>
<italic>A</italic>
</sub>)</td>
</tr>
<tr>
<td align="left">
<italic>OP</italic>_2<italic>SWAP</italic>
</td>
<td align="left">&#x7c;<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>&#x7c;&#x2265; 4</td>
<td align="left">
<italic>OP</italic>_2<italic>SWAP</italic>(<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>, <italic>&#x3c6;</italic>
<sub>
<italic>A</italic>
</sub>) &#x3d; (<italic>A</italic>
<sub>2</sub>&#x22c5;<italic>A</italic>
<sub>3</sub>&#x22c5;<italic>A</italic>
<sub>0</sub>&#x22c5;<italic>A</italic>
<sub>1</sub>&#x22c5;<italic>A</italic>
<sub>4</sub>&#x22c5;&#x2026;&#x22c5;<italic>A</italic>
<sub>
<italic>k</italic>
</sub>, <italic>&#x3c6;</italic>
<sub>
<italic>A</italic>
</sub>)</td>
</tr>
<tr>
<td align="left">
<italic>OP</italic>_<italic>ADD</italic>
</td>
<td align="left">&#x7c;<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>&#x7c;&#x2265; 2</td>
<td align="left">
<italic>OP</italic>_<italic>ADD</italic>(<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>, <italic>&#x3c6;</italic>
<sub>
<italic>A</italic>
</sub>) &#x3d; ((<italic>A</italic>
<sub>0</sub> &#x2b; <italic>A</italic>
<sub>1</sub>) &#x22c5; <italic>A</italic>
<sub>2</sub>&#x22ef;<italic>A</italic>
<sub>
<italic>k</italic>
</sub>, <italic>&#x3c6;</italic>
<sub>
<italic>A</italic>
</sub>)</td>
</tr>
<tr>
<td align="left">
<italic>OP</italic>_<italic>SUB</italic>
</td>
<td align="left">&#x7c;<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>&#x7c;&#x2265; 2</td>
<td align="left">
<italic>OP</italic>_<italic>SUB</italic>(<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>, <italic>&#x3c6;</italic>
<sub>
<italic>A</italic>
</sub>) &#x3d; ((<italic>A</italic>
<sub>1</sub> &#x2212; <italic>A</italic>
<sub>0</sub>) &#x22c5; <italic>A</italic>
<sub>2</sub>&#x22ef;<italic>A</italic>
<sub>
<italic>k</italic>
</sub>, <italic>&#x3c6;</italic>
<sub>
<italic>A</italic>
</sub>)</td>
</tr>
<tr>
<td align="left">
<italic>OP</italic>_<italic>EQUAL</italic>
</td>
<td align="left">&#x7c;<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>&#x7c;&#x2265; 2</td>
<td align="left">
<inline-formula id="inf3">
<mml:math id="m4">
<mml:mtext mathvariant="sans-serif">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:mtext mathvariant="sans-serif">EQUAL</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x3d;</mml:mo>
<mml:mfenced open="{" close="">
<mml:mrow>
<mml:mtable class="matrix">
<mml:mtr>
<mml:mtd columnalign="center">
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mn>1</mml:mn>
<mml:mo>&#x22c5;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mn>2</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mo>&#x22c5;</mml:mo>
<mml:mo>&#x2026;</mml:mo>
<mml:mo>&#x22c5;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>k</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:mtd>
<mml:mtd columnalign="center">
<mml:mtext>if</mml:mtext>
</mml:mtd>
<mml:mtd columnalign="center">
<mml:msub>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mn>0</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mo>&#x3d;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mn>1</mml:mn>
</mml:mrow>
</mml:msub>
</mml:mtd>
</mml:mtr>
<mml:mtr>
<mml:mtd columnalign="center">
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mn>0</mml:mn>
<mml:mo>&#x22c5;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mn>2</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mo>&#x22c5;</mml:mo>
<mml:mo>&#x2026;</mml:mo>
<mml:mo>&#x22c5;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>k</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:mtd>
<mml:mtd columnalign="center">
<mml:mtext>if</mml:mtext>
</mml:mtd>
<mml:mtd columnalign="center">
<mml:msub>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mn>0</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mo>&#x2260;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mn>1</mml:mn>
</mml:mrow>
</mml:msub>
</mml:mtd>
</mml:mtr>
</mml:mtable>
</mml:mrow>
</mml:mfenced>
</mml:math>
</inline-formula>
</td>
</tr>
<tr>
<td align="left">
<italic>OP</italic>_<italic>EQUALVERIFY</italic>
</td>
<td align="left">&#x7c;<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>&#x7c;&#x2265; 2 &#x2227; <italic>A</italic>
<sub>0</sub> &#x3d; <italic>A</italic>
<sub>1</sub>
</td>
<td align="left">
<italic>OP</italic>_<italic>EQUALVERIFY</italic>(<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>, <italic>&#x3c6;</italic>
<sub>
<italic>A</italic>
</sub>) &#x3d; (<italic>A</italic>
<sub>2</sub>&#x22c5;&#x2026;&#x22c5;<italic>A</italic>
<sub>
<italic>k</italic>
</sub>, <italic>&#x3c6;</italic>
<sub>
<italic>A</italic>
</sub>)</td>
</tr>
<tr>
<td align="left">
<italic>OP</italic>_<italic>PICK</italic>
</td>
<td align="left">&#x7c;<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>&#x7c;&#x2265; 1 &#x2227; <italic>A</italic>
<sub>0</sub> &#x2265; 0 &#x2227;&#x7c;<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>&#x7c;&#x2265; <italic>A</italic>
<sub>0</sub> &#x2b; 2</td>
<td align="left">
<inline-formula id="inf4">
<mml:math id="m5">
<mml:mtext mathvariant="sans-serif">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:mtext mathvariant="sans-serif">PICK</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x3d;</mml:mo>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mn>0</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mo>&#x2b;</mml:mo>
<mml:mn>1</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mo>&#x22c5;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mn>1</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mo>&#x22c5;</mml:mo>
<mml:mo>&#x2026;</mml:mo>
<mml:mo>&#x22c5;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>k</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:math>
</inline-formula>
</td>
</tr>
<tr>
<td align="left">
<italic>OP</italic>_<italic>ROLL</italic>
</td>
<td align="left">&#x7c;<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>&#x7c;&#x2265; 1 &#x2227; <italic>A</italic>
<sub>0</sub> &#x2265; 0 &#x2227;&#x7c;<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>&#x7c;&#x2265; <italic>A</italic>
<sub>0</sub> &#x2b; 2</td>
<td align="left">
<inline-formula id="inf5">
<mml:math id="m6">
<mml:mtext mathvariant="sans-serif">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:mtext mathvariant="sans-serif">ROLL</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x3d;</mml:mo>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mn>0</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mo>&#x2b;</mml:mo>
<mml:mn>1</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mo>&#x22c5;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mn>1</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mo>&#x22c5;</mml:mo>
<mml:mo>&#x2026;</mml:mo>
<mml:mo>&#x22c5;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mn>0</mml:mn>
</mml:mrow>
</mml:msub>
</mml:mrow>
</mml:msub>
<mml:mo>&#x22c5;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mn>0</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mo>&#x2b;</mml:mo>
<mml:mn>2</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mo>&#x22c5;</mml:mo>
<mml:mo>&#x2026;</mml:mo>
<mml:mo>&#x22c5;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>k</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:math>
</inline-formula>
</td>
</tr>
<tr>
<td align="left">
<italic>OP</italic>_<italic>DEPTH</italic>
</td>
<td align="left">None</td>
<td align="left">
<italic>OP</italic>_<italic>DEPTH</italic>(<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>, <italic>&#x3c6;</italic>
<sub>
<italic>A</italic>
</sub>) &#x3d; (&#x7c;<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>&#x7c;&#x22c5; <italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>, <italic>&#x3c6;</italic>
<sub>
<italic>A</italic>
</sub>)</td>
</tr>
<tr>
<td align="left">
<italic>OP</italic>_<italic>HASH</italic>160</td>
<td align="left">&#x7c;<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>&#x7c;&#x2265; 1</td>
<td align="left">
<italic>OP</italic>_<italic>HASH</italic>160(<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>, <italic>&#x3c6;</italic>
<sub>
<italic>A</italic>
</sub>) &#x3d; (<italic>hash</italic>(<italic>A</italic>
<sub>0</sub>) &#x22c5;<italic>tail</italic>(<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>), <italic>&#x3c6;</italic>
<sub>
<italic>A</italic>
</sub>)</td>
</tr>
<tr>
<td align="left">
<italic>OP</italic>_<italic>CHECKSIG</italic>
</td>
<td align="left">&#x7c;<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>&#x7c;&#x2265; 2</td>
<td align="left">
<italic>OP</italic>_<italic>CHECKSIG</italic>(<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>, <italic>&#x3c6;</italic>
<sub>
<italic>A</italic>
</sub>) &#x3d; (<italic>chksig</italic>(<italic>A</italic>
<sub>0</sub>, <italic>A</italic>
<sub>1</sub>)&#x22c5;<italic>A</italic>
<sub>2</sub>&#x22c5;&#x2026;&#x22c5;<italic>A</italic>
<sub>
<italic>k</italic>
</sub>, <italic>&#x3c6;</italic>
<sub>
<italic>A</italic>
</sub>)</td>
</tr>
<tr>
<td align="left">
<italic>OP</italic>_<italic>CHECKSIGVERIFY</italic>
</td>
<td align="left">&#x7c;<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>&#x7c;&#x2265; 2 &#x2227;<italic>chksig</italic>(<italic>A</italic>
<sub>0</sub>, <italic>A</italic>
<sub>1</sub>) &#x3d; 1</td>
<td align="left">
<italic>OP</italic>_<italic>CHECKSIGVERIFY</italic>(<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>, <italic>&#x3c6;</italic>
<sub>
<italic>A</italic>
</sub>) &#x3d; (<italic>A</italic>
<sub>2</sub>&#x22c5;&#x2026;&#x22c5;<italic>A</italic>
<sub>
<italic>k</italic>
</sub>, <italic>&#x3c6;</italic>
<sub>
<italic>A</italic>
</sub>)</td>
</tr>
</tbody>
</table>
</table-wrap>
<sec id="s3-2-1">
<title>3.2.1 Basic Operators in Script</title>
<p>The most basic operation in Script is pushing data onto the (main) stack, which is achieved using a multitude of different operators [see e.g. the section on &#x201c;Constants&#x201d; in <xref ref-type="bibr" rid="B9">Bitcoin Wiki (2021)</xref>]. In order to simplify this process, we combine all of these methods of pushing data through the <italic>OP</italic>_<italic>PUSH</italic>
<sub>
<italic>C</italic>
</sub> operator, which pushes the value <italic>C</italic> onto the main stack. In terms of our generic description of Script commands (1), the semantics of this operation is defined as follows:<disp-formula id="equ1">
<mml:math id="m7">
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:msub>
<mml:mrow>
<mml:mtext mathvariant="normal">PUSH</mml:mtext>
</mml:mrow>
<mml:mrow>
<mml:mi>C</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x3d;</mml:mo>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mi>C</mml:mi>
<mml:mo>&#x22c5;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>.</mml:mo>
</mml:math>
</disp-formula>That is, if the operator receives as input a pair of valid stacks <italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub> and <italic>&#x3c6;</italic>
<sub>
<italic>A</italic>
</sub>, then it puts <italic>C</italic> on top of <italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>. Moreover, as already mentioned, we assume that <italic>OP</italic>_<italic>PUSH</italic>
<sub>
<italic>C</italic>
</sub>(&#x25a1;) &#x3d; &#x25a1;.</p>
<p>Notice that for each value <inline-formula id="inf6">
<mml:math id="m8">
<mml:mi>C</mml:mi>
<mml:mo>&#x2208;</mml:mo>
<mml:mi mathvariant="double-struck">Z</mml:mi>
</mml:math>
</inline-formula>, we include an operator <italic>OP</italic>_<italic>PUSH</italic>
<sub>
<italic>C</italic>
</sub>. We designed the language in this way to be able to define the semantics of a sequence of operators as their composition as functions. In fact, if we had included a single operator <italic>OP</italic>_<italic>PUSH</italic> with input (<italic>C</italic>, <italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>, <italic>&#x3c6;</italic>
<sub>
<italic>A</italic>
</sub>), then this property would no longer hold; in particular, the output (<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>, <italic>&#x3c6;</italic>
<sub>
<italic>A</italic>
</sub>) of an operator cannot be used as the input of <italic>OP</italic>_<italic>PUSH</italic>.</p>
<p>Similarly, to pop the top of the stack, we can use <italic>OP</italic>_<italic>DROP</italic>, and to duplicate the top element of the stack, <italic>OP</italic>_<italic>DUP</italic>. Both of these operators require that the main stack <italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub> contains at least one element (i.e. &#x7c;<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>&#x7c;&#x2265; 1), otherwise they return an error. In the case of a nonempty stack, their behavior is defined as:<disp-formula id="equ2">
<mml:math id="m9">
<mml:mtable class="eqnarray-star">
<mml:mtr>
<mml:mtd columnalign="right">
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:mtext mathvariant="normal">DROP</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:mtd>
<mml:mtd columnalign="left">
<mml:mo>&#x3d;</mml:mo>
</mml:mtd>
<mml:mtd columnalign="left">
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mtext mathvariant="normal">tail</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:mtd>
</mml:mtr>
<mml:mtr>
<mml:mtd columnalign="right">
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:mtext mathvariant="normal">DUP</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:mtd>
<mml:mtd columnalign="left">
<mml:mo>&#x3d;</mml:mo>
</mml:mtd>
<mml:mtd columnalign="left">
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mtext mathvariant="normal">top</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x22c5;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:mtd>
</mml:mtr>
</mml:mtable>
</mml:math>
</disp-formula>
</p>
<p>The alternate stack in Bitcoin can be accessed in a very limited number of ways: we can only move the top element from the main stack onto it by means of the operator <italic>OP</italic>_<italic>TOALTSTACK</italic>, and move the top element of the alternate stack onto the main stack by means of the operator <italic>OP</italic>_<italic>FROMALTSTACK</italic>. Formally,<disp-formula id="equ3">
<mml:math id="m10">
<mml:mtable class="eqnarray-star">
<mml:mtr>
<mml:mtd columnalign="right">
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:mtext mathvariant="normal">TOALTSTACK</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:mtd>
<mml:mtd columnalign="left">
<mml:mo>&#x3d;</mml:mo>
</mml:mtd>
<mml:mtd columnalign="left">
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mtext mathvariant="normal">tail</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>,</mml:mo>
<mml:mtext mathvariant="normal">top</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x22c5;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mspace width="1em"/>
<mml:mspace width="1em"/>
<mml:mtext>&#x2009;if&#x2009;</mml:mtext>
<mml:mo stretchy="false">&#x7c;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo stretchy="false">&#x7c;</mml:mo>
<mml:mo>&#x2265;</mml:mo>
<mml:mn>1</mml:mn>
</mml:mtd>
</mml:mtr>
<mml:mtr>
<mml:mtd columnalign="right">
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:mtext mathvariant="normal">FROMALTSTACK</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:mtd>
<mml:mtd columnalign="left">
<mml:mo>&#x3d;</mml:mo>
</mml:mtd>
<mml:mtd columnalign="left">
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mtext mathvariant="normal">top</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x22c5;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:mtext mathvariant="normal">tail</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mspace width="1em"/>
<mml:mspace width="1em"/>
<mml:mtext>if&#x2009;</mml:mtext>
<mml:mo stretchy="false">&#x7c;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo stretchy="false">&#x7c;</mml:mo>
<mml:mo>&#x2265;</mml:mo>
<mml:mn>1</mml:mn>
</mml:mtd>
</mml:mtr>
</mml:mtable>
</mml:math>
</disp-formula>
</p>
<p>In <xref ref-type="table" rid="T1">Table&#x20;1</xref>, we provide the list of remaining basic operators and their semantics (except for the last three rows of this table that include the operators defined in the following section).</p>
<p>As Script operators are understood as functions, the semantics of a script <italic>f</italic>
<sub>1</sub>&#x22c5;<italic>f</italic>
<sub>2</sub>&#x22c5;&#x2026;&#x22c5;<italic>f</italic>
<sub>
<italic>n</italic>
</sub> consisting of a sequence of operators is defined as the composition of these functions. Moreover, a script is <italic>executed successfully</italic> over a stack <italic>&#x3c6;</italic> if upon executing all of its commands with <italic>&#x3c6;</italic> as the initial main stack, we are left with a nonempty main stack containing a nonzero element at the top. Formally, a script <italic>f</italic>
<sub>1</sub>&#x22c5;<italic>f</italic>
<sub>2</sub>&#x22c5;&#x2026;&#x22c5;<italic>f</italic>
<sub>
<italic>n</italic>
</sub> is executed successfully over a stack <italic>&#x3c6;</italic> if (<italic>f</italic>
<sub>
<italic>n</italic>
</sub>&#x25e6;&#x2026;&#x25e6;<italic>f</italic>
<sub>2</sub>&#x25e6;<italic>f</italic>
<sub>1</sub>)(<italic>&#x3c6;</italic>, <italic>&#x25b;</italic>) &#x3d; (<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>, <italic>&#x3c6;</italic>
<sub>
<italic>A</italic>
</sub>) with <italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub> &#x2260; <italic>&#x25b;</italic> and <italic>top</italic>(<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>) &#x2260; 0. It is important to notice that the possibility of starting with a nonempty main stack is included because of the way in which the unlocking and the locking script are executed in succession, which does not exactly match the execution of the concatenation of both scripts. Formally, when we have a locking script <italic>l</italic>, and an unlocking script <italic>u</italic>, we require that: 1) <inline-formula id="inf7">
<mml:math id="m11">
<mml:mi>u</mml:mi>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mi>&#x3b5;</mml:mi>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x3d;</mml:mo>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msubsup>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>u</mml:mi>
</mml:mrow>
</mml:msubsup>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:math>
</inline-formula> (with no errors thrown in between); and 2) <inline-formula id="inf8">
<mml:math id="m12">
<mml:mi>l</mml:mi>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msubsup>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>u</mml:mi>
</mml:mrow>
</mml:msubsup>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:math>
</inline-formula> executes successfully.</p>
<p>
<statement content-type="example" id="Example_3_1">
<label>Example 3.1</label>
<p>Consider the script<disp-formula id="equ4">
<mml:math id="m13">
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:msub>
<mml:mrow>
<mml:mtext mathvariant="normal">PUSH</mml:mtext>
</mml:mrow>
<mml:mrow>
<mml:mn>5</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mo>&#x22c5;</mml:mo>
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:msub>
<mml:mrow>
<mml:mtext mathvariant="normal">PUSH</mml:mtext>
</mml:mrow>
<mml:mrow>
<mml:mo>&#x2212;</mml:mo>
<mml:mn>3</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mo>&#x22c5;</mml:mo>
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:mtext mathvariant="normal">ADD</mml:mtext>
</mml:math>
</disp-formula>
</p>
<p>We execute this script starting with empty main and alternate stacks. We first push number 5 onto the main stack, and then push &#x2212;3 at the top of the main stack. The last operator is OP_ADD, which according to the semantics defined in <xref ref-type="table" rid="T1">Table&#x20;1</xref> generates a main stack containing only the number 2 &#x3d; &#x2212; 3&#x20;&#x2b; 5. Hence, this script is executed successfully, since upon its completion, we have a nonempty main stack with a nonzero top element. &#x25a0;</p>
</statement>
</p>
</sec>
<sec id="s3-2-2">
<title>3.2.2 Operators for Executing Cryptographic Primitives</title>
<p>An important part of Script resides in the execution of cryptographic primitives, since in most of the popular locking scripts these functions are used to verify the identity of the recipient of a transaction. While there are several cryptographic operators in Script, we only consider the most prevalent of them: <italic>OP</italic>_<italic>HASH</italic>160, which hashes an input, and <italic>OP</italic>_<italic>CHECKSIG</italic> and <italic>OP</italic>_<italic>CHECKSIGVERIFY</italic>, which are used to check a digital signature. The analysis for all the other cryptographic primitives is identical to these cases. Let us first describe the primitives <italic>hash</italic> and <italic>chksig</italic> underlying these operators.</p>
<p>The operator <inline-formula id="inf9">
<mml:math id="m14">
<mml:mtext mathvariant="normal">hash</mml:mtext>
<mml:mo>:</mml:mo>
<mml:mi mathvariant="double-struck">Z</mml:mi>
<mml:mo>&#x2192;</mml:mo>
<mml:mi mathvariant="double-struck">Z</mml:mi>
</mml:math>
</inline-formula> is a function whose value is the result of hashing the input by using SHA-256 and then RIPEMD-160. Moreover, <italic>chksig</italic> is defined as follows. In a digital signature protocol, the signature verification function receives as input a public key, a string and a signature. Then such a function determines whether the signature was obtained by executing the signing function over the string and the private key corresponding to the public key. However, the signature verification operators in Script only receive as input a public key and a signature. This is because the purpose of these operators is just to determine if the recipient has access to a certain private key. Therefore, the string that is signed is a predetermined construction that is obtained by executing certain transformations over a combination of the transaction&#x2019;s inputs, outputs and locking scripts. Thus, given that for the purposes of each script the document that is signed is a constant, we will disregard this element in our analysis, and we define <inline-formula id="inf10">
<mml:math id="m15">
<mml:mtext mathvariant="normal">chksig</mml:mtext>
<mml:mo>:</mml:mo>
<mml:mi mathvariant="double-struck">Z</mml:mi>
<mml:mo>&#xd7;</mml:mo>
<mml:mi mathvariant="double-struck">Z</mml:mi>
<mml:mo>&#x2192;</mml:mo>
<mml:mrow>
<mml:mo stretchy="false">{</mml:mo>
<mml:mrow>
<mml:mn>0,1</mml:mn>
</mml:mrow>
<mml:mo stretchy="false">}</mml:mo>
</mml:mrow>
</mml:math>
</inline-formula> as a function that takes only two inputs: a string representing a public key and a string representing a digital signature. The value of <italic>chksig</italic>(<italic>n</italic>
<sub>1</sub>, <italic>n</italic>
<sub>2</sub>) is defined as 1 if <italic>n</italic>
<sub>2</sub> is a valid signature for the document constructed from the transaction (as described previously) and the public key <italic>n</italic>
<sub>1</sub>, and the value of <italic>chksig</italic>(<italic>n</italic>
<sub>1</sub>, <italic>n</italic>
<sub>2</sub>) is 0 otherwise. The digital signature protocol that is used to generate and verify signatures is ECDSA with the secp256k1 elliptic curve (<xref ref-type="bibr" rid="B9">Bitcoin Wiki, 2021</xref>).</p>
<p>Finally, we provide the formal definitions of the hashing and signature checking operators. For the hashing operator, the main stack <italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub> is required to contain at least one element (i.e. &#x7c;<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>&#x7c;&#x2265; 1), whereas both signature checking operators require the main stack to have at least two elements (i.e. &#x7c;<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>&#x7c;&#x2265; 2). If these conditions are not satisfied, then these operators return an error &#x25a1;. In the definition, we assume that <italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub> &#x3d; <italic>A</italic>
<sub>0</sub>&#x22c5;<italic>A</italic>
<sub>1</sub>&#x22c5;&#x2026;&#x22c5;<italic>A</italic>
<sub>
<italic>k</italic>
</sub>:<disp-formula id="equ5">
<mml:math id="m16">
<mml:mtable class="eqnarray-star">
<mml:mtr>
<mml:mtd columnalign="right">
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:mtext mathvariant="normal">HASH</mml:mtext>
<mml:mn>160</mml:mn>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:mtd>
<mml:mtd columnalign="left">
<mml:mo>&#x3d;</mml:mo>
</mml:mtd>
<mml:mtd columnalign="left">
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mtext mathvariant="normal">hash</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mn>0</mml:mn>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x22c5;</mml:mo>
<mml:mtext mathvariant="normal">tail</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:mtd>
</mml:mtr>
<mml:mtr>
<mml:mtd columnalign="right">
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:mtext mathvariant="normal">CHECKSIG</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:mtd>
<mml:mtd columnalign="left">
<mml:mo>&#x3d;</mml:mo>
</mml:mtd>
<mml:mtd columnalign="left">
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mtext mathvariant="normal">chksig</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mn>0</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mn>1</mml:mn>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x22c5;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mn>2</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mo>&#x22c5;</mml:mo>
<mml:mo>&#x2026;</mml:mo>
<mml:mo>&#x22c5;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>k</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:mtd>
</mml:mtr>
<mml:mtr>
<mml:mtd columnalign="right">
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:mtext mathvariant="normal">CHECKSIGVERIFY</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:mtd>
<mml:mtd columnalign="left">
<mml:mo>&#x3d;</mml:mo>
</mml:mtd>
<mml:mtd columnalign="left">
<mml:mfenced open="{" close="">
<mml:mrow>
<mml:mtable class="cases">
<mml:mtr>
<mml:mtd columnalign="left">
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mn>2</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mo>&#x22c5;</mml:mo>
<mml:mo>&#x2026;</mml:mo>
<mml:mo>&#x22c5;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>k</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mspace width="1em"/>
</mml:mtd>
<mml:mtd columnalign="left">
<mml:mtext>if&#x2009;</mml:mtext>
<mml:mtext mathvariant="normal">chksig</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mn>0</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mn>1</mml:mn>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x3d;</mml:mo>
<mml:mn>1</mml:mn>
</mml:mtd>
</mml:mtr>
<mml:mtr>
<mml:mtd columnalign="left">
<mml:mo>&#x25a1;</mml:mo>
<mml:mspace width="1em"/>
</mml:mtd>
<mml:mtd columnalign="left">
<mml:mtext>if&#x2009;</mml:mtext>
<mml:mtext mathvariant="normal">chksig</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mn>0</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mn>1</mml:mn>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x3d;</mml:mo>
<mml:mn>0</mml:mn>
</mml:mtd>
</mml:mtr>
</mml:mtable>
</mml:mrow>
</mml:mfenced>
</mml:mtd>
</mml:mtr>
</mml:mtable>
</mml:math>
</disp-formula>
</p>
</sec>
<sec id="s3-2-3">
<title>3.2.3 Operators for Flow Control</title>
<p>The final piece we need to add are the flow control operators of the form if-then-else. While conceptually simple, formalizing this concept needs an extra piece of notation, since in a block of the&#x20;form</p>
<p>
<sans-serif>if</sans-serif> <inline-formula id="inf11">
<mml:math id="m17">
<mml:mo>&#x3c;</mml:mo>
<mml:mi mathvariant="monospace">s</mml:mi>
<mml:mi mathvariant="monospace">o</mml:mi>
<mml:mi mathvariant="monospace">m</mml:mi>
<mml:mi mathvariant="monospace">e</mml:mi>
<mml:mi mathvariant="monospace">c</mml:mi>
<mml:mi mathvariant="monospace">o</mml:mi>
<mml:mi mathvariant="monospace">m</mml:mi>
<mml:mi mathvariant="monospace">m</mml:mi>
<mml:mi mathvariant="monospace">a</mml:mi>
<mml:mi mathvariant="monospace">n</mml:mi>
<mml:mi mathvariant="monospace">d</mml:mi>
<mml:mi mathvariant="monospace">s</mml:mi>
<mml:mo>&#x3e;</mml:mo>
</mml:math>
</inline-formula> <sans-serif>else</sans-serif> <inline-formula id="inf12">
<mml:math id="m18">
<mml:mo>&#x3c;</mml:mo>
<mml:mi mathvariant="monospace">s</mml:mi>
<mml:mi mathvariant="monospace">o</mml:mi>
<mml:mi mathvariant="monospace">m</mml:mi>
<mml:mi mathvariant="monospace">e</mml:mi>
<mml:mi mathvariant="monospace">o</mml:mi>
<mml:mi mathvariant="monospace">t</mml:mi>
<mml:mi mathvariant="monospace">h</mml:mi>
<mml:mi mathvariant="monospace">e</mml:mi>
<mml:mi mathvariant="monospace">r</mml:mi>
<mml:mi mathvariant="monospace">c</mml:mi>
<mml:mi mathvariant="monospace">o</mml:mi>
<mml:mi mathvariant="monospace">m</mml:mi>
<mml:mi mathvariant="monospace">m</mml:mi>
<mml:mi mathvariant="monospace">a</mml:mi>
<mml:mi mathvariant="monospace">n</mml:mi>
<mml:mi mathvariant="monospace">d</mml:mi>
<mml:mi mathvariant="monospace">s</mml:mi>
<mml:mo>&#x3e;</mml:mo>
</mml:math>
</inline-formula> <sans-serif>end_if</sans-serif>,</p>
<p>we need to determine the correct block of commands to be executed while reading the script from left to right. We achieve this by including an extra stack, called the <italic>control stack</italic>, which is denoted by <italic>&#x3c6;</italic>
<sub>
<italic>I</italic>
</sub>. Intuitively, the control stack allows us to decide whether an operator is outside an if-then-else block, in which case it is executed as usual, or whether it belongs to some of the commands within this if-then-else block, in which case we need to make sure that only the operators from the appropriate block are being executed.</p>
<p>The control stack <italic>&#x3c6;</italic>
<sub>
<italic>I</italic>
</sub> consist of zeros and ones exclusively, that is, <italic>&#x3c6;</italic>
<sub>
<italic>I</italic>
</sub> &#x2208; {0,1}<sup>&#x2217;</sup>. A control stack <italic>&#x3c6;</italic>
<sub>
<italic>I</italic>
</sub> is said to represent an <italic>execution state</italic> if <italic>&#x3c6;</italic>
<sub>
<italic>I</italic>
</sub> &#x2208; {1}<sup>&#x2217;</sup>, which indicates that the command we are seeing has to be executed (in this case, this will be a command within the if-then-else block). Similarly, an empty control stack indicates that we are outside the if-then-else portion of the script, and should therefore execute the operator.</p>
<p>Working with an additional stack also requires to redefine the semantics of all other commands that we outlined in the previous sections, to allow us to work with them in case flow control operators are present in the script. We do this in the expected way: all previous operators are only executed when the control stack is in an execution state. That is, for every Script operator <italic>f</italic>&#x20;&#x2208; <italic>O</italic>, <xref ref-type="disp-formula" rid="e1">Eq. 1</xref> should be replaced by the following:<disp-formula id="e2">
<mml:math id="m19">
<mml:mi>f</mml:mi>
<mml:mo>:</mml:mo>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msup>
<mml:mrow>
<mml:mi mathvariant="double-struck">Z</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mo>&#x2217;</mml:mo>
</mml:mrow>
</mml:msup>
<mml:mo>&#xd7;</mml:mo>
<mml:msup>
<mml:mrow>
<mml:mi mathvariant="double-struck">Z</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mo>&#x2217;</mml:mo>
</mml:mrow>
</mml:msup>
<mml:mo>&#xd7;</mml:mo>
<mml:msup>
<mml:mrow>
<mml:mrow>
<mml:mo stretchy="false">{</mml:mo>
<mml:mrow>
<mml:mn>0,1</mml:mn>
</mml:mrow>
<mml:mo stretchy="false">}</mml:mo>
</mml:mrow>
</mml:mrow>
<mml:mrow>
<mml:mo>&#x2217;</mml:mo>
</mml:mrow>
</mml:msup>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x222a;</mml:mo>
<mml:mrow>
<mml:mo stretchy="false">{</mml:mo>
<mml:mrow>
<mml:mo>&#x25a1;</mml:mo>
</mml:mrow>
<mml:mo stretchy="false">}</mml:mo>
</mml:mrow>
<mml:mo>&#x2192;</mml:mo>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msup>
<mml:mrow>
<mml:mi mathvariant="double-struck">Z</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mo>&#x2217;</mml:mo>
</mml:mrow>
</mml:msup>
<mml:mo>&#xd7;</mml:mo>
<mml:msup>
<mml:mrow>
<mml:mi mathvariant="double-struck">Z</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mo>&#x2217;</mml:mo>
</mml:mrow>
</mml:msup>
<mml:mo>&#xd7;</mml:mo>
<mml:msup>
<mml:mrow>
<mml:mrow>
<mml:mo stretchy="false">{</mml:mo>
<mml:mrow>
<mml:mn>0,1</mml:mn>
</mml:mrow>
<mml:mo stretchy="false">}</mml:mo>
</mml:mrow>
</mml:mrow>
<mml:mrow>
<mml:mo>&#x2217;</mml:mo>
</mml:mrow>
</mml:msup>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x222a;</mml:mo>
<mml:mrow>
<mml:mo stretchy="false">{</mml:mo>
<mml:mrow>
<mml:mo>&#x25a1;</mml:mo>
</mml:mrow>
<mml:mo stretchy="false">}</mml:mo>
</mml:mrow>
<mml:mo>.</mml:mo>
</mml:math>
<label>(2)</label>
</disp-formula>
</p>
<p>Hence, each operator takes as input three stacks: the main stack, the alternate stack and the control stack. The semantics of commands from <xref ref-type="table" rid="T1">Table&#x20;1</xref> is then redefined so that there is a third input, <italic>&#x3c6;</italic>
<sub>
<italic>I</italic>
</sub>, which is also the third output (<italic>&#x3c6;</italic>
<sub>
<italic>I</italic>
</sub> is not changed by the operators in <xref ref-type="table" rid="T1">Table&#x20;1</xref>). Besides, the condition column in <xref ref-type="table" rid="T1">Table&#x20;1</xref> is modified to include the fact that <italic>&#x3c6;</italic>
<sub>
<italic>I</italic>
</sub> represents an execution state (that is, <italic>&#x3c6;</italic>
<sub>
<italic>I</italic>
</sub> &#x2208; {1}&#x2217;). In particular, for each operator <italic>f</italic> in <xref ref-type="table" rid="T1">Table&#x20;1</xref>, if <italic>&#x3c6;</italic>
<sub>
<italic>I</italic>
</sub> is not an execution state, then we have that <italic>f</italic>(<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>, <italic>&#x3c6;</italic>
<sub>
<italic>A</italic>
</sub>, <italic>&#x3c6;</italic>
<sub>
<italic>I</italic>
</sub>) &#x3d; (<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>, <italic>&#x3c6;</italic>
<sub>
<italic>A</italic>
</sub>, <italic>&#x3c6;</italic>
<sub>
<italic>I</italic>
</sub>); namely, the command is not executed. For example, consider again the operation <italic>OP</italic>_<italic>PUSH</italic>
<sub>
<italic>C</italic>
</sub> with <inline-formula id="inf13">
<mml:math id="m20">
<mml:mi>C</mml:mi>
<mml:mo>&#x2208;</mml:mo>
<mml:mi mathvariant="double-struck">Z</mml:mi>
</mml:math>
</inline-formula>. Its semantics, taking now into consideration the control stack, is defined as follows:<disp-formula id="equ6">
<mml:math id="m21">
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:msub>
<mml:mrow>
<mml:mtext mathvariant="normal">PUSH</mml:mtext>
</mml:mrow>
<mml:mrow>
<mml:mi>C</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>I</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x3d;</mml:mo>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mi>C</mml:mi>
<mml:mo>&#x22c5;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>I</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>,</mml:mo>
</mml:math>
</disp-formula>whenever <italic>&#x3c6;</italic>
<sub>
<italic>I</italic>
</sub> is an execution state. When <italic>&#x3c6;</italic>
<sub>
<italic>I</italic>
</sub> is not an execution state, the semantics of this operator is defined as:<disp-formula id="equ7">
<mml:math id="m22">
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:msub>
<mml:mrow>
<mml:mtext mathvariant="normal">PUSH</mml:mtext>
</mml:mrow>
<mml:mrow>
<mml:mi>C</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>I</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x3d;</mml:mo>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>I</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>.</mml:mo>
</mml:math>
</disp-formula>
</p>
<p>The flow control operators <italic>OP</italic>_<italic>IF</italic>, <italic>OP</italic>_<italic>ELSE</italic>, <italic>OP</italic>_<italic>ENDIF</italic> are the only ones that can modify the control&#x20;stack.</p>
<p>Next we explain how they interact with the main and alternate stacks, and also how they modify the control stack. In essence, these three commands come in tandem, and take the form:<disp-formula id="equ8">
<mml:math id="m23">
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:mtext mathvariant="normal">IF</mml:mtext>
<mml:mo>&#x3c;</mml:mo>
<mml:mi mathvariant="monospace">c</mml:mi>
<mml:mi mathvariant="monospace">o</mml:mi>
<mml:mi mathvariant="monospace">m</mml:mi>
<mml:mi mathvariant="monospace">m</mml:mi>
<mml:mi mathvariant="monospace">a</mml:mi>
<mml:mi mathvariant="monospace">n</mml:mi>
<mml:mi mathvariant="monospace">d</mml:mi>
<mml:mi mathvariant="monospace">s</mml:mi>
<mml:mi mathvariant="monospace">1</mml:mi>
<mml:mo>&#x3e;</mml:mo>
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:mtext mathvariant="normal">ELSE</mml:mtext>
<mml:mo>&#x3c;</mml:mo>
<mml:mi mathvariant="monospace">c</mml:mi>
<mml:mi mathvariant="monospace">o</mml:mi>
<mml:mi mathvariant="monospace">m</mml:mi>
<mml:mi mathvariant="monospace">m</mml:mi>
<mml:mi mathvariant="monospace">a</mml:mi>
<mml:mi mathvariant="monospace">n</mml:mi>
<mml:mi mathvariant="monospace">d</mml:mi>
<mml:mi mathvariant="monospace">s</mml:mi>
<mml:mi mathvariant="monospace">2</mml:mi>
<mml:mo>&#x3e;</mml:mo>
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:mtext mathvariant="normal">ENDIF</mml:mtext>
<mml:mo>.</mml:mo>
</mml:math>
</disp-formula>
</p>
<p>Both commands1 and commands2 are sequences of Script commands, which can again contain if-then-else blocks. The objective of the control stack is to signal whether commands1 or commands2 are to be executed, depending on whether the top value of the main stack upon reaching the <italic>OP</italic>_<italic>IF</italic> is true or false. This is achieved by pushing/popping the appropriate value to/from the control stack when either <italic>OP</italic>_<italic>IF</italic> or <italic>OP</italic>_<italic>ELSE</italic> is reached, as to signal which block of commands will be executed. Recall that only a control stack in an execution state allows for a command to be executed, so we will use this property accordingly.</p>
<p>Intuitively, when reaching an <italic>OP</italic>_<italic>IF</italic> statement, we will store the truth value of the top of the main stack onto the control stack. If this was true (or nonzero in our notation), we will push 1 onto the control stack, thus making it be in an execution state. Then, upon reaching its corresponding <italic>OP</italic>_<italic>ELSE</italic>, we will replace the value 1 at the top of the control stack with 0, making it not be in an execution state. This will allow us to skip all the commands until reaching the accompanying <italic>OP</italic>_<italic>ENDIF</italic>, which simply pops the top of the control stack. A similar process occurs when the top value of the main stack upon reaching <italic>OP</italic>_<italic>IF</italic> is false. Notice that if-then-else statements can be nested. However, in a syntactically correct script this is not an issue, as the control stack is populated and cleared as expected. Formally, the semantics of <italic>OP</italic>_<italic>IF</italic> is defined as follows:<disp-formula id="equ9">
<mml:math id="m24">
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:mtext mathvariant="normal">IF</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>I</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x3d;</mml:mo>
<mml:mfenced open="{" close="">
<mml:mrow>
<mml:mtable class="cases">
<mml:mtr>
<mml:mtd columnalign="left">
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mtext mathvariant="normal">tail</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:mn>1</mml:mn>
<mml:mo>&#x22c5;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>I</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mspace width="1em"/>
</mml:mtd>
<mml:mtd columnalign="left">
<mml:mtext>if&#x2009;</mml:mtext>
<mml:mo stretchy="false">&#x7c;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo stretchy="false">&#x7c;</mml:mo>
<mml:mo>&#x2265;</mml:mo>
<mml:mn>1</mml:mn>
<mml:mo>&#x2227;</mml:mo>
<mml:mtext mathvariant="normal">top</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x2260;</mml:mo>
<mml:mn>0</mml:mn>
<mml:mo>&#x2227;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>I</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>&#x2208;</mml:mo>
<mml:msup>
<mml:mrow>
<mml:mrow>
<mml:mo stretchy="false">{</mml:mo>
<mml:mrow>
<mml:mn>1</mml:mn>
</mml:mrow>
<mml:mo stretchy="false">}</mml:mo>
</mml:mrow>
</mml:mrow>
<mml:mrow>
<mml:mo>&#x2217;</mml:mo>
</mml:mrow>
</mml:msup>
</mml:mtd>
</mml:mtr>
<mml:mtr>
<mml:mtd columnalign="left">
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mtext mathvariant="normal">tail</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:mn>0</mml:mn>
<mml:mo>&#x22c5;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>I</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mspace width="1em"/>
</mml:mtd>
<mml:mtd columnalign="left">
<mml:mtext>if&#x2009;</mml:mtext>
<mml:mo stretchy="false">&#x7c;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo stretchy="false">&#x7c;</mml:mo>
<mml:mo>&#x2265;</mml:mo>
<mml:mn>1</mml:mn>
<mml:mo>&#x2227;</mml:mo>
<mml:mtext mathvariant="normal">top</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x3d;</mml:mo>
<mml:mn>0</mml:mn>
<mml:mo>&#x2227;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>I</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>&#x2208;</mml:mo>
<mml:msup>
<mml:mrow>
<mml:mrow>
<mml:mo stretchy="false">{</mml:mo>
<mml:mrow>
<mml:mn>1</mml:mn>
</mml:mrow>
<mml:mo stretchy="false">}</mml:mo>
</mml:mrow>
</mml:mrow>
<mml:mrow>
<mml:mo>&#x2217;</mml:mo>
</mml:mrow>
</mml:msup>
</mml:mtd>
</mml:mtr>
<mml:mtr>
<mml:mtd columnalign="left">
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:mn>0</mml:mn>
<mml:mo>&#x22c5;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>I</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mspace width="1em"/>
</mml:mtd>
<mml:mtd columnalign="left">
<mml:mtext>if&#x2009;</mml:mtext>
<mml:mo stretchy="false">&#x7c;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>I</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo stretchy="false">&#x7c;</mml:mo>
<mml:mo>&#x2265;</mml:mo>
<mml:mn>1</mml:mn>
<mml:mo>&#x2227;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>I</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>&#x2209;</mml:mo>
<mml:msup>
<mml:mrow>
<mml:mrow>
<mml:mo stretchy="false">{</mml:mo>
<mml:mrow>
<mml:mn>1</mml:mn>
</mml:mrow>
<mml:mo stretchy="false">}</mml:mo>
</mml:mrow>
</mml:mrow>
<mml:mrow>
<mml:mo>&#x2217;</mml:mo>
</mml:mrow>
</mml:msup>
</mml:mtd>
</mml:mtr>
</mml:mtable>
</mml:mrow>
</mml:mfenced>
</mml:math>
</disp-formula>
</p>
<p>Moreover, in any other case, <italic>OP</italic>_<italic>IF</italic>(<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>, <italic>&#x3c6;</italic>
<sub>
<italic>A</italic>
</sub>, <italic>&#x3c6;</italic>
<sub>
<italic>I</italic>
</sub>) &#x3d; &#x25a1;. For example, an error is returned if <italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub> is an empty stack, as there is no stack element to ascertain the truth value. Thus, the definition of <sans-serif>OP</sans-serif>_<sans-serif>IF</sans-serif> states that three outcomes are possible upon reaching this operator, under the appropriate conditions not to produce an error: 1) If the top element of the main stack is different from 0 and we are in an execution state, then 1 is pushed onto the control stack, in order to signal that the IF part of the if-then-else block is to be executed. Besides, the main stack is popped. 2) If the top of the main stack is 0, and we are in an execution state, we push 0 onto the control stack (i.e. we do not execute the commands in the IF block, but rather in the ELSE block), and the main stack is popped. 3) Finally, if we are not in an execution state, we push the value 0 to the control stack. The value of the element pushed to the control stack in this last case is not actually relevant because even if an OP_ELSE command where to invert it, the stack would remain in a state of no execution stemming from the existence of one or more 0 elements corresponding to lower if-then-else blocks. However, it is still necessary to track the existence of this new branch, in order to correctly close it once we reach its corresponding OP_ENDIF command.</p>
<p>On the other hand, the OP_ELSE operator simply has to signal whether the commands that follow it are to be executed or not, which is done by changing the top element of the control stack as follows:<disp-formula id="equ10">
<mml:math id="m25">
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:mtext mathvariant="normal">ELSE</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>I</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x3d;</mml:mo>
<mml:mfenced open="{" close="">
<mml:mrow>
<mml:mtable class="cases">
<mml:mtr>
<mml:mtd columnalign="left">
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:mn>1</mml:mn>
<mml:mo>&#x22c5;</mml:mo>
<mml:mtext mathvariant="normal">tail</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>I</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mspace width="1em"/>
</mml:mtd>
<mml:mtd columnalign="left">
<mml:mtext>if&#x2009;</mml:mtext>
<mml:mo stretchy="false">&#x7c;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>I</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo stretchy="false">&#x7c;</mml:mo>
<mml:mo>&#x2265;</mml:mo>
<mml:mn>1</mml:mn>
<mml:mo>&#x2227;</mml:mo>
<mml:mtext mathvariant="normal">top</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>I</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x3d;</mml:mo>
<mml:mn>0</mml:mn>
</mml:mtd>
</mml:mtr>
<mml:mtr>
<mml:mtd columnalign="left">
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:mn>0</mml:mn>
<mml:mo>&#x22c5;</mml:mo>
<mml:mtext mathvariant="normal">tail</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>I</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mspace width="1em"/>
</mml:mtd>
<mml:mtd columnalign="left">
<mml:mtext>if&#x2009;</mml:mtext>
<mml:mo stretchy="false">&#x7c;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>I</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo stretchy="false">&#x7c;</mml:mo>
<mml:mo>&#x2265;</mml:mo>
<mml:mn>1</mml:mn>
<mml:mo>&#x2227;</mml:mo>
<mml:mtext mathvariant="normal">top</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>I</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x3d;</mml:mo>
<mml:mn>1</mml:mn>
</mml:mtd>
</mml:mtr>
</mml:mtable>
</mml:mrow>
</mml:mfenced>
</mml:math>
</disp-formula>
</p>
<p>Moreover, if <italic>&#x3c6;</italic>
<sub>
<italic>I</italic>
</sub> is empty, then the operator <italic>OP</italic>_<italic>ELSE</italic> returns an error, that is, <italic>OP</italic>_<italic>ELSE</italic>(<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>, <italic>&#x3c6;</italic>
<sub>
<italic>A</italic>
</sub>, <italic>&#x3c6;</italic>
<sub>
<italic>I</italic>
</sub>) &#x3d; &#x25a1;. Notice that <sans-serif>OP</sans-serif>_<sans-serif>ELSE</sans-serif> simply flips the top bit in the control stack to signal the transition between the &#x201c;then&#x201d; and the &#x201c;else&#x201d; blocks. As previously stated, in case the top element in the stack is a 0 because the stack was not in an execution state when reaching the corresponding <sans-serif>OP</sans-serif>_<sans-serif>IF</sans-serif> operator, <sans-serif>OP</sans-serif>_<sans-serif>ELSE</sans-serif> will change it to a 1. However, the stack will still not be in an execution state, because there will still exist one or more 0 elements that stem from lower if-then-else blocks. Finally, each if-then-else block is required to be correctly closed <italic>via</italic> the <italic>OP</italic>_<italic>ENDIF</italic> operator. To ensure this, we simply pop the top element of the control stack upon reaching this command:<disp-formula id="equ11">
<mml:math id="m26">
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:mtext mathvariant="normal">ENDIF</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>I</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x3d;</mml:mo>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:mtext mathvariant="normal">tail</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>I</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:math>
</disp-formula>
</p>
<p>Notice that as for the case of <italic>OP</italic>_<italic>ELSE</italic>, if <italic>&#x3c6;</italic>
<sub>
<italic>I</italic>
</sub> is empty, then the operator <italic>OP</italic>_<italic>ENDIF</italic> returns the error symbol &#x25a1;.</p>
<p>It is important to notice that in adding these flow control operators to Script, we introduce more nuance into the definition of a successful execution. More specifically, we now say that a script is <italic>executed successfully</italic> over a stack <italic>&#x3c6;</italic> if upon executing all of its operators with <italic>&#x3c6;</italic> as our initial main stack, we are left not only with a nonempty main stack which contains a nonzero element at the top, but also with an empty control stack. Formally, a script <italic>f</italic>
<sub>1</sub>&#x22c5;<italic>f</italic>
<sub>2</sub>&#x22c5;&#x2026;&#x22c5;<italic>f</italic>
<sub>
<italic>n</italic>
</sub> is executed successfully over a stack <italic>&#x3c6;</italic> if (<italic>f</italic>
<sub>
<italic>n</italic>
</sub>&#x25e6;&#x22ef;&#x25e6;<italic>f</italic>
<sub>2</sub>&#x25e6;<italic>f</italic>
<sub>1</sub>)(<italic>&#x3c6;</italic>, <italic>&#x25b;</italic>, <italic>&#x25b;</italic>) &#x3d; (<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>, <italic>&#x3c6;</italic>
<sub>
<italic>A</italic>
</sub>, <italic>&#x3c6;</italic>
<sub>
<italic>I</italic>
</sub>) with <italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub> &#x2260; <italic>&#x25b;</italic>, <italic>top</italic>(<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>) &#x2260; 0 and <italic>&#x3c6;</italic>
<sub>
<italic>I</italic>
</sub> &#x3d; <italic>&#x25b;</italic>. Conceptually, this new condition requires flow control blocks to be properly structured in Script. In particular, a script that ends with a nonempty control stack has an unfinished if-then-else block, which indicates that it is not well constructed.</p>
<p>As we have explained previously, when executing a pair of an unlocking and a locking script, the process consists of executing the unlocking script over a trio of empty stacks, and then executing the locking script over the final main stack of the previous execution and a pair of empty stacks. However, if after the first execution we are left with a nonempty control stack signaling unfinished if-then-else blocks, then the locking script is simply given an error and the combined execution ends unsuccessfully (see next section for a formal definition of the unlockability of Script problem). Therefore, when executing a pair of an unlocking and a locking script, both executions have to contain properly structured if-then-else blocks.</p>
<p>
<statement content-type="example" id="Example_3_2">
<label>Example 3.2</label>
<p>To illustrate how flow control operators work, consider the following script: <disp-formula id="equ12">
<mml:math id="m27">
<mml:mtable class="align-star" columnalign="left">
<mml:mtr>
<mml:mtd columnalign="right"/>
<mml:mtd columnalign="left">
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:msub>
<mml:mrow>
<mml:mtext mathvariant="normal">PUSH</mml:mtext>
</mml:mrow>
<mml:mrow>
<mml:mn>0</mml:mn>
</mml:mrow>
</mml:msub>
</mml:mtd>
</mml:mtr>
<mml:mtr>
<mml:mtd columnalign="right"/>
<mml:mtd columnalign="left">
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:mtext mathvariant="normal">IF</mml:mtext>
</mml:mtd>
</mml:mtr>
<mml:mtr>
<mml:mtd columnalign="right"/>
<mml:mtd columnalign="left">
<mml:mspace width="2em"/>
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:mtext mathvariant="normal">DUP</mml:mtext>
</mml:mtd>
</mml:mtr>
<mml:mtr>
<mml:mtd columnalign="right"/>
<mml:mtd columnalign="left">
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:mtext mathvariant="normal">ELSE</mml:mtext>
</mml:mtd>
</mml:mtr>
<mml:mtr>
<mml:mtd columnalign="right"/>
<mml:mtd columnalign="left">
<mml:mspace width="2em"/>
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:msub>
<mml:mrow>
<mml:mtext mathvariant="normal">PUSH</mml:mtext>
</mml:mrow>
<mml:mrow>
<mml:mn>3</mml:mn>
</mml:mrow>
</mml:msub>
</mml:mtd>
</mml:mtr>
<mml:mtr>
<mml:mtd columnalign="right"/>
<mml:mtd columnalign="left">
<mml:mspace width="2em"/>
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:mtext mathvariant="normal">IF</mml:mtext>
</mml:mtd>
</mml:mtr>
<mml:mtr>
<mml:mtd columnalign="right"/>
<mml:mtd columnalign="left">
<mml:mspace width="2em"/>
<mml:mspace width="2em"/>
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:msub>
<mml:mrow>
<mml:mtext mathvariant="normal">PUSH</mml:mtext>
</mml:mrow>
<mml:mrow>
<mml:mn>7</mml:mn>
</mml:mrow>
</mml:msub>
</mml:mtd>
</mml:mtr>
<mml:mtr>
<mml:mtd columnalign="right"/>
<mml:mtd columnalign="left">
<mml:mspace width="2em"/>
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:mtext mathvariant="normal">ELSE</mml:mtext>
</mml:mtd>
</mml:mtr>
<mml:mtr>
<mml:mtd columnalign="right"/>
<mml:mtd columnalign="left">
<mml:mspace width="2em"/>
<mml:mspace width="2em"/>
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:mtext mathvariant="normal">DUP</mml:mtext>
</mml:mtd>
</mml:mtr>
<mml:mtr>
<mml:mtd columnalign="right"/>
<mml:mtd columnalign="left">
<mml:mspace width="2em"/>
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:mtext mathvariant="normal">ENDIF</mml:mtext>
</mml:mtd>
</mml:mtr>
<mml:mtr>
<mml:mtd columnalign="right"/>
<mml:mtd columnalign="left">
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:mtext mathvariant="normal">ENDIF</mml:mtext>
</mml:mtd>
</mml:mtr>
</mml:mtable>
</mml:math>
</disp-formula>
</p>
<p>Recall that a script consists of a concatenation of operators, but we have represented this vertically and indented to better illustrate how flow control blocks are nested. When executing this script, value 0 is pushed onto the main stack first (notice that at the beginning the control stack is empty, and we are thus in an execution state), so we have that:<disp-formula id="equ13">
<mml:math id="m28">
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>I</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x3d;</mml:mo>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mn>0</mml:mn>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:math>
</disp-formula>
</p>
<p>Following this, an OP_IF statement is encountered, and the control stack is updated accordingly. In this case, given that we have value 0 on top of the main stack, 0 is pushed onto the control stack, and the main stack is emptied:<disp-formula id="equ14">
<mml:math id="m29">
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>I</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x3d;</mml:mo>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mi>&#x3b5;</mml:mi>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
<mml:mo>,</mml:mo>
<mml:mn>0</mml:mn>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:math>
</disp-formula>
</p>
<p>Since we are not in an execution state, the OP_DUP command is ignored, and we continue with the OP_ELSE operator. Given that the top of the control stack is equal to 0, we replace this value with 1, signaling that the next block of commands is to be executed: <disp-formula id="equ15">
<mml:math id="m30">
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>I</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x3d;</mml:mo>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mi>&#x3b5;</mml:mi>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
<mml:mo>,</mml:mo>
<mml:mn>1</mml:mn>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:math>
</disp-formula>
</p>
<p>The operator OP_PUSH<sub>3</sub> is then executed, so the value 3 is pushed onto the main stack:<disp-formula id="equ16">
<mml:math id="m31">
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>I</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x3d;</mml:mo>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mn>3</mml:mn>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
<mml:mo>,</mml:mo>
<mml:mn>1</mml:mn>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:math>
</disp-formula>
</p>
<p>Afterwards, another OP_IF operator is reached. Since we are in an execution state and value 3 is different from 0, value 3 is popped from the main stack, and 1 is pushed onto the control stack:<disp-formula id="equ17">
<mml:math id="m32">
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>I</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x3d;</mml:mo>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mi>&#x3b5;</mml:mi>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
<mml:mo>,</mml:mo>
<mml:mn>1</mml:mn>
<mml:mo>&#x22c5;</mml:mo>
<mml:mn>1</mml:mn>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:math>
</disp-formula>
</p>
<p>This means that in the next step we push value 7 onto the main stack, when executing the operator OP_PUSH<sub>7</sub>:<disp-formula id="equ18">
<mml:math id="m33">
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>I</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x3d;</mml:mo>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mn>7</mml:mn>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
<mml:mo>,</mml:mo>
<mml:mn>1</mml:mn>
<mml:mo>&#x22c5;</mml:mo>
<mml:mn>1</mml:mn>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:math>
</disp-formula>
</p>
<p>The next operator is OP_ELSE, which switches the value 1 on top of the control stack to 0, which in turn means that we are no longer in an execution state:<disp-formula id="equ19">
<mml:math id="m34">
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>I</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x3d;</mml:mo>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mn>7</mml:mn>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
<mml:mo>,</mml:mo>
<mml:mn>0</mml:mn>
<mml:mo>&#x22c5;</mml:mo>
<mml:mn>1</mml:mn>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:math>
</disp-formula>
</p>
<p>Thus, we need to ignore the following OP_DUP operator, and we need to continue with the OP_ENDIF command. Here the top of the control stack is popped: <disp-formula id="equ20">
<mml:math id="m35">
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>I</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x3d;</mml:mo>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mn>7</mml:mn>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
<mml:mo>,</mml:mo>
<mml:mn>1</mml:mn>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:math>
</disp-formula>
</p>
<p>Finally, the last command OP_ENDIF is executed, leaving the control stack empty, and finishing with value 7 on the main stack:<disp-formula id="equ21">
<mml:math id="m36">
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>I</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x3d;</mml:mo>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mn>7</mml:mn>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:math>
</disp-formula>
</p>
<p>Thus, the script results in a successful execution<italic>.</italic> &#x25a0;</p>
<p>Finally, we comment once again that some flow-control operators have been left out from our formalization. We do this for the sake of readability and because those operators can be simulated with a constant number of other operators. In particular, the operators we do not covered correspond to: <sans-serif>OP_NOP</sans-serif>, which does nothing at all, <sans-serif>OP_NOTIF</sans-serif> which simulates an <sans-serif>OP_IF</sans-serif> but when the value of the top of the stack is false, and <sans-serif>OP_RETURN</sans-serif>, which is used to mark transactions as invalid.</p>
</statement>
</p>
</sec>
</sec>
</sec>
<sec id="s4">
<title>4 Complexity of Script</title>
<p>In this section, we will focus on analyzing the computational cost of working with Script. To draw a complete picture, we start by formally defining in <xref ref-type="sec" rid="s4-1">Section 4.1</xref> the evaluation and unlockability problems for this language. Then in <xref ref-type="sec" rid="s4-2">Section 4.2</xref>, we provide a formal proof for the folklore result that evaluating a pair of unlocking and locking scripts can be done in polynomial time for the set of Script operators currently in use (<xref ref-type="bibr" rid="B9">Bitcoin Wiki, 2021</xref>). We also highlight that the original implementation of Script contained some operators that actually allowed for the construction of programs that run in exponential time in the length of the script, so the disabling of these is well justified. Moreover, we show in <xref ref-type="sec" rid="s4-3">Section 4.3</xref> that the situation with the unlockability problem is completely different, as this problem is shown to be NP-hard. It is important to mention that this latter result is proved by combining some of the simplest operators in Script, and, in particular, without relaying on any of the cryptographic operators in the language. Hence, this result is a warning that the unlockability problem can become difficult even if some simple operators are&#x20;used.</p>
<sec id="s4-1">
<title>4.1 The Evaluation and Unlockability Problems</title>
<p>The evaluation problem for Script is defined as follows:</p>
<table-wrap id="udT1" position="float">
<table>
<tbody valign="top">
<tr>
<td align="left">
<sc>Problem</sc>
</td>
<td align="left">
<sc>Evaluation of Script</sc>
</td>
</tr>
<tr>
<td align="left">
<sc>Input</sc>
</td>
<td align="left">A locking script <italic>l</italic> and an unlocking script <italic>u</italic>
</td>
</tr>
<tr>
<td align="left">
<sc>Question</sc>
</td>
<td align="left">Are the following executions successful</td>
</tr>
<tr>
<td align="left"/>
<td align="left">(i) <inline-formula id="inf14">
<mml:math id="m37">
<mml:mi>u</mml:mi>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mi>&#x3b5;</mml:mi>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x3d;</mml:mo>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msubsup>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>u</mml:mi>
</mml:mrow>
</mml:msubsup>
<mml:mo>,</mml:mo>
<mml:msubsup>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>u</mml:mi>
</mml:mrow>
</mml:msubsup>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:math>
</inline-formula>; and</td>
</tr>
<tr>
<td align="left"/>
<td align="left">(ii) <inline-formula id="inf15">
<mml:math id="m38">
<mml:mi>l</mml:mi>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msubsup>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>u</mml:mi>
</mml:mrow>
</mml:msubsup>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:math>
</inline-formula>?</td>
</tr>
</tbody>
</table>
</table-wrap>
<p>As explained in <xref ref-type="sec" rid="s2">Section 2</xref>, the unlocking script <italic>u</italic>, and the locking script <italic>l</italic> are executed separately in order to strengthen the security of Script. That is, we first run the unlocking script with a triple of empty stacks. Provided that this execution is successful, the content of the main stack at the end of this execution, denoted by <inline-formula id="inf16">
<mml:math id="m39">
<mml:msubsup>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>u</mml:mi>
</mml:mrow>
</mml:msubsup>
</mml:math>
</inline-formula>, is transferred to the locking script, whose execution starts with an empty alternate stack and an empty control stack. In fact, as per the current specification (<xref ref-type="bibr" rid="B9">Bitcoin Wiki, 2021</xref>), and implementation (<xref ref-type="bibr" rid="B13">Github, 2010</xref>) of Script, the alternate stack content is erased when starting the execution of the locking script. Recall from <xref ref-type="sec" rid="s3">Section 3</xref> the fact that a successful execution also requires the script to start and finish with an empty control stack, to validate that flow control commands are properly nested and completed within both the locking and the unlocking script. From now on, when the answer to the previous question is positive, then we say that the pair of scripts <italic>u</italic> and <italic>l</italic> executes successfully.</p>
<p>Moreover, the unlockability of Script problem is defined as follows:</p>
<table-wrap id="udT2" position="float">
<table>
<tbody valign="top">
<tr>
<td align="left">
<sc>Problem</sc>
</td>
<td align="left">
<sc>Unlockability of Script</sc>
</td>
</tr>
<tr>
<td align="left">
<sc>Input</sc>
</td>
<td align="left">A locking script <italic>l</italic>
</td>
</tr>
<tr>
<td align="left">
<sc>Question</sc>
</td>
<td align="left">Is there an unlocking script <italic>u</italic>, such that <italic>l</italic> and <italic>u</italic>, when given as inputs to the <sc>Evaluation of Script</sc> problem result in a positive answer?</td>
</tr>
</tbody>
</table>
</table-wrap>
</sec>
<sec id="s4-2">
<title>4.2 On the Complexity of the Evaluation Problem</title>
<p>While the main objective of this paper is studying unlockability of Script, we will start by proving the folklore result saying that any script can be evaluated in polynomial time. We do this to show that our formalization of Script conforms with the intuitive understanding of the language. It is important to note that if we were to add some simple operators to Script that may seem unassuming, this property could cease to be true. In fact, previous versions of the language were able to produce scripts that could not be evaluated in polynomial time. To illustrate this notion we introduce the currently disabled <sans-serif>O</sans-serif>
<sans-serif>P</sans-serif>_<sans-serif>MUL</sans-serif> operator. Let <inline-formula id="inf17">
<mml:math id="m40">
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>&#x3d;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mn>0</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mo>&#x22c5;</mml:mo>
<mml:mo>&#x2026;</mml:mo>
<mml:mo>&#x22c5;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>k</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>&#x2208;</mml:mo>
<mml:msup>
<mml:mrow>
<mml:mi mathvariant="double-struck">Z</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mo>&#x2217;</mml:mo>
</mml:mrow>
</mml:msup>
</mml:math>
</inline-formula> and <italic>&#x3c6;</italic>
<sub>
<italic>I</italic>
</sub> &#x2208; {1}&#x2217;. We define the semantics of <sans-serif>OP</sans-serif>_<sans-serif>MUL</sans-serif> as follows. If &#x7c;<italic>&#x3c6;</italic>
<sub>
<italic>M</italic>
</sub>&#x7c;&#x2265; 2, then<disp-formula id="equ22">
<mml:math id="m41">
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:mtext mathvariant="normal">MUL</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>I</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x3d;</mml:mo>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mn>0</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mo>&#x2217;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mn>1</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mo>&#x22c5;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mn>2</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mo>&#x22c5;</mml:mo>
<mml:mo>&#x2026;</mml:mo>
<mml:mo>&#x22c5;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>k</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>I</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>,</mml:mo>
</mml:math>
</disp-formula>where &#x2217; signifies the multiplication of integer numbers. Now we can prove that using <sans-serif>OP</sans-serif>_<sans-serif>MUL</sans-serif> we can create scripts that can not be evaluated in polynomial time. The following lemma gives an insight as to how this is possible.</p>
<p>
<statement content-type="lemma" id="Lemma_4_1">
<label>Lemma 4.1</label>
<p>There exists a script <inline-formula id="inf18">
<mml:math id="m42">
<mml:mi>S</mml:mi>
<mml:mo>&#x3d;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>f</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mn>0</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mo>&#x22c5;</mml:mo>
<mml:mo>&#x2026;</mml:mo>
<mml:mo>&#x22c5;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>f</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>n</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>&#x2208;</mml:mo>
<mml:msup>
<mml:mrow>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mrow>
<mml:mo stretchy="false">{</mml:mo>
<mml:mrow>
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:msub>
<mml:mrow>
<mml:mtext mathvariant="normal">PUSH</mml:mtext>
</mml:mrow>
<mml:mrow>
<mml:mn>2</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:mtext mathvariant="normal">MUL</mml:mtext>
<mml:mo>,</mml:mo>
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:mtext mathvariant="normal">DUP</mml:mtext>
</mml:mrow>
<mml:mo stretchy="false">}</mml:mo>
</mml:mrow>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:mrow>
<mml:mrow>
<mml:mo>&#x2217;</mml:mo>
</mml:mrow>
</mml:msup>
</mml:math>
</inline-formula>
<italic>, such that</italic>
<disp-formula id="equ23">
<mml:math id="m43">
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>f</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>n</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>&#x25e6;</mml:mo>
<mml:mo>&#x2026;</mml:mo>
<mml:mo>&#x25e6;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>f</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mn>0</mml:mn>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mi>&#x3b5;</mml:mi>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x3d;</mml:mo>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mi>A</mml:mi>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:math>
</disp-formula>and <inline-formula id="inf19">
<mml:math id="m44">
<mml:mi>A</mml:mi>
<mml:mo>&#x2265;</mml:mo>
<mml:msup>
<mml:mrow>
<mml:mn>2</mml:mn>
</mml:mrow>
<mml:mrow>
<mml:msup>
<mml:mrow>
<mml:mn>2</mml:mn>
</mml:mrow>
<mml:mrow>
<mml:mtext>cn</mml:mtext>
</mml:mrow>
</mml:msup>
</mml:mrow>
</mml:msup>
</mml:math>
</inline-formula>, for some c &#x3e;&#x20;0.</p>
</statement>
</p>
<p>
<statement content-type="proof" id="uProof_1">
<label>Proof</label>
<p>For this, consider the script<disp-formula id="equ24">
<mml:math id="m45">
<mml:mi>S</mml:mi>
<mml:mo>&#x3d;</mml:mo>
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:msub>
<mml:mrow>
<mml:mtext mathvariant="normal">PUSH</mml:mtext>
</mml:mrow>
<mml:mrow>
<mml:mn>2</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mo>&#x22c5;</mml:mo>
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:mtext mathvariant="normal">DUP</mml:mtext>
<mml:mo>&#x22c5;</mml:mo>
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:mtext mathvariant="normal">MUL</mml:mtext>
<mml:mo>&#x22c5;</mml:mo>
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:mtext mathvariant="normal">DUP</mml:mtext>
<mml:mo>&#x22c5;</mml:mo>
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:mtext mathvariant="normal">MUL</mml:mtext>
<mml:mo>&#x22c5;</mml:mo>
<mml:mo>&#x2026;</mml:mo>
<mml:mo>&#x22c5;</mml:mo>
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:mtext mathvariant="normal">DUP</mml:mtext>
<mml:mo>&#x22c5;</mml:mo>
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:mtext mathvariant="normal">MUL</mml:mtext>
<mml:mo>.</mml:mo>
</mml:math>
</disp-formula>
</p>
<p>The main idea of the proof is that this script will end its execution with <inline-formula id="inf20">
<mml:math id="m46">
<mml:msup>
<mml:mrow>
<mml:mn>2</mml:mn>
</mml:mrow>
<mml:mrow>
<mml:msup>
<mml:mrow>
<mml:mn>2</mml:mn>
</mml:mrow>
<mml:mrow>
<mml:mi>m</mml:mi>
</mml:mrow>
</mml:msup>
</mml:mrow>
</mml:msup>
</mml:math>
</inline-formula> at the top of the main stack, where m is the number of repetitions of the OP_DUP&#x22c5;OP_MUL sequence of operators.</p>
<p>More formally, let <inline-formula id="inf21">
<mml:math id="m47">
<mml:mi>m</mml:mi>
<mml:mo>&#x2208;</mml:mo>
<mml:mi mathvariant="double-struck">N</mml:mi>
</mml:math>
</inline-formula> be an arbitrary number and S<sub>m</sub> &#x3d; OP_PUSH<sub>2</sub>&#x22c5;(OP_DUP&#x22c5;OP_MUL)<sup>m</sup>. Then:<disp-formula id="equ25">
<mml:math id="m48">
<mml:msub>
<mml:mrow>
<mml:mi>S</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>m</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mi>&#x3b5;</mml:mi>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x3d;</mml:mo>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msup>
<mml:mrow>
<mml:mn>2</mml:mn>
</mml:mrow>
<mml:mrow>
<mml:msup>
<mml:mrow>
<mml:mn>2</mml:mn>
</mml:mrow>
<mml:mrow>
<mml:mi>m</mml:mi>
</mml:mrow>
</mml:msup>
</mml:mrow>
</mml:msup>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>.</mml:mo>
</mml:math>
</disp-formula>
</p>
<p>This can be easily shown by mathematical induction on&#x20;m.</p>
<p>Base case. Consider S<sub>0</sub> &#x3d; OP_PUSH<sub>2</sub>. Then we trivially have<disp-formula id="equ26">
<mml:math id="m49">
<mml:msub>
<mml:mrow>
<mml:mi>S</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mn>0</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mi>&#x3b5;</mml:mi>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x3d;</mml:mo>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mn>2</mml:mn>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x3d;</mml:mo>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msup>
<mml:mrow>
<mml:mn>2</mml:mn>
</mml:mrow>
<mml:mrow>
<mml:mn>1</mml:mn>
</mml:mrow>
</mml:msup>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x3d;</mml:mo>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msup>
<mml:mrow>
<mml:mn>2</mml:mn>
</mml:mrow>
<mml:mrow>
<mml:msup>
<mml:mrow>
<mml:mn>2</mml:mn>
</mml:mrow>
<mml:mrow>
<mml:mn>0</mml:mn>
</mml:mrow>
</mml:msup>
</mml:mrow>
</mml:msup>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>.</mml:mo>
</mml:math>
</disp-formula>
</p>
<p>Inductive step. Suppose that for an arbitrary number <inline-formula id="inf22">
<mml:math id="m50">
<mml:mi>i</mml:mi>
<mml:mo>&#x2208;</mml:mo>
<mml:mi mathvariant="double-struck">N</mml:mi>
</mml:math>
</inline-formula>, we have that <inline-formula id="inf23">
<mml:math id="m51">
<mml:msub>
<mml:mrow>
<mml:mi>S</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>i</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mi>&#x3b5;</mml:mi>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x3d;</mml:mo>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msup>
<mml:mrow>
<mml:mn>2</mml:mn>
</mml:mrow>
<mml:mrow>
<mml:msup>
<mml:mrow>
<mml:mn>2</mml:mn>
</mml:mrow>
<mml:mrow>
<mml:mi>i</mml:mi>
</mml:mrow>
</mml:msup>
</mml:mrow>
</mml:msup>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:math>
</inline-formula>. Now, we can note that S<sub>i&#x2b;1</sub> &#x3d; S<sub>i</sub>&#x22c5;(OP_DUP&#x22c5;OP_MUL). Thus, we have that<disp-formula id="equ27">
<mml:math id="m52">
<mml:mtable class="eqnarray-star">
<mml:mtr>
<mml:mtd columnalign="right">
<mml:msub>
<mml:mrow>
<mml:mi>S</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>i</mml:mi>
<mml:mo>&#x2b;</mml:mo>
<mml:mn>1</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mi>&#x3b5;</mml:mi>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:mtd>
<mml:mtd columnalign="left">
<mml:mo>&#x3d;</mml:mo>
</mml:mtd>
<mml:mtd columnalign="left">
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:mtext mathvariant="normal">MUL</mml:mtext>
<mml:mo>&#x25e6;</mml:mo>
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:mtext mathvariant="normal">DUP</mml:mtext>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>S</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>i</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mi>&#x3b5;</mml:mi>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:mtd>
</mml:mtr>
<mml:mtr>
<mml:mtd columnalign="right"/>
<mml:mtd columnalign="left">
<mml:mo>&#x3d;</mml:mo>
</mml:mtd>
<mml:mtd columnalign="left">
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:mtext mathvariant="normal">MUL</mml:mtext>
<mml:mo>&#x25e6;</mml:mo>
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:mtext mathvariant="normal">DUP</mml:mtext>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msup>
<mml:mrow>
<mml:mn>2</mml:mn>
</mml:mrow>
<mml:mrow>
<mml:msup>
<mml:mrow>
<mml:mn>2</mml:mn>
</mml:mrow>
<mml:mrow>
<mml:mi>i</mml:mi>
</mml:mrow>
</mml:msup>
</mml:mrow>
</mml:msup>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:mtd>
</mml:mtr>
<mml:mtr>
<mml:mtd columnalign="right"/>
<mml:mtd columnalign="left">
<mml:mo>&#x3d;</mml:mo>
</mml:mtd>
<mml:mtd columnalign="left">
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msup>
<mml:mrow>
<mml:mn>2</mml:mn>
</mml:mrow>
<mml:mrow>
<mml:msup>
<mml:mrow>
<mml:mn>2</mml:mn>
</mml:mrow>
<mml:mrow>
<mml:mi>i</mml:mi>
</mml:mrow>
</mml:msup>
</mml:mrow>
</mml:msup>
<mml:mo>&#x2217;</mml:mo>
<mml:msup>
<mml:mrow>
<mml:mn>2</mml:mn>
</mml:mrow>
<mml:mrow>
<mml:msup>
<mml:mrow>
<mml:mn>2</mml:mn>
</mml:mrow>
<mml:mrow>
<mml:mi>i</mml:mi>
</mml:mrow>
</mml:msup>
</mml:mrow>
</mml:msup>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:mtd>
</mml:mtr>
<mml:mtr>
<mml:mtd columnalign="right"/>
<mml:mtd columnalign="left">
<mml:mo>&#x3d;</mml:mo>
</mml:mtd>
<mml:mtd columnalign="left">
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msup>
<mml:mrow>
<mml:mn>2</mml:mn>
</mml:mrow>
<mml:mrow>
<mml:msup>
<mml:mrow>
<mml:mn>2</mml:mn>
</mml:mrow>
<mml:mrow>
<mml:mi>i</mml:mi>
<mml:mo>&#x2b;</mml:mo>
<mml:mn>1</mml:mn>
</mml:mrow>
</mml:msup>
</mml:mrow>
</mml:msup>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>.</mml:mo>
</mml:mtd>
</mml:mtr>
</mml:mtable>
</mml:math>
</disp-formula>
</p>
<p>From <xref ref-type="statement" rid="Lemma_4_1">Lemma 4.1</xref> we can conclude that it is possible to construct a stack that has an element that is double exponential in magnitude and therefore exponential in size compared to the amount of operators in the script that is being executed<xref ref-type="fn" rid="FN5">
<sup>5</sup>
</xref>. Moreover, as each used operator is constant in size, the size of the constructed element is also exponential in the size of the script. This means that it is not possible to write, save or use such an element in polynomial time compared to the size of our script. Thus, such a script could not be evaluated in polynomial time. A similar result can be obtained for some other operators that were supported in the original proposal of Script, such as for instance <sans-serif>OP_CAT</sans-serif>. In light of this result, disabling some operators seems well justified [see (<xref ref-type="bibr" rid="B9">Bitcoin Wiki, 2021</xref>) for the full list of disabled operators].</p>
<p>Taking this result into consideration, it is important to prove that with the current definition of Script, any script can be evaluated in polynomial time. Letting Ptime be the class of problems that can be solved in polynomial time, we have the following:</p>
</statement>
</p>
<p>
<statement content-type="theorem" id="Theorem_4_2">
<label>Theorem 4.2</label>
<p>The problem Evaluation of Script is in Ptime.</p>
</statement>
</p>
<p>
<statement content-type="proof" id="uProof_2">
<label>Proof</label>
<p>The proof proceeds in four steps. First, we show that Script operators, by themselves, do not introduce transformations that produce drastic changes in the stack. We then show that this remains true when analyzing sequences of operators. This, in turn, allows us to show that the execution time of a script over an empty stack is actually in polynomial time, from which the proof of this theorem readily follows.</p>
<p>We start by defining three auxiliary functions that will help us establish some properties over the execution of operators: function <inline-formula id="inf24">
<mml:math id="m53">
<mml:mtext mathvariant="normal">maxelem</mml:mtext>
<mml:mo>:</mml:mo>
<mml:msup>
<mml:mrow>
<mml:mi mathvariant="double-struck">Z</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mo>&#x2217;</mml:mo>
</mml:mrow>
</mml:msup>
<mml:mo>&#xd7;</mml:mo>
<mml:msup>
<mml:mrow>
<mml:mi mathvariant="double-struck">Z</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mo>&#x2217;</mml:mo>
</mml:mrow>
</mml:msup>
<mml:mo>&#x2192;</mml:mo>
<mml:mi mathvariant="double-struck">N</mml:mi>
</mml:math>
</inline-formula> obtains the size of the biggest element in a stack (independent of its sign), function <inline-formula id="inf25">
<mml:math id="m54">
<mml:mtext mathvariant="normal">elemnr</mml:mtext>
<mml:mo>:</mml:mo>
<mml:msup>
<mml:mrow>
<mml:mi mathvariant="double-struck">Z</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mo>&#x2217;</mml:mo>
</mml:mrow>
</mml:msup>
<mml:mo>&#x2192;</mml:mo>
<mml:mi mathvariant="double-struck">N</mml:mi>
</mml:math>
</inline-formula> obtains the amount of elements in a stack, and <inline-formula id="inf26">
<mml:math id="m55">
<mml:mtext mathvariant="normal">maxpush</mml:mtext>
<mml:mo>:</mml:mo>
<mml:msup>
<mml:mrow>
<mml:mi>O</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mo>&#x2217;</mml:mo>
</mml:mrow>
</mml:msup>
<mml:mo>&#x2192;</mml:mo>
<mml:mi mathvariant="double-struck">N</mml:mi>
</mml:math>
</inline-formula> provides the maximum element pushed by a script, independent of its&#x20;sign.</p>
<p>Let S &#x3d; f<sub>0</sub>&#x22c5;&#x2026;&#x22c5;f<sub>n</sub> &#x2208; O&#x2217;, <inline-formula id="inf27">
<mml:math id="m56">
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>&#x3d;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mn>0</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mo>&#x22c5;</mml:mo>
<mml:mo>&#x2026;</mml:mo>
<mml:mo>&#x22c5;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>k</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>&#x2208;</mml:mo>
<mml:msup>
<mml:mrow>
<mml:mi mathvariant="double-struck">Z</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mo>&#x2217;</mml:mo>
</mml:mrow>
</mml:msup>
</mml:math>
</inline-formula> and <inline-formula id="inf28">
<mml:math id="m57">
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>&#x3d;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>B</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mn>0</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mo>&#x22c5;</mml:mo>
<mml:mo>&#x2026;</mml:mo>
<mml:mo>&#x22c5;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>B</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>&#x2113;</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>&#x2208;</mml:mo>
<mml:msup>
<mml:mrow>
<mml:mi mathvariant="double-struck">Z</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mo>&#x2217;</mml:mo>
</mml:mrow>
</mml:msup>
</mml:math>
</inline-formula>. We define the values of these functions as follows;<disp-formula id="equ28">
<mml:math id="m58">
<mml:mtable class="eqnarray-star">
<mml:mtr>
<mml:mtd columnalign="right">
<mml:mtext mathvariant="normal">maxelem</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:mtd>
<mml:mtd columnalign="left">
<mml:mo>&#x3d;</mml:mo>
</mml:mtd>
<mml:mtd columnalign="left">
<mml:munder>
<mml:mrow>
<mml:mi>max</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
<mml:mo>&#x2208;</mml:mo>
<mml:mrow>
<mml:mo stretchy="false">{</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mn>0</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:mo>&#x2026;</mml:mo>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>k</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">}</mml:mo>
</mml:mrow>
<mml:mo>&#x222a;</mml:mo>
<mml:mrow>
<mml:mo stretchy="false">{</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>B</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mn>0</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:mo>&#x2026;</mml:mo>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>B</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>&#x2113;</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">}</mml:mo>
</mml:mrow>
</mml:mrow>
</mml:munder>
<mml:mo stretchy="false">&#x7c;</mml:mo>
<mml:mi>A</mml:mi>
<mml:mo stretchy="false">&#x7c;</mml:mo>
</mml:mtd>
</mml:mtr>
<mml:mtr>
<mml:mtd columnalign="right">
<mml:mtext mathvariant="normal">elemnr</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:mtd>
<mml:mtd columnalign="left">
<mml:mo>&#x3d;</mml:mo>
</mml:mtd>
<mml:mtd columnalign="left">
<mml:mi>k</mml:mi>
<mml:mo>&#x2b;</mml:mo>
<mml:mn>1</mml:mn>
</mml:mtd>
</mml:mtr>
<mml:mtr>
<mml:mtd columnalign="right">
<mml:mtext mathvariant="normal">maxpush</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mi>S</mml:mi>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:mtd>
<mml:mtd columnalign="left">
<mml:mo>&#x3d;</mml:mo>
</mml:mtd>
<mml:mtd columnalign="left">
<mml:mi>max</mml:mi>
<mml:mrow>
<mml:mo stretchy="false">{</mml:mo>
<mml:mrow>
<mml:mo stretchy="false">&#x7c;</mml:mo>
<mml:mi>C</mml:mi>
<mml:mo stretchy="false">&#x7c;</mml:mo>
<mml:mo>:</mml:mo>
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:msub>
<mml:mrow>
<mml:mtext mathvariant="normal">PUSH</mml:mtext>
</mml:mrow>
<mml:mrow>
<mml:mi>C</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>&#x2208;</mml:mo>
<mml:mrow>
<mml:mo stretchy="false">{</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>f</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mn>0</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:mo>&#x2026;</mml:mo>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>f</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>n</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">}</mml:mo>
</mml:mrow>
</mml:mrow>
<mml:mo stretchy="false">}</mml:mo>
</mml:mrow>
</mml:mtd>
</mml:mtr>
</mml:mtable>
</mml:math>
</disp-formula>
</p>
<p>As the reader might have already noticed, empty stacks provides for edge cases in which maxelem is not defined, and likewise for maxpush, and so they must be accounted for separately. To that extent, let S&#x2032; &#x3d; g<sub>0</sub>&#x22c5;&#x2026;&#x22c5;g<sub>m</sub> &#x2208; O&#x2217; such that <inline-formula id="inf29">
<mml:math id="m59">
<mml:mrow>
<mml:mo stretchy="false">{</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>g</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mn>0</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:mo>&#x2026;</mml:mo>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>g</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>m</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">}</mml:mo>
</mml:mrow>
<mml:mo>&#x2229;</mml:mo>
<mml:mrow>
<mml:mo stretchy="false">{</mml:mo>
<mml:mrow>
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:msub>
<mml:mrow>
<mml:mtext mathvariant="normal">PUSH</mml:mtext>
</mml:mrow>
<mml:mrow>
<mml:mi>C</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo stretchy="false">&#x2223;</mml:mo>
<mml:mi>C</mml:mi>
<mml:mo>&#x2208;</mml:mo>
<mml:mi mathvariant="double-struck">Z</mml:mi>
</mml:mrow>
<mml:mo stretchy="false">}</mml:mo>
</mml:mrow>
<mml:mo>&#x3d;</mml:mo>
<mml:mi>&#x2205;</mml:mi>
</mml:math>
</inline-formula>. Then we have that:<disp-formula id="equ29">
<mml:math id="m60">
<mml:mtable class="eqnarray-star">
<mml:mtr>
<mml:mtd columnalign="right">
<mml:mtext mathvariant="normal">maxelem</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mi>&#x3b5;</mml:mi>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:mtd>
<mml:mtd columnalign="left">
<mml:mo>&#x3d;</mml:mo>
</mml:mtd>
<mml:mtd columnalign="left">
<mml:mn>0</mml:mn>
</mml:mtd>
</mml:mtr>
<mml:mtr>
<mml:mtd columnalign="right">
<mml:mtext mathvariant="normal">maxpush</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mrow>
<mml:mi>S</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mo>&#x2032;</mml:mo>
</mml:mrow>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:mtd>
<mml:mtd columnalign="left">
<mml:mo>&#x3d;</mml:mo>
</mml:mtd>
<mml:mtd columnalign="left">
<mml:mn>0</mml:mn>
</mml:mtd>
</mml:mtr>
</mml:mtable>
</mml:math>
</disp-formula>
</p>
<p>As we mentioned in our proof strategy, our first task is to show that none of the operators in Script produces a stack that explodes in size. In formal terms, this translates to restrictions for the auxiliary functions introduced previously.</p>
</statement>
</p>
<p>
<statement content-type="lemma" id="Lemma_4_3">
<label>Lemma 4.3</label>
<p>Let f &#x2208; O, <inline-formula id="inf30">
<mml:math id="m61">
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>&#x2208;</mml:mo>
<mml:msup>
<mml:mrow>
<mml:mi mathvariant="double-struck">Z</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mo>&#x2217;</mml:mo>
</mml:mrow>
</mml:msup>
</mml:math>
</inline-formula>, <inline-formula id="inf31">
<mml:math id="m62">
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>&#x2208;</mml:mo>
<mml:msup>
<mml:mrow>
<mml:mi mathvariant="double-struck">Z</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mo>&#x2217;</mml:mo>
</mml:mrow>
</mml:msup>
</mml:math>
</inline-formula> and &#x3c6;<sub>I</sub> &#x2208; {0,1}&#x2217; such that <inline-formula id="inf32">
<mml:math id="m63">
<mml:mi>f</mml:mi>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>I</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x3d;</mml:mo>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msubsup>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mo>&#x2032;</mml:mo>
</mml:mrow>
</mml:msubsup>
<mml:mo>,</mml:mo>
<mml:msubsup>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mo>&#x2032;</mml:mo>
</mml:mrow>
</mml:msubsup>
<mml:mo>,</mml:mo>
<mml:msubsup>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>I</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mo>&#x2032;</mml:mo>
</mml:mrow>
</mml:msubsup>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:math>
</inline-formula>. Then we have that:<disp-formula id="equ30">
<mml:math id="m64">
<mml:mtext mathvariant="normal">elemnr</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msubsup>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mo>&#x2032;</mml:mo>
</mml:mrow>
</mml:msubsup>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x2264;</mml:mo>
<mml:mtext mathvariant="normal">elemnr</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x2b;</mml:mo>
<mml:mn>3</mml:mn>
</mml:math>
</disp-formula>
</p>
<p>Moreover, assume that <inline-formula id="inf33">
<mml:math id="m65">
<mml:mi>f</mml:mi>
<mml:mo>&#x2209;</mml:mo>
<mml:mrow>
<mml:mo stretchy="false">{</mml:mo>
<mml:mrow>
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:mtext mathvariant="normal">DEPTH</mml:mtext>
<mml:mo>,</mml:mo>
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:mtext mathvariant="normal">HASH</mml:mtext>
<mml:mn>160</mml:mn>
</mml:mrow>
<mml:mo stretchy="false">}</mml:mo>
</mml:mrow>
<mml:mo>&#x222a;</mml:mo>
<mml:mrow>
<mml:mo stretchy="false">{</mml:mo>
<mml:mrow>
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:msub>
<mml:mrow>
<mml:mtext mathvariant="normal">PUSH</mml:mtext>
</mml:mrow>
<mml:mrow>
<mml:mi>C</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo stretchy="false">&#x2223;</mml:mo>
<mml:mi>C</mml:mi>
<mml:mo>&#x2208;</mml:mo>
<mml:mi mathvariant="double-struck">Z</mml:mi>
</mml:mrow>
<mml:mo stretchy="false">}</mml:mo>
</mml:mrow>
</mml:math>
</inline-formula>. Then we have<disp-formula id="equ31">
<mml:math id="m66">
<mml:mtext mathvariant="normal">maxelem</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msubsup>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mo>&#x2032;</mml:mo>
</mml:mrow>
</mml:msubsup>
<mml:mo>,</mml:mo>
<mml:msubsup>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mo>&#x2032;</mml:mo>
</mml:mrow>
</mml:msubsup>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x2264;</mml:mo>
<mml:mn>2</mml:mn>
<mml:mo>&#x22c5;</mml:mo>
<mml:mtext mathvariant="normal">maxelem</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x2b;</mml:mo>
<mml:mn>1</mml:mn>
</mml:math>
</disp-formula>
</p>
</statement>
</p>
<p>
<statement content-type="proof" id="uProof_3">
<label>Proof</label>
<p>For this proof one needs a one-by-one analysis showing that each of the operators of Script satisfies these bounds. We give a few examples of how this is proved for some particular operators, the full details for the entire Script language are provided as <xref ref-type="sec" rid="s11">Supplemental Material</xref>.</p>
<p>We show how to prove the bound on elemnr using the OP_3DUP operator. For an arbitrary pair of stacks <inline-formula id="inf34">
<mml:math id="m67">
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>&#x3d;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mn>0</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mo>&#x22c5;</mml:mo>
<mml:mo>&#x2026;</mml:mo>
<mml:mo>&#x22c5;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>k</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>&#x2208;</mml:mo>
<mml:msup>
<mml:mrow>
<mml:mi mathvariant="double-struck">Z</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mo>&#x2217;</mml:mo>
</mml:mrow>
</mml:msup>
</mml:math>
</inline-formula> and <inline-formula id="inf35">
<mml:math id="m68">
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>&#x2208;</mml:mo>
<mml:msup>
<mml:mrow>
<mml:mi mathvariant="double-struck">Z</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mo>&#x2217;</mml:mo>
</mml:mrow>
</mml:msup>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>I</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>&#x2208;</mml:mo>
<mml:msup>
<mml:mrow>
<mml:mrow>
<mml:mo stretchy="false">{</mml:mo>
<mml:mrow>
<mml:mn>1</mml:mn>
</mml:mrow>
<mml:mo stretchy="false">}</mml:mo>
</mml:mrow>
</mml:mrow>
<mml:mrow>
<mml:mo>&#x2217;</mml:mo>
</mml:mrow>
</mml:msup>
</mml:math>
</inline-formula>, if these stacks fulfill the conditions for the <sans-serif>OP</sans-serif>_<sans-serif>3DUP</sans-serif> operator, then we have that<disp-formula id="equ32">
<mml:math id="m69">
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:mn>3</mml:mn>
<mml:mtext>DUP</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>I</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mspace width="0.3333em"/>
<mml:mo>&#x3d;</mml:mo>
<mml:mspace width="0.3333em"/>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msubsup>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mo>&#x2032;</mml:mo>
</mml:mrow>
</mml:msubsup>
<mml:mo>,</mml:mo>
<mml:msubsup>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mo>&#x2032;</mml:mo>
</mml:mrow>
</mml:msubsup>
<mml:mo>,</mml:mo>
<mml:msubsup>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>I</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mo>&#x2032;</mml:mo>
</mml:mrow>
</mml:msubsup>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mspace width="0.3333em"/>
<mml:mo>&#x3d;</mml:mo>
<mml:mspace width="0.3333em"/>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mn>0</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mo>&#x22c5;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mn>1</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mo>&#x22c5;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mn>2</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mo>&#x22c5;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>I</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>,</mml:mo>
</mml:math>
</disp-formula>or, in other words, OP_3DUP pushes elements A<sub>0</sub>, A<sub>1</sub> and A<sub>2</sub> onto &#x3c6;<sub>M</sub>. This means that <inline-formula id="inf36">
<mml:math id="m70">
<mml:mtext mathvariant="normal">elemnr</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msubsup>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mo>&#x2032;</mml:mo>
</mml:mrow>
</mml:msubsup>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x3d;</mml:mo>
<mml:mtext mathvariant="normal">elemnr</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x2b;</mml:mo>
<mml:mn>3</mml:mn>
</mml:math>
</inline-formula>, which was to be&#x20;shown.</p>
<p>For the bound on the size maxelem of elements in the stack, we use the OP_ADD operator to illustrate the proof. Again, for an arbitrary pair of stacks <inline-formula id="inf37">
<mml:math id="m71">
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>&#x3d;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mn>0</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mo>&#x22c5;</mml:mo>
<mml:mo>&#x2026;</mml:mo>
<mml:mo>&#x22c5;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>k</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>&#x2208;</mml:mo>
<mml:msup>
<mml:mrow>
<mml:mi mathvariant="double-struck">Z</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mo>&#x2217;</mml:mo>
</mml:mrow>
</mml:msup>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>&#x2208;</mml:mo>
<mml:msup>
<mml:mrow>
<mml:mi mathvariant="double-struck">Z</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mo>&#x2217;</mml:mo>
</mml:mrow>
</mml:msup>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>I</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>&#x2208;</mml:mo>
<mml:msup>
<mml:mrow>
<mml:mrow>
<mml:mo stretchy="false">{</mml:mo>
<mml:mrow>
<mml:mn>1</mml:mn>
</mml:mrow>
<mml:mo stretchy="false">}</mml:mo>
</mml:mrow>
</mml:mrow>
<mml:mrow>
<mml:mo>&#x2217;</mml:mo>
</mml:mrow>
</mml:msup>
</mml:math>
</inline-formula>, if these stacks fulfill the conditions for the <sans-serif>OP</sans-serif>_<sans-serif>ADD</sans-serif> operator, then we have that<disp-formula id="equ33">
<mml:math id="m72">
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:mtext mathvariant="normal">ADD</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>I</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mspace width="0.3333em"/>
<mml:mo>&#x3d;</mml:mo>
<mml:mspace width="0.3333em"/>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msubsup>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mo>&#x2032;</mml:mo>
</mml:mrow>
</mml:msubsup>
<mml:mo>,</mml:mo>
<mml:msubsup>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mo>&#x2032;</mml:mo>
</mml:mrow>
</mml:msubsup>
<mml:mo>,</mml:mo>
<mml:msubsup>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>I</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mo>&#x2032;</mml:mo>
</mml:mrow>
</mml:msubsup>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mspace width="0.3333em"/>
<mml:mo>&#x3d;</mml:mo>
<mml:mspace width="0.3333em"/>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mn>0</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mo>&#x2b;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mn>1</mml:mn>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x22c5;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mn>2</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mo>&#x22c5;</mml:mo>
<mml:mo>&#x2026;</mml:mo>
<mml:mo>&#x22c5;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>k</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>I</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>.</mml:mo>
</mml:math>
</disp-formula>
</p>
<p>It is clear that &#x7c;A<sub>0</sub>&#x7c;, &#x2026;, &#x7c;A<sub>k</sub>&#x7c; &#x2264; maxelem(&#x3c6;<sub>M</sub>), hence we have that<disp-formula id="equ34">
<mml:math id="m73">
<mml:mo stretchy="false">&#x7c;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mn>0</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mo stretchy="false">&#x7c;</mml:mo>
<mml:mo>&#x2b;</mml:mo>
<mml:mo stretchy="false">&#x7c;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mn>1</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mo stretchy="false">&#x7c;</mml:mo>
<mml:mspace width="0.3333em"/>
<mml:mo>&#x2264;</mml:mo>
<mml:mspace width="0.3333em"/>
<mml:mn>2</mml:mn>
<mml:mo>&#x22c5;</mml:mo>
<mml:mtext mathvariant="normal">maxelem</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mspace width="0.3333em"/>
<mml:mo>&#x2264;</mml:mo>
<mml:mspace width="0.3333em"/>
<mml:mn>2</mml:mn>
<mml:mo>&#x22c5;</mml:mo>
<mml:mtext mathvariant="normal">maxelem</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x2b;</mml:mo>
<mml:mn>1</mml:mn>
<mml:mo>.</mml:mo>
</mml:math>
</disp-formula>
</p>
<p>By combining both results we can conclude that<disp-formula id="equ35">
<mml:math id="m74">
<mml:mtext mathvariant="normal">maxelem</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msubsup>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mo>&#x2032;</mml:mo>
</mml:mrow>
</mml:msubsup>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x2264;</mml:mo>
<mml:mn>2</mml:mn>
<mml:mo>&#x22c5;</mml:mo>
<mml:mtext mathvariant="normal">maxelem</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x2b;</mml:mo>
<mml:mn>1</mml:mn>
<mml:mo>,</mml:mo>
</mml:math>
</disp-formula>which was to be shown. &#x25a0; &#x25a1;</p>
<p>Our next step is to use the bounds presented above to provide upper bounds on the values of these functions over the execution of complete scripts. These bounds must take into account the size of the stacks, so we need to discuss how these are encoded. For our complexity results, we assume that stacks are represented as arrays of integer elements. Assuming that the elements in the stacks are represented in binary notation, and that we use one extra bit to represent the sign of each number, we define the size &#x2016;&#x3c6;&#x2016; of a stack <inline-formula id="inf38">
<mml:math id="m75">
<mml:mi>&#x3c6;</mml:mi>
<mml:mo>&#x3d;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mn>0</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mo>&#x22c5;</mml:mo>
<mml:mo>&#x2026;</mml:mo>
<mml:mo>&#x22c5;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>k</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>&#x2208;</mml:mo>
<mml:msup>
<mml:mrow>
<mml:mi mathvariant="double-struck">Z</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mo>&#x2217;</mml:mo>
</mml:mrow>
</mml:msup>
</mml:math>
</inline-formula> as:<disp-formula id="equ36">
<mml:math id="m76">
<mml:mo stretchy="false">&#x2016;</mml:mo>
<mml:mi>&#x3c6;</mml:mi>
<mml:mo stretchy="false">&#x2016;</mml:mo>
<mml:mo>&#x3d;</mml:mo>
<mml:munderover accentunder="false" accent="false">
<mml:mrow>
<mml:mo>&#x2211;</mml:mo>
</mml:mrow>
<mml:mrow>
<mml:mi>i</mml:mi>
<mml:mo>&#x3d;</mml:mo>
<mml:mn>0</mml:mn>
</mml:mrow>
<mml:mrow>
<mml:mi>k</mml:mi>
</mml:mrow>
</mml:munderover>
<mml:msub>
<mml:mrow>
<mml:mi>log</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mn>2</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mo stretchy="false">&#x7c;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>i</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo stretchy="false">&#x7c;</mml:mo>
<mml:mo>&#x2b;</mml:mo>
<mml:mn>1</mml:mn>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>.</mml:mo>
</mml:math>
</disp-formula>
</p>
<p>From this definition, we can derive the following bounds:<disp-formula id="e3">
<mml:math id="m77">
<mml:mtable class="eqnarray">
<mml:mtr>
<mml:mtd columnalign="right">
<mml:msub>
<mml:mrow>
<mml:mi>log</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mn>2</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mtext mathvariant="normal">maxelem</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x2b;</mml:mo>
<mml:mn>1</mml:mn>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:mtd>
<mml:mtd columnalign="left">
<mml:mo>&#x2264;</mml:mo>
</mml:mtd>
<mml:mtd columnalign="left">
<mml:mo stretchy="false">&#x2016;</mml:mo>
<mml:mi>&#x3c6;</mml:mi>
<mml:mo stretchy="false">&#x2016;</mml:mo>
</mml:mtd>
</mml:mtr>
</mml:mtable>
</mml:math>
<label>(3)</label>
</disp-formula>
<disp-formula id="e4">
<mml:math id="m78">
<mml:mtable class="eqnarray">
<mml:mtr>
<mml:mtd columnalign="right">
<mml:mtext mathvariant="normal">elemnr</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:mtd>
<mml:mtd columnalign="left">
<mml:mo>&#x2264;</mml:mo>
</mml:mtd>
<mml:mtd columnalign="left">
<mml:mo stretchy="false">&#x2016;</mml:mo>
<mml:mi>&#x3c6;</mml:mi>
<mml:mo stretchy="false">&#x2016;</mml:mo>
</mml:mtd>
</mml:mtr>
</mml:mtable>
</mml:math>
<label>(4)</label>
</disp-formula>
</p>
<p>These bounds will help us in relating several results that make use of the auxiliary functions with the size of the representation of the stack. This is useful because we will be interested in establishing a relationship between the runtime of executing a script with an initial stack and the sizes of the inputs.</p>
<p>Let us now turn to (upper) bound the values of the auxiliary functions. In particular, we need to prove that the different elements of the stacks, during the execution of a script, are of polynomial-size in the sizes of the script and the initial stack. This idea is formalized in the following lemma; the proof is once again by a direct examination of each operator.</p>
</statement>
</p>
<p>
<statement content-type="lemma" id="Lemma_4_4">
<label>Lemma 4.4</label>
<p>Let S &#x3d; f<sub>0</sub>&#x22c5;&#x2026;&#x22c5;f<sub>n</sub> &#x2208; O&#x2217; and <inline-formula id="inf39">
<mml:math id="m79">
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>&#x2208;</mml:mo>
<mml:msup>
<mml:mrow>
<mml:mi mathvariant="double-struck">Z</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mo>&#x2217;</mml:mo>
</mml:mrow>
</mml:msup>
</mml:math>
</inline-formula>. After any partial execution (f<sub>i</sub>&#x25e6;&#x2026;&#x25e6;f<sub>0</sub>)(&#x3c6;<sub>M</sub>, &#x25b;, &#x25b;), the following conditions hold.<list list-type="simple">
<list-item>
<p>1. The amount of elements that can appear in the main stack is bounded by elemnr(&#x3c6;<sub>M</sub>) &#x2b; 3(n &#x2b;&#x20;1).</p>
</list-item>
<list-item>
<p>2. The biggest element that can appear in either stack is bounded&#x20;by</p>
</list-item>
</list>
<disp-formula id="equ37">
<mml:math id="m80">
<mml:msub>
<mml:mrow>
<mml:mi>p</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mtext mathvariant="normal">maxelem</mml:mtext>
</mml:mrow>
</mml:msub>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msup>
<mml:mrow>
<mml:mn>2</mml:mn>
</mml:mrow>
<mml:mrow>
<mml:mi>n</mml:mi>
</mml:mrow>
</mml:msup>
<mml:mo>,</mml:mo>
<mml:msup>
<mml:mrow>
<mml:mn>2</mml:mn>
</mml:mrow>
<mml:mrow>
<mml:mo stretchy="false">&#x2016;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo stretchy="false">&#x2016;</mml:mo>
</mml:mrow>
</mml:msup>
<mml:mo>,</mml:mo>
<mml:mtext mathvariant="normal">maxpush</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mi>S</mml:mi>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>,</mml:mo>
</mml:math>
</disp-formula>for some fixed polynomial p<sub>maxelem</sub>.<list list-type="simple">
<list-item>
<p>3. The size of the representation of the main stack is bounded&#x20;by</p>
</list-item>
</list>
<disp-formula id="equ38">
<mml:math id="m81">
<mml:msub>
<mml:mrow>
<mml:mi>p</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mtext mathvariant="italic">size</mml:mtext>
</mml:mrow>
</mml:msub>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mi>n</mml:mi>
<mml:mo>,</mml:mo>
<mml:mo stretchy="false">&#x2016;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo stretchy="false">&#x2016;</mml:mo>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>log</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mn>2</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mtext mathvariant="normal">maxpush</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mi>S</mml:mi>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x2b;</mml:mo>
<mml:mn>1</mml:mn>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>,</mml:mo>
</mml:math>
</disp-formula>for some fixed polynomial p<sub>size</sub>.</p>
<p>We finally have all the ingredients to provide the upper bound on the execution time of script evaluation. For this result we consider a na&#xef;ve algorithm that receives as input a script S &#x3d; f<sub>0</sub>&#x22c5;&#x2026;&#x22c5;f<sub>n</sub> &#x2208; O&#x2217; and a stack <inline-formula id="inf40">
<mml:math id="m82">
<mml:mi>&#x3c6;</mml:mi>
<mml:mo>&#x2208;</mml:mo>
<mml:msup>
<mml:mrow>
<mml:mi mathvariant="double-struck">Z</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mo>&#x2217;</mml:mo>
</mml:mrow>
</mml:msup>
</mml:math>
</inline-formula> and executes each operator in sequence over the stack. This is without loss of generality, as using faster, more involved algorithms can only decrease the total running time of the operations. In what follows we use T to denote the execution time of said algorithm, having in mind that the full execution involves working over a trio of stacks (the main stack, the alt-stack and the auxiliary stack for the IF-ELSE control flow). Therefore, we treat T as a function <inline-formula id="inf41">
<mml:math id="m83">
<mml:mi>T</mml:mi>
<mml:mo>:</mml:mo>
<mml:msup>
<mml:mrow>
<mml:mi>O</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mo>&#x2217;</mml:mo>
</mml:mrow>
</mml:msup>
<mml:mo>&#xd7;</mml:mo>
<mml:msup>
<mml:mrow>
<mml:mi mathvariant="double-struck">Z</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mo>&#x2217;</mml:mo>
</mml:mrow>
</mml:msup>
<mml:mo>&#xd7;</mml:mo>
<mml:msup>
<mml:mrow>
<mml:mi mathvariant="double-struck">Z</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mo>&#x2217;</mml:mo>
</mml:mrow>
</mml:msup>
<mml:mo>&#xd7;</mml:mo>
<mml:msup>
<mml:mrow>
<mml:mrow>
<mml:mo stretchy="false">{</mml:mo>
<mml:mrow>
<mml:mn>0,1</mml:mn>
</mml:mrow>
<mml:mo stretchy="false">}</mml:mo>
</mml:mrow>
</mml:mrow>
<mml:mrow>
<mml:mo>&#x2217;</mml:mo>
</mml:mrow>
</mml:msup>
<mml:mo>&#x2192;</mml:mo>
<mml:mi mathvariant="double-struck">N</mml:mi>
</mml:math>
</inline-formula>.</p>
</statement>
</p>
<p>
<statement content-type="lemma" id="Lemma_4_5">
<label>Lemma 4.5</label>
<p>Let S &#x3d; f<sub>0</sub>&#x22c5;&#x2026;&#x22c5;f<sub>n</sub> &#x2208; O&#x2217; and <inline-formula id="inf42">
<mml:math id="m84">
<mml:mi>&#x3c6;</mml:mi>
<mml:mo>&#x2208;</mml:mo>
<mml:msup>
<mml:mrow>
<mml:mi mathvariant="double-struck">Z</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mo>&#x2217;</mml:mo>
</mml:mrow>
</mml:msup>
</mml:math>
</inline-formula>. Then we have that<disp-formula id="equ39">
<mml:math id="m85">
<mml:mi>T</mml:mi>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mi>S</mml:mi>
<mml:mo>,</mml:mo>
<mml:mi>&#x3c6;</mml:mi>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x2264;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>p</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>T</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mi>n</mml:mi>
<mml:mo>,</mml:mo>
<mml:mo stretchy="false">&#x2016;</mml:mo>
<mml:mi>&#x3c6;</mml:mi>
<mml:mo stretchy="false">&#x2016;</mml:mo>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>log</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mn>2</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mtext mathvariant="normal">maxpush</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mi>S</mml:mi>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x2b;</mml:mo>
<mml:mn>1</mml:mn>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:math>
</disp-formula>for some fixed polynomial p<sub>T</sub> (independent of S and &#x3c6;).</p>
<p>The proof of this lemma is by induction, using <xref ref-type="statement" rid="Lemma_4_4">Lemma 4.4</xref> and <xref ref-type="statement" rid="Lemma_4_3">Lemma 4.3</xref> for the inductive and base&#x20;cases.</p>
<p>Having established that the execution time of the algorithm that applies a script to an initial stack can be executed in polynomial time, we can move on to prove that script evaluation is in <sc>Ptime</sc>. As we have previously discussed, an algorithm that performs script evaluation starts by executing an unlocking script over a trio of empty stacks and then, if the final control stack is empty, it executes a locking script over the previous final main stack and two empty stacks. Thus, all we need to do is to show that both of these operations take polynomial time when executed sequentially. This is shown in the following lemma. Note that we only have consider the case in which the unlocking script that the algorithm receives does not result in an error and that finishes with an empty control stack; the remaining cases imply an early stop in the algorithm so they are also captured by the bounds for a complete execution.</p>
</statement>
</p>
<p>
<statement content-type="lemma" id="Lemma_4_6">
<label>Lemma 4.6</label>
<p>Let S<sub>L</sub> &#x3d; f<sub>0</sub>&#x22c5;&#x2026;&#x22c5;f<sub>n</sub> &#x2208; O&#x2217; and S<sub>U</sub> &#x3d; g<sub>0</sub>&#x22c5;&#x2026;&#x22c5;g<sub>m</sub> &#x2208; O&#x2217;, such that<disp-formula id="equ40">
<mml:math id="m86">
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>g</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>m</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>&#x25e6;</mml:mo>
<mml:mo>&#x2026;</mml:mo>
<mml:mo>&#x25e6;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>g</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mn>0</mml:mn>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mi>&#x3b5;</mml:mi>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x3d;</mml:mo>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>.</mml:mo>
</mml:math>
</disp-formula>
</p>
<p>Then, there is a fixed polynomial p<sub>emp</sub> (independent of S<sub>L</sub> and S<sub>U</sub>) such that:<disp-formula id="equ41">
<mml:math id="m87">
<mml:mi>T</mml:mi>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>S</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>U</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x2b;</mml:mo>
<mml:mi>T</mml:mi>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>S</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>L</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x2264;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>p</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>e</mml:mi>
<mml:mi>m</mml:mi>
<mml:mi>p</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mi>m</mml:mi>
<mml:mo>,</mml:mo>
<mml:mi>n</mml:mi>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>log</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mn>2</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mtext mathvariant="normal">maxpush</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>S</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>U</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x2b;</mml:mo>
<mml:mn>1</mml:mn>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>log</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mn>2</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mtext mathvariant="normal">maxpush</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>S</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>L</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x2b;</mml:mo>
<mml:mn>1</mml:mn>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:math>
</disp-formula>
</p>
</statement>
</p>
<p>
<statement content-type="proof" id="uProof_4">
<label>Proof</label>
<p>Let S<sub>L</sub> &#x3d; <italic>f</italic>
<sub>0</sub>&#x22c5;&#x2026;&#x22c5;<italic>f</italic>
<sub>n</sub> &#x2208; O&#x2217; and S<sub>U</sub> &#x3d; <italic>g</italic>
<sub>0</sub>&#x22c5;&#x2026;&#x22c5;<italic>g</italic>
<sub>m</sub> &#x2208; O&#x2217;, such that<disp-formula id="equ42">
<mml:math id="m88">
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>g</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>m</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>&#x25e6;</mml:mo>
<mml:mo>&#x2026;</mml:mo>
<mml:mo>&#x25e6;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>g</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mn>0</mml:mn>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mi>&#x3b5;</mml:mi>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x3d;</mml:mo>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>A</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>.</mml:mo>
</mml:math>
</disp-formula>
</p>
<p>From <xref ref-type="statement" rid="Lemma_4_5">Lemma 4.5</xref> there is a fixed polynomial p<sub>T</sub> and the following bound on T(S<sub>U</sub>, &#x25b;, &#x25b;, &#x25b;):<disp-formula id="equ43">
<mml:math id="m89">
<mml:mtable class="align-star" columnalign="left">
<mml:mtr>
<mml:mtd columnalign="right">
<mml:mi>T</mml:mi>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>S</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>U</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:mtd>
<mml:mtd columnalign="left">
<mml:mo>&#x2264;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>p</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>T</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mi>m</mml:mi>
<mml:mo>,</mml:mo>
<mml:mo stretchy="false">&#x2016;</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
<mml:mo stretchy="false">&#x2016;</mml:mo>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>log</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mn>2</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mtext mathvariant="normal">maxpush</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>S</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>U</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x2b;</mml:mo>
<mml:mn>1</mml:mn>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:mtd>
</mml:mtr>
<mml:mtr>
<mml:mtd columnalign="right"/>
<mml:mtd columnalign="left">
<mml:mo>&#x2264;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>p</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>U</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mi>m</mml:mi>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>log</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mn>2</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mtext mathvariant="normal">maxpush</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>S</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>U</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x2b;</mml:mo>
<mml:mn>1</mml:mn>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>,</mml:mo>
</mml:mtd>
</mml:mtr>
</mml:mtable>
</mml:math>
</disp-formula>where p<sub>U</sub> is again a fixed polynomial. We can also bound T(S<sub>L</sub>, &#x3c6;<sub>M</sub>, &#x25b;, &#x25b;) in the same way:<disp-formula id="equ44">
<mml:math id="m90">
<mml:mi>T</mml:mi>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>S</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>L</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x2264;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>p</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>T</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mi>n</mml:mi>
<mml:mo>,</mml:mo>
<mml:mo stretchy="false">&#x2016;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo stretchy="false">&#x2016;</mml:mo>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>log</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mn>2</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mtext mathvariant="normal">maxpush</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>S</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>L</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x2b;</mml:mo>
<mml:mn>1</mml:mn>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>.</mml:mo>
</mml:math>
</disp-formula>
</p>
<p>Moreover, from <xref ref-type="statement" rid="Lemma_4_4">Lemma 4.4</xref> we can also bound &#x2016;&#x3c6;<sub>M</sub>&#x2016;:<disp-formula id="equ45">
<mml:math id="m91">
<mml:mo stretchy="false">&#x2016;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo stretchy="false">&#x2016;</mml:mo>
<mml:mo>&#x2264;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>p</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mtext mathvariant="italic">size</mml:mtext>
</mml:mrow>
</mml:msub>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mi>m</mml:mi>
<mml:mo>,</mml:mo>
<mml:mo stretchy="false">&#x2016;</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
<mml:mo stretchy="false">&#x2016;</mml:mo>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>log</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mn>2</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mtext mathvariant="normal">maxpush</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>S</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>U</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x2b;</mml:mo>
<mml:mn>1</mml:mn>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>.</mml:mo>
</mml:math>
</disp-formula>
</p>
<p>By combining both of these bounds we can conclude that<disp-formula id="equ46">
<mml:math id="m92">
<mml:mi>T</mml:mi>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>S</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>L</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x2264;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>p</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>L</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mi>m</mml:mi>
<mml:mo>,</mml:mo>
<mml:mi>n</mml:mi>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>log</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mn>2</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mtext mathvariant="normal">maxpush</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>S</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>U</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x2b;</mml:mo>
<mml:mn>1</mml:mn>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>log</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mn>2</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mtext mathvariant="normal">maxpush</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>S</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>L</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x2b;</mml:mo>
<mml:mn>1</mml:mn>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>,</mml:mo>
</mml:math>
</disp-formula>for some polynomial p<sub>L</sub>. Furthermore, adding equations for both executions over S<sub>L</sub> and S<sub>U</sub>, we obtain:<disp-formula id="equ47">
<mml:math id="m93">
<mml:mtable class="align-star" columnalign="left">
<mml:mtr>
<mml:mtd columnalign="right">
<mml:mi>T</mml:mi>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>S</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>U</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x2b;</mml:mo>
<mml:mi>T</mml:mi>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>S</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>L</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>&#x3c6;</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>M</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
<mml:mo>,</mml:mo>
<mml:mi>&#x3b5;</mml:mi>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:mtd>
<mml:mtd columnalign="left">
<mml:mo>&#x2264;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>p</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>U</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mi>m</mml:mi>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>log</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mn>2</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mtext mathvariant="normal">maxpush</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>S</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>U</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x2b;</mml:mo>
<mml:mn>1</mml:mn>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mspace width="0.3333em"/>
<mml:mo>&#x2b;</mml:mo>
</mml:mtd>
</mml:mtr>
<mml:mtr>
<mml:mtd columnalign="right"/>
<mml:mtd columnalign="left">
<mml:mspace width="2em"/>
<mml:msub>
<mml:mrow>
<mml:mi>p</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>L</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mi>m</mml:mi>
<mml:mo>,</mml:mo>
<mml:mi>n</mml:mi>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>log</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mn>2</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mtext mathvariant="normal">maxpush</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>S</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>U</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x2b;</mml:mo>
<mml:mn>1</mml:mn>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>log</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mn>2</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mtext mathvariant="normal">maxpush</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>S</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>L</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x2b;</mml:mo>
<mml:mn>1</mml:mn>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:mtd>
</mml:mtr>
<mml:mtr>
<mml:mtd columnalign="right"/>
<mml:mtd columnalign="left">
<mml:mo>&#x2264;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>p</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>e</mml:mi>
<mml:mi>m</mml:mi>
<mml:mi>p</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mi>m</mml:mi>
<mml:mo>,</mml:mo>
<mml:mi>n</mml:mi>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>log</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mn>2</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mtext mathvariant="normal">maxpush</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>S</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>U</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x2b;</mml:mo>
<mml:mn>1</mml:mn>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>,</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>log</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mn>2</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:mtext mathvariant="normal">maxpush</mml:mtext>
<mml:mrow>
<mml:mo stretchy="false">(</mml:mo>
<mml:mrow>
<mml:msub>
<mml:mrow>
<mml:mi>S</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>L</mml:mi>
</mml:mrow>
</mml:msub>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>&#x2b;</mml:mo>
<mml:mn>1</mml:mn>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
</mml:mrow>
<mml:mo stretchy="false">)</mml:mo>
</mml:mrow>
<mml:mo>,</mml:mo>
</mml:mtd>
</mml:mtr>
</mml:mtable>
</mml:math>
</disp-formula>where p<sub>emp</sub> is a fixed polynomial independent of S<sub>L</sub> and S<sub>U</sub>. &#x25a0; &#x25a1;</p>
<p>Note that we have not included the validity checks that need to be performed between the executions of both scripts and also at the end of the execution of the locking script to determine whether the execution was successful. This is because these checks can be performed in constant time and do not impact the complexity analysis of the problem. This concludes the proof of the Theorem.</p>
</statement>
</p>
</sec>
<sec id="s4-3">
<title>4.3 Unlockability is Computationally Infeasible</title>
<p>The evaluation of a pair of scripts can be done efficiently, but what about checking whether a script is unlockable? Recall that the Unlockability of Script problem receives a locking script l, and consists of checking whether there exists any unlocking script u such that l and u result in a positive answer when evaluated together.</p>
<p>Unfortunately, the following result tells us that this problem cannot be solved efficiently.</p>
<p>
<statement content-type="theorem" id="Theorem_4_7">
<label>Theorem 4.7</label>
<p>The problem Unlockability of Script is NP-hard.</p>
</statement>
</p>
<p>
<statement content-type="proof" id="uProof_5">
<label>Proof</label>
<p>To prove the theorem, we provide a polynomial-time reduction from 3SAT, which is a well-known NP-complete problem. Let &#x3c8; &#x3d; C<sub>0</sub> &#x2227; C<sub>1</sub> &#x2227;&#x2026;&#x2227;C<sub>m</sub> be a formula in CNF, where each clause C<sub>i</sub> is the conjunction of three literals:<disp-formula id="equ48">
<mml:math id="m94">
<mml:msub>
<mml:mrow>
<mml:mi>C</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>i</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>&#x3d;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>u</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>i</mml:mi>
<mml:mo>,</mml:mo>
<mml:mn>0</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mo>&#x2228;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>u</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>i</mml:mi>
<mml:mo>,</mml:mo>
<mml:mn>1</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mo>&#x2228;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>u</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>i</mml:mi>
<mml:mo>,</mml:mo>
<mml:mn>2</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
</mml:math>
</disp-formula>that is, each u<sub>i,j</sub> is either a propositional variable x or the negation of a propositional variable &#xac;x. Besides, assume that {x<sub>0</sub>, x<sub>1</sub>, &#x2026;, x<sub>k</sub>} is the set of variables occurring in &#x3c8;. Next, we show how to construct in polynomial-time a script l<sub>&#x3c8;</sub> that can be used to check whether &#x3c8; is satisfiable.</p>
<p>By definition of the problem Unlockability of Script, the&#x20;script l<sub>&#x3c8;</sub> has to be executed over the main stack resulting from the execution of an unlocking script. Thus, l<sub>&#x3c8;</sub> interprets such a stack as a truth assignment for the formula &#x3c8;, and verifies whether such an assignment satisfies this formula. In this way, an unlocking script for l<sub>&#x3c8;</sub> represents a truth assignment satisfying &#x3c8;, so that &#x3c8; is satisfiable if and only if l<sub>&#x3c8;</sub> is unlockable. More precisely, we define l<sub>&#x3c8;</sub> as follows:<disp-formula id="equ49">
<mml:math id="m95">
<mml:msub>
<mml:mrow>
<mml:mi>l</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mi>&#x3c8;</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>&#x2254;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>l</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mtext>length</mml:mtext>
</mml:mrow>
</mml:msub>
<mml:mo>&#x22c5;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>l</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mtext>binary</mml:mtext>
</mml:mrow>
</mml:msub>
<mml:mo>&#x22c5;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>l</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mtext>sat</mml:mtext>
</mml:mrow>
</mml:msub>
<mml:mo>&#x22c5;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>l</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mtext>end</mml:mtext>
</mml:mrow>
</mml:msub>
</mml:math>
</disp-formula>where each script l<sub>length</sub>, l<sub>binary</sub>, l<sub>sat</sub>, l<sub>end</sub> are as defined below.<list list-type="simple">
<list-item>
<p>&#x2022; The script l<sub>length</sub> checks whether the stack that it receives as input contains k &#x2b; 1 elements (which is the number of variables occurring in &#x3c8;):</p>
</list-item>
</list>
<disp-formula id="equ50">
<mml:math id="m96">
<mml:msub>
<mml:mrow>
<mml:mi>l</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mtext>length</mml:mtext>
</mml:mrow>
</mml:msub>
<mml:mo>&#x2254;</mml:mo>
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:mtext mathvariant="normal">DEPTH</mml:mtext>
<mml:mo>&#x22c5;</mml:mo>
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:msub>
<mml:mrow>
<mml:mtext mathvariant="normal">PUSH</mml:mtext>
</mml:mrow>
<mml:mrow>
<mml:mi>k</mml:mi>
<mml:mo>&#x2b;</mml:mo>
<mml:mn>1</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mo>&#x22c5;</mml:mo>
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:mtext mathvariant="normal">EQUALVERIFY</mml:mtext>
</mml:math>
</disp-formula>
<list list-type="simple">
<list-item>
<p>&#x2022; The script l<sub>binary</sub> verifies whether each one of the k &#x2b; 1 elements of the stack is either 0 or 1. More precisely, we have that:</p>
</list-item>
</list>
<disp-formula id="equ51">
<mml:math id="m97">
<mml:msub>
<mml:mrow>
<mml:mi>l</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mtext>binary</mml:mtext>
</mml:mrow>
</mml:msub>
<mml:mo>&#x2254;</mml:mo>
<mml:msubsup>
<mml:mrow>
<mml:mi>l</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mtext>binary</mml:mtext>
</mml:mrow>
<mml:mrow>
<mml:mn>0</mml:mn>
</mml:mrow>
</mml:msubsup>
<mml:mo>&#x22c5;</mml:mo>
<mml:msubsup>
<mml:mrow>
<mml:mi>l</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mtext>binary</mml:mtext>
</mml:mrow>
<mml:mrow>
<mml:mn>1</mml:mn>
</mml:mrow>
</mml:msubsup>
<mml:mo>&#x22c5;</mml:mo>
<mml:mo>&#x2026;</mml:mo>
<mml:mo>&#x22c5;</mml:mo>
<mml:msubsup>
<mml:mrow>
<mml:mi>l</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mtext>binary</mml:mtext>
</mml:mrow>
<mml:mrow>
<mml:mi>k</mml:mi>
</mml:mrow>
</mml:msubsup>
<mml:mo>,</mml:mo>
</mml:math>
</disp-formula>where for every i &#x2208; {0, 1, &#x2026;, k}:<disp-formula id="equ52">
<mml:math id="m98">
<mml:mtable class="eqnarray-star">
<mml:mtr>
<mml:mtd columnalign="right">
<mml:msubsup>
<mml:mrow>
<mml:mi>l</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mtext>binary</mml:mtext>
</mml:mrow>
<mml:mrow>
<mml:mi>i</mml:mi>
</mml:mrow>
</mml:msubsup>
</mml:mtd>
<mml:mtd columnalign="left">
<mml:mo>&#x2254;</mml:mo>
</mml:mtd>
<mml:mtd columnalign="left">
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:msub>
<mml:mrow>
<mml:mtext mathvariant="normal">PUSH</mml:mtext>
</mml:mrow>
<mml:mrow>
<mml:mi>i</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>&#x22c5;</mml:mo>
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:mtext mathvariant="normal">PICK</mml:mtext>
<mml:mo>&#x22c5;</mml:mo>
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:mtext mathvariant="normal">IFDUP</mml:mtext>
<mml:mo>&#x22c5;</mml:mo>
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:mtext mathvariant="normal">IF</mml:mtext>
<mml:mo>&#x22c5;</mml:mo>
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:msub>
<mml:mrow>
<mml:mtext mathvariant="normal">PUSH</mml:mtext>
</mml:mrow>
<mml:mrow>
<mml:mn>1</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mo>&#x22c5;</mml:mo>
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:mtext mathvariant="normal">EQUALVERIFY</mml:mtext>
<mml:mo>&#x22c5;</mml:mo>
</mml:mtd>
</mml:mtr>
<mml:mtr>
<mml:mtd columnalign="right"/>
<mml:mtd columnalign="left"/>
<mml:mtd columnalign="left">
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:mtext mathvariant="normal">ENDIF</mml:mtext>
<mml:mo>.</mml:mo>
</mml:mtd>
</mml:mtr>
</mml:mtable>
</mml:math>
</disp-formula>
<list list-type="simple">
<list-item>
<p>&#x2022; The script l<sub>sat</sub> checks whether the formula &#x3c8; is satisfied by the truth assignment stored in the stack, that is, by the sequence of k &#x2b; 1 symbols 0 and 1 stored in the stack. More precisely, we have that:</p>
</list-item>
</list>
<disp-formula id="equ53">
<mml:math id="m99">
<mml:msub>
<mml:mrow>
<mml:mi>l</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mtext>sat</mml:mtext>
</mml:mrow>
</mml:msub>
<mml:mo>&#x2254;</mml:mo>
<mml:msubsup>
<mml:mrow>
<mml:mi>l</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mtext>sat</mml:mtext>
</mml:mrow>
<mml:mrow>
<mml:mn>0</mml:mn>
</mml:mrow>
</mml:msubsup>
<mml:mo>&#x22c5;</mml:mo>
<mml:msubsup>
<mml:mrow>
<mml:mi>l</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mtext>sat</mml:mtext>
</mml:mrow>
<mml:mrow>
<mml:mn>1</mml:mn>
</mml:mrow>
</mml:msubsup>
<mml:mo>&#x22c5;</mml:mo>
<mml:mo>&#x2026;</mml:mo>
<mml:mo>&#x22c5;</mml:mo>
<mml:msubsup>
<mml:mrow>
<mml:mi>l</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mtext>sat</mml:mtext>
</mml:mrow>
<mml:mrow>
<mml:mi>m</mml:mi>
</mml:mrow>
</mml:msubsup>
<mml:mo>,</mml:mo>
</mml:math>
</disp-formula>where each script <inline-formula id="inf43">
<mml:math id="m100">
<mml:msubsup>
<mml:mrow>
<mml:mi>l</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mtext>sat</mml:mtext>
</mml:mrow>
<mml:mrow>
<mml:mi>i</mml:mi>
</mml:mrow>
</mml:msubsup>
</mml:math>
</inline-formula> (0 &#x2264; i &#x2264; m) is defined as follows. Assuming that C<sub>i</sub> &#x3d; u<sub>i,0</sub> &#x2228; u<sub>i,1</sub> &#x2228; u<sub>i,2</sub>, we have that:<disp-formula id="equ54">
<mml:math id="m101">
<mml:msubsup>
<mml:mrow>
<mml:mi>l</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mtext>sat</mml:mtext>
</mml:mrow>
<mml:mrow>
<mml:mi>i</mml:mi>
</mml:mrow>
</mml:msubsup>
<mml:mo>&#x2254;</mml:mo>
<mml:msubsup>
<mml:mrow>
<mml:mi>l</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mtext>val</mml:mtext>
</mml:mrow>
<mml:mrow>
<mml:mi>i</mml:mi>
<mml:mo>,</mml:mo>
<mml:mn>0</mml:mn>
</mml:mrow>
</mml:msubsup>
<mml:mo>&#x22c5;</mml:mo>
<mml:msubsup>
<mml:mrow>
<mml:mi>l</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mtext>val</mml:mtext>
</mml:mrow>
<mml:mrow>
<mml:mi>i</mml:mi>
<mml:mo>,</mml:mo>
<mml:mn>1</mml:mn>
</mml:mrow>
</mml:msubsup>
<mml:mo>&#x22c5;</mml:mo>
<mml:msubsup>
<mml:mrow>
<mml:mi>l</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mtext>val</mml:mtext>
</mml:mrow>
<mml:mrow>
<mml:mi>i</mml:mi>
<mml:mo>,</mml:mo>
<mml:mn>2</mml:mn>
</mml:mrow>
</mml:msubsup>
<mml:mo>&#x22c5;</mml:mo>
<mml:msub>
<mml:mrow>
<mml:mi>l</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mtext>add</mml:mtext>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
</mml:math>
</disp-formula>where <inline-formula id="inf44">
<mml:math id="m102">
<mml:msubsup>
<mml:mrow>
<mml:mi>l</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mtext>val</mml:mtext>
</mml:mrow>
<mml:mrow>
<mml:mi>i</mml:mi>
<mml:mo>,</mml:mo>
<mml:mn>0</mml:mn>
</mml:mrow>
</mml:msubsup>
</mml:math>
</inline-formula>, <inline-formula id="inf45">
<mml:math id="m103">
<mml:msubsup>
<mml:mrow>
<mml:mi>l</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mtext>val</mml:mtext>
</mml:mrow>
<mml:mrow>
<mml:mi>i</mml:mi>
<mml:mo>,</mml:mo>
<mml:mn>1</mml:mn>
</mml:mrow>
</mml:msubsup>
</mml:math>
</inline-formula>, <inline-formula id="inf46">
<mml:math id="m104">
<mml:msubsup>
<mml:mrow>
<mml:mi>l</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mtext>val</mml:mtext>
</mml:mrow>
<mml:mrow>
<mml:mi>i</mml:mi>
<mml:mo>,</mml:mo>
<mml:mn>2</mml:mn>
</mml:mrow>
</mml:msubsup>
</mml:math>
</inline-formula> and l<sub>add</sub> are defined as follows. If u<sub>i,0</sub> &#x3d; x<sub>r</sub> for some r &#x2208; {0, &#x2026;, k}, then<disp-formula id="equ55">
<mml:math id="m105">
<mml:msubsup>
<mml:mrow>
<mml:mi>l</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mtext>val</mml:mtext>
</mml:mrow>
<mml:mrow>
<mml:mi>i</mml:mi>
<mml:mo>,</mml:mo>
<mml:mn>0</mml:mn>
</mml:mrow>
</mml:msubsup>
<mml:mo>&#x2254;</mml:mo>
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:msub>
<mml:mrow>
<mml:mtext mathvariant="normal">PUSH</mml:mtext>
</mml:mrow>
<mml:mrow>
<mml:mi>r</mml:mi>
</mml:mrow>
</mml:msub>
<mml:mo>&#x22c5;</mml:mo>
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:mtext mathvariant="normal">PICK</mml:mtext>
<mml:mo>.</mml:mo>
</mml:math>
</disp-formula>
</p>
<p>Thus, <inline-formula id="inf47">
<mml:math id="m106">
<mml:msubsup>
<mml:mrow>
<mml:mi>l</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mtext>val</mml:mtext>
</mml:mrow>
<mml:mrow>
<mml:mi>i</mml:mi>
<mml:mo>,</mml:mo>
<mml:mn>0</mml:mn>
</mml:mrow>
</mml:msubsup>
</mml:math>
</inline-formula> puts the value assigned to the propositional variable x<sub>r</sub> in the top of the stack. On the other hand, if u<sub>i,0</sub> &#x3d; &#xac;x<sub>r</sub> for some r &#x2208; {0, &#x2026;, k}, then<disp-formula id="equ56">
<mml:math id="m107">
<mml:msubsup>
<mml:mrow>
<mml:mi>l</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mtext>val</mml:mtext>
</mml:mrow>
<mml:mrow>
<mml:mi>i</mml:mi>
<mml:mo>,</mml:mo>
<mml:mn>0</mml:mn>
</mml:mrow>
</mml:msubsup>
<mml:mo>&#x2254;</mml:mo>
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:msub>
<mml:mrow>
<mml:mtext mathvariant="normal">PUSH</mml:mtext>
</mml:mrow>
<mml:mrow>
<mml:mn>1</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mo>&#x22c5;</mml:mo>
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:msub>
<mml:mrow>
<mml:mtext mathvariant="normal">PUSH</mml:mtext>
</mml:mrow>
<mml:mrow>
<mml:mi>r</mml:mi>
<mml:mo>&#x2b;</mml:mo>
<mml:mn>1</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mo>&#x22c5;</mml:mo>
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:mtext mathvariant="normal">PICK</mml:mtext>
<mml:mo>&#x22c5;</mml:mo>
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:mtext mathvariant="normal">SUB</mml:mtext>
<mml:mo>.</mml:mo>
</mml:math>
</disp-formula>
</p>
<p>Hence, <inline-formula id="inf48">
<mml:math id="m108">
<mml:msubsup>
<mml:mrow>
<mml:mi>l</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mtext>val</mml:mtext>
</mml:mrow>
<mml:mrow>
<mml:mi>i</mml:mi>
<mml:mo>,</mml:mo>
<mml:mn>0</mml:mn>
</mml:mrow>
</mml:msubsup>
</mml:math>
</inline-formula> puts the value assigned to &#xac;x<sub>r</sub> in the top of the stack (this value is obtained by subtracting the value assigned of x<sub>j</sub> from 1). Similarly, if u<sub>i,1</sub> &#x3d; x<sub>s</sub> for some s &#x2208; {0, &#x2026;, k}, then<disp-formula id="equ57">
<mml:math id="m109">
<mml:msubsup>
<mml:mrow>
<mml:mi>l</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mtext>val</mml:mtext>
</mml:mrow>
<mml:mrow>
<mml:mi>i</mml:mi>
<mml:mo>,</mml:mo>
<mml:mn>1</mml:mn>
</mml:mrow>
</mml:msubsup>
<mml:mo>&#x2254;</mml:mo>
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:msub>
<mml:mrow>
<mml:mtext mathvariant="normal">PUSH</mml:mtext>
</mml:mrow>
<mml:mrow>
<mml:mi>s</mml:mi>
<mml:mo>&#x2b;</mml:mo>
<mml:mn>1</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mo>&#x22c5;</mml:mo>
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:mtext mathvariant="normal">PICK</mml:mtext>
<mml:mo>.</mml:mo>
</mml:math>
</disp-formula>
</p>
<p>Thus, <inline-formula id="inf49">
<mml:math id="m110">
<mml:msubsup>
<mml:mrow>
<mml:mi>l</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mtext>val</mml:mtext>
</mml:mrow>
<mml:mrow>
<mml:mi>i</mml:mi>
<mml:mo>,</mml:mo>
<mml:mn>1</mml:mn>
</mml:mrow>
</mml:msubsup>
</mml:math>
</inline-formula> puts the value assigned to x<sub>s</sub> in the top of the stack. Notice that the operator OP_PUSH<sub>s&#x2b;1</sub> has to be used as the stack contains the extra value computed by the script <inline-formula id="inf50">
<mml:math id="m111">
<mml:msubsup>
<mml:mrow>
<mml:mi>l</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mtext>val</mml:mtext>
</mml:mrow>
<mml:mrow>
<mml:mi>i</mml:mi>
<mml:mo>,</mml:mo>
<mml:mn>0</mml:mn>
</mml:mrow>
</mml:msubsup>
</mml:math>
</inline-formula>. In the same way, if u<sub>i,1</sub> &#x3d; &#xac;x<sub>s</sub> for some s &#x2208; {0, &#x2026;, k}, then<disp-formula id="equ58">
<mml:math id="m112">
<mml:msubsup>
<mml:mrow>
<mml:mi>l</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mtext>val</mml:mtext>
</mml:mrow>
<mml:mrow>
<mml:mi>i</mml:mi>
<mml:mo>,</mml:mo>
<mml:mn>1</mml:mn>
</mml:mrow>
</mml:msubsup>
<mml:mo>&#x2254;</mml:mo>
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:msub>
<mml:mrow>
<mml:mtext mathvariant="normal">PUSH</mml:mtext>
</mml:mrow>
<mml:mrow>
<mml:mn>1</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mo>&#x22c5;</mml:mo>
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:msub>
<mml:mrow>
<mml:mtext mathvariant="normal">PUSH</mml:mtext>
</mml:mrow>
<mml:mrow>
<mml:mi>s</mml:mi>
<mml:mo>&#x2b;</mml:mo>
<mml:mn>2</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mo>&#x22c5;</mml:mo>
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:mtext mathvariant="normal">PICK</mml:mtext>
<mml:mo>&#x22c5;</mml:mo>
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:mtext mathvariant="normal">SUB</mml:mtext>
<mml:mo>,</mml:mo>
</mml:math>
</disp-formula>so that the value assigned to &#xac;x<sub>s</sub> is put in the top of the stack by <inline-formula id="inf51">
<mml:math id="m113">
<mml:msubsup>
<mml:mrow>
<mml:mi>l</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mtext>val</mml:mtext>
</mml:mrow>
<mml:mrow>
<mml:mi>i</mml:mi>
<mml:mo>,</mml:mo>
<mml:mn>1</mml:mn>
</mml:mrow>
</mml:msubsup>
</mml:math>
</inline-formula>. Moreover, <inline-formula id="inf52">
<mml:math id="m114">
<mml:msubsup>
<mml:mrow>
<mml:mi>l</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mtext>val</mml:mtext>
</mml:mrow>
<mml:mrow>
<mml:mi>i</mml:mi>
<mml:mo>,</mml:mo>
<mml:mn>2</mml:mn>
</mml:mrow>
</mml:msubsup>
</mml:math>
</inline-formula> is defined in the same way but considering that the stack contains the extra values computed by the scripts <inline-formula id="inf53">
<mml:math id="m115">
<mml:msubsup>
<mml:mrow>
<mml:mi>l</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mtext>val</mml:mtext>
</mml:mrow>
<mml:mrow>
<mml:mi>i</mml:mi>
<mml:mo>,</mml:mo>
<mml:mn>0</mml:mn>
</mml:mrow>
</mml:msubsup>
</mml:math>
</inline-formula> and <inline-formula id="inf54">
<mml:math id="m116">
<mml:msubsup>
<mml:mrow>
<mml:mi>l</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mtext>val</mml:mtext>
</mml:mrow>
<mml:mrow>
<mml:mi>i</mml:mi>
<mml:mo>,</mml:mo>
<mml:mn>1</mml:mn>
</mml:mrow>
</mml:msubsup>
</mml:math>
</inline-formula>. Finally,<disp-formula id="equ59">
<mml:math id="m117">
<mml:msub>
<mml:mrow>
<mml:mi>l</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mtext>add</mml:mtext>
</mml:mrow>
</mml:msub>
<mml:mo>&#x2254;</mml:mo>
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:mtext mathvariant="normal">ADD</mml:mtext>
<mml:mo>&#x22c5;</mml:mo>
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:mtext mathvariant="normal">ADD</mml:mtext>
<mml:mo>&#x22c5;</mml:mo>
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:mtext mathvariant="normal">VERIFY</mml:mtext>
<mml:mo>,</mml:mo>
</mml:math>
</disp-formula>which allows us to add the values for the three literals in the clause. If at least one of them is positive, the result is greater than 0 and the execution of OP_VERIFY is successful. Otherwise, the result is 0 and the execution of OP_VERIFY fails.<list list-type="simple">
<list-item>
<p>&#x2022; Finally, we have that:</p>
</list-item>
</list>
<disp-formula id="equ60">
<mml:math id="m118">
<mml:msub>
<mml:mrow>
<mml:mi>l</mml:mi>
</mml:mrow>
<mml:mrow>
<mml:mtext>end</mml:mtext>
</mml:mrow>
</mml:msub>
<mml:mo>&#x2254;</mml:mo>
<mml:mtext mathvariant="normal">OP</mml:mtext>
<mml:mtext>_</mml:mtext>
<mml:msub>
<mml:mrow>
<mml:mtext mathvariant="normal">PUSH</mml:mtext>
</mml:mrow>
<mml:mrow>
<mml:mn>1</mml:mn>
</mml:mrow>
</mml:msub>
<mml:mo>,</mml:mo>
</mml:math>
</disp-formula>which ensures that if l<sub>length</sub>, l<sub>binary</sub> and l<sub>sat</sub> are executed successfully, then the top element in the main stack is&#x20;1.</p>
<p>From the definition of l<sub>&#x3c8;</sub>, it is straightforward to prove that &#x3c8; is satisfiable if and only if l<sub>&#x3c8;</sub> is unlockable, and that l<sub>&#x3c8;</sub> can be constructed in polynomial time in the size of &#x3c8;. Hence, we have provided a polynomial-time reduction form 3SAT to the problem <sc>Unlockability of Script</sc>, thus showing that the latter is NP-hard.</p>
</statement>
</p>
</sec>
</sec>
<sec id="s5">
<title>5 Discussion and Future Work</title>
<p>In this work, we focused on Script, the scripting language of the Bitcoin protocol, and contribute to its understanding in three aspects:<list list-type="simple">
<list-item>
<p>&#x2022; First, we provided a formal mathematical model for Script, which we used to study its algorithmic properties and main characteristics.</p>
</list-item>
<list-item>
<p>&#x2022; Second, we (re)prove the folklore result stating that Script can be evaluated in <sc>Ptime</sc>.</p>
</list-item>
<list-item>
<p>&#x2022; And third, we showed that determining whether a script is unlockable is <sc>NP</sc>-hard.</p>
</list-item>
</list>
</p>
<p>These three advancements allow us to better understand Script, and provide some insight into the behavior of nodes on the Bitcoin network. First, we observe that the vast amount of scripts used in Bitcoin transactions only establish the most basic unlocking conditions. Intuitively, one of the main reasons for this is that the nodes in the network tend to favor standard locking scripts, because they guarantee that their executions will be short and efficient. Our formalization, together with the result on efficiently evaluating Script, actually tell us that this might be somewhat overly cautious, given that any Bitcoin script can be run efficiently by a node. On the other hand, if we are preoccupied with detecting unspendable outputs, for instance to remove them from the unspent transaction output (UTXO) pool, then the <sc>NP</sc>-hardness result tells us that sticking to standard scripts is indeed a safe tactic, since no efficient algorithm exists for checking whether an output is spendable (unless P&#x3d;&#x20;<sc>NP</sc>).</p>
<p>Looking ahead, we believe that further investigation into unlockability is necessary. As mentioned previously, unlockability is useful for two reasons: 1) a wallet creating a transaction would definitely want to discard unspendable outputs, or at least warn the user about them; and 2) network nodes would want to remove unspendable outputs form their UTXO pool. The <sc>NP</sc>-hardness result tells us that this, in principle, will not be possible. However, if we were able to also show that unlockability can be solved in <sc>NP</sc>, a SAT solver might be used to check Script unlockability. At this point in time, SAT solvers have advanced to the point that it is feasible to determine whether a formula is satisfiable for reasonable inputs, so that we might be able to use these techniques to check structural consistency of a Script (provided that the unlockability problem belongs to <sc>NP</sc>). Of course, here we would need to assume, as in any Bitcoin transaction, that the correct cryptographic data is provided by the recipient, thus allowing us to verify whether the Script has any logical errors using the SAT solver. Our conjecture at this point is that the unlockability problem indeed belongs to&#x20;<sc>NP</sc>.</p>
<p>Another direction worth pursuing would be to look for tractable fragments of Script in terms of the unlockability problem. Moreover, our formalization also allows to check whether a specific property is expressible using Script, which might be of interest when exploring smart contracts that could potentially be supported. Overall, we hope to make this work useful to the users wanting to specify non-trivial spending conditions, ultimately making the usage of non-standard scripts a more accepted practice.</p>
</sec>
</body>
<back>
<sec id="s6">
<title>Data Availability Statement</title>
<p>The original contributions presented in the study are included in the article/<xref ref-type="sec" rid="s11">Supplementary Material</xref>, further inquiries can be directed to the corresponding author.</p>
</sec>
<sec id="s7">
<title>Author Contributions</title>
<p>All authors listed have made an equal contribution to the work and approved it for publication.</p>
</sec>
<sec id="s8">
<title>Funding</title>
<p>This work was funded by ANID&#x2014;Millennium Science Initiative Program&#x2014;Code ICN17_002, and by Fondecyt grant 1191337.</p>
</sec>
<sec sec-type="COI-statement" id="s9">
<title>Conflict of Interest</title>
<p>The authors declare that the research was conducted in the absence of any commercial or financial relationships that could be construed as a potential conflict of interest.</p>
</sec>
<sec sec-type="disclaimer" id="s10">
<title>Publisher&#x2019;s Note</title>
<p>All claims expressed in this article are solely those of the authors and do not necessarily represent those of their affiliated organizations, or those of the publisher, the editors and the reviewers. Any product that may be evaluated in this article, or claim that may be made by its manufacturer, is not guaranteed or endorsed by the publisher.</p>
</sec>
<sec id="s11">
<title>Supplementary Material</title>
<p>The Supplementary Material for this article can be found online at: <ext-link ext-link-type="uri" xlink:href="https://www.frontiersin.org/articles/10.3389/fbloc.2021.770503/full#supplementary-material">https://www.frontiersin.org/articles/10.3389/fbloc.2021.770503/full&#x23;supplementary-material</ext-link>
</p>
<supplementary-material xlink:href="DataSheet1.PDF" id="SM1" mimetype="application/PDF" xmlns:xlink="http://www.w3.org/1999/xlink"/>
</sec>
<fn-group>
<fn id="FN1">
<label>1</label>
<p>This notion should not be confused with the more general notion of smart contract in Ethereum (<xref ref-type="bibr" rid="B11">Buterin et&#x20;al., 2014</xref>; <xref ref-type="bibr" rid="B12">Dannen, 2017</xref>), which has been developed based on a Turing-complete language (<xref ref-type="bibr" rid="B4">Atzei et&#x20;al., 2017</xref>; <xref ref-type="bibr" rid="B3">Antonopoulos and Wood, 2018</xref>).</p>
</fn>
<fn id="FN2">
<label>2</label>
<p>As we explain below, one does not necessarily provide a digital signature. This example serves for illustrative purposes&#x20;only.</p>
</fn>
<fn id="FN3">
<label>3</label>
<p>We use this for simplicity. Pay to script hash is by far the currently most used type of script, often encapsulating P2PKH.</p>
</fn>
<fn id="FN4">
<label>4</label>
<p>In other words, we assume that each binary string encodes an integer. Notice that in Bitcoin the integers are bounded by size, however, for complexity theoretic analysis it is natural to lift this restriction, since considering bounded size inputs makes all of the results trivial.</p>
</fn>
<fn id="FN5">
<label>5</label>
<p>In reality, Script has constraints over the size that its elements can occupy. Thus, if a number were to surpass this limit, an exception would be raised. However, we feel that it is important to work with a generalization of the language that does not constrain the size of the elements because the maximum size that is imposed is much larger than what a user would normally interact&#x20;with.</p>
</fn>
</fn-group>
<ref-list>
<title>References</title>
<ref id="B1">
<citation citation-type="book">
<person-group person-group-type="author">
<name>
<surname>Andrychowicz</surname>
<given-names>M.</given-names>
</name>
<name>
<surname>Dziembowski</surname>
<given-names>S.</given-names>
</name>
<name>
<surname>Malinowski</surname>
<given-names>D.</given-names>
</name>
<name>
<surname>Mazurek</surname>
<given-names>&#x141;.</given-names>
</name>
</person-group> (<year>2014</year>). &#x201c;<article-title>Modeling Bitcoin Contracts by Timed Automata</article-title>,&#x201d; in <conf-name>Formal Modeling and Analysis of Timed Systems - 12th International Conference, FORMATS 2014</conf-name>, <conf-loc>Florence, Italy</conf-loc>, <conf-date>September 8-10, 2014</conf-date>. Editors <person-group person-group-type="editor">
<name>
<surname>Legay</surname>
<given-names>A.</given-names>
</name>
<name>
<surname>Bozga</surname>
<given-names>M.</given-names>
</name>
</person-group> (<publisher-name>Springer</publisher-name>), <fpage>7</fpage>&#x2013;<lpage>22</lpage>. <comment>Proceedings of Lecture Notes in Computer Science</comment>. <pub-id pub-id-type="doi">10.1007/978-3-319-10512-3_2</pub-id> </citation>
</ref>
<ref id="B2">
<citation citation-type="book">
<person-group person-group-type="author">
<name>
<surname>Antonopoulos</surname>
<given-names>A. M.</given-names>
</name>
</person-group> (<year>2017</year>). <source>Mastering Bitcoin: Programming the Open Blockchain</source>. (<publisher-loc>Sebastopol, CA</publisher-loc>: <publisher-name>O&#x2019;Reilly Media, Inc.</publisher-name>) </citation>
</ref>
<ref id="B3">
<citation citation-type="book">
<person-group person-group-type="author">
<name>
<surname>Antonopoulos</surname>
<given-names>A. M.</given-names>
</name>
<name>
<surname>Wood</surname>
<given-names>G.</given-names>
</name>
</person-group> (<year>2018</year>). <source>Mastering Ethereum: Building Smart Contracts and Dapps</source>. (<publisher-loc>Sebastopol, CA</publisher-loc>: <publisher-name>O&#x2019;Reilly Media, Inc.</publisher-name>). </citation>
</ref>
<ref id="B4">
<citation citation-type="book">
<person-group person-group-type="author">
<name>
<surname>Atzei</surname>
<given-names>N.</given-names>
</name>
<name>
<surname>Bartoletti</surname>
<given-names>M.</given-names>
</name>
<name>
<surname>Cimoli</surname>
<given-names>T.</given-names>
</name>
</person-group> (<year>2017</year>). &#x201c;<article-title>A Survey of Attacks on Ethereum Smart Contracts (Sok)</article-title>,&#x201d; in <conf-name>Principles of Security and Trust - 6th International Conference, POST 2017, Held as Part of the European&#x20;Joint Conferences on Theory and Practice of Software, ETAPS 2017</conf-name>, <conf-loc>Uppsala, Sweden</conf-loc>, <conf-date>April 22-29, 2017</conf-date> (<publisher-name>Springer</publisher-name>), <fpage>164</fpage>&#x2013;<lpage>186</lpage>. <comment>Proceedings of Lecture Notes in Computer Science</comment>. <pub-id pub-id-type="doi">10.1007/978-3-662-54455-6_8</pub-id> </citation>
</ref>
<ref id="B5">
<citation citation-type="book">
<person-group person-group-type="author">
<name>
<surname>Atzei</surname>
<given-names>N.</given-names>
</name>
<name>
<surname>Bartoletti</surname>
<given-names>M.</given-names>
</name>
<name>
<surname>Cimoli</surname>
<given-names>T.</given-names>
</name>
<name>
<surname>Lande</surname>
<given-names>S.</given-names>
</name>
<name>
<surname>Zunino</surname>
<given-names>R.</given-names>
</name>
</person-group> (<year>2018a</year>). &#x201c;<article-title>Sok: Unraveling Bitcoin Smart Contracts</article-title>,&#x201d; in <conf-name>Principles of Security and Trust - 7th International Conference, POST 2018, Held as Part of the European Joint Conferences on Theory and Practice of Software, ETAPS 2018</conf-name>, <conf-loc>Thessaloniki, GreeceApril 14-20, 2018</conf-loc> (<publisher-name>Springer</publisher-name>), <fpage>217</fpage>&#x2013;<lpage>242</lpage>. <comment>Proceedings of Lecture Notes in Computer Science</comment>. <pub-id pub-id-type="doi">10.1007/978-3-319-89722-6_9</pub-id> </citation>
</ref>
<ref id="B6">
<citation citation-type="book">
<person-group person-group-type="author">
<name>
<surname>Atzei</surname>
<given-names>N.</given-names>
</name>
<name>
<surname>Bartoletti</surname>
<given-names>M.</given-names>
</name>
<name>
<surname>Lande</surname>
<given-names>S.</given-names>
</name>
<name>
<surname>Zunino</surname>
<given-names>R.</given-names>
</name>
</person-group> (<year>2018b</year>). &#x201c;<article-title>A Formal Model of Bitcoin Transactions</article-title>,&#x201d; in <conf-name>Financial Cryptography and Data Security - 22nd International Conference, FC 2018</conf-name>, <conf-loc>Nieuwpoort, Cura&#xe7;ao</conf-loc>, <conf-date>February 26-March 2, 2018</conf-date> (<publisher-name>Springer</publisher-name>), <fpage>541</fpage>&#x2013;<lpage>560</lpage>. <comment>Revised Selected Papers</comment>. <pub-id pub-id-type="doi">10.1007/978-3-662-58387-6_29</pub-id> </citation>
</ref>
<ref id="B7">
<citation citation-type="book">
<person-group person-group-type="author">
<name>
<surname>Bartoletti</surname>
<given-names>M.</given-names>
</name>
<name>
<surname>Zunino</surname>
<given-names>R.</given-names>
</name>
</person-group> (<year>2018</year>). &#x201c;<article-title>Bitml: A Calculus for Bitcoin Smart Contracts</article-title>,&#x201d; in <conf-name>Proceedings of the 2018 ACM SIGSAC Conference on Computer and Communications Security, CCS 2018</conf-name>, <conf-loc>Toronto, ON, Canada</conf-loc>, <conf-date>October 15-19, 2018</conf-date> (<publisher-name>ACM</publisher-name>), <fpage>83</fpage>&#x2013;<lpage>100</lpage>. </citation>
</ref>
<ref id="B8">
<citation citation-type="journal">
<person-group person-group-type="author">
<name>
<surname>Bartoletti</surname>
<given-names>M.</given-names>
</name>
<name>
<surname>Zunino</surname>
<given-names>R.</given-names>
</name>
</person-group> (<year>2019</year>). <article-title>Formal Models of Bitcoin Contracts: A Survey</article-title>. <source>Front. Blockchain</source> <volume>2</volume>, <fpage>8</fpage>. <pub-id pub-id-type="doi">10.3389/fbloc.2019.00008</pub-id> </citation>
</ref>
<ref id="B9">
<citation citation-type="web">
<collab>Bitcoin Wiki</collab> (<year>2021</year>). <article-title>Bitcoin Wiki - Script</article-title>. <comment>[Dataset]</comment>. <comment>Available at: <ext-link ext-link-type="uri" xlink:href="https://en.bitcoin.it/wiki/Script">https://en.bitcoin.it/wiki/Script</ext-link>
</comment> (<comment>Accessed February 15, 2021</comment>). </citation>
</ref>
<ref id="B10">
<citation citation-type="journal">
<person-group person-group-type="author">
<name>
<surname>Bonneau</surname>
<given-names>J.</given-names>
</name>
<name>
<surname>Miller</surname>
<given-names>A.</given-names>
</name>
<name>
<surname>Clark</surname>
<given-names>J.</given-names>
</name>
<name>
<surname>Narayanan</surname>
<given-names>A.</given-names>
</name>
<name>
<surname>Kroll</surname>
<given-names>J.&#x20;A.</given-names>
</name>
<name>
<surname>Felten</surname>
<given-names>E. W.</given-names>
</name>
</person-group> (<year>2015</year>). &#x201c;<article-title>Sok: Research Perspectives and Challenges for Bitcoin and Cryptocurrencies</article-title>,&#x201d; in <conf-name>2015 IEEE Symposium on Security and Privacy, SP 2015</conf-name>, <conf-loc>San Jose, CA, USA</conf-loc>, <conf-date>May 17-21, 2015</conf-date>, <fpage>104</fpage>&#x2013;<lpage>121</lpage>. <pub-id pub-id-type="doi">10.1109/sp.2015.14</pub-id> </citation>
</ref>
<ref id="B11">
<citation citation-type="journal">
<person-group person-group-type="author">
<name>
<surname>Buterin</surname>
<given-names>V.</given-names>
</name>
</person-group> (<year>2014</year>). <article-title>A next-generation smart contract and decentralized application platform</article-title>
<source>White Paper</source> <volume>3</volume> (<issue>37</issue>). </citation>
</ref>
<ref id="B12">
<citation citation-type="book">
<person-group person-group-type="author">
<name>
<surname>Dannen</surname>
<given-names>C.</given-names>
</name>
</person-group> (<year>2017</year>). <source>Introducing Ethereum and Solidity</source>, <volume>Vol. 318</volume>. (<publisher-loc>Berkeley, CA</publisher-loc>: <publisher-name>Springer</publisher-name>). </citation>
</ref>
<ref id="B13">
<citation citation-type="web">
<collab>Github</collab> (<year>2010</year>). <article-title>Script Implementation: Security Improvements</article-title>. <comment>[Dataset]</comment>. <comment>Available at: <ext-link ext-link-type="uri" xlink:href="https://github.com/bitcoin/bitcoin/commit/6ff5f718b6a67797b2b3bab8905d607ad216ee21">https://github.com/bitcoin/bitcoin/commit/6ff5f718b6a67797b2b3bab8905d607ad216ee21</ext-link>
</comment> (<comment>Accessed February 15, 2021</comment>). </citation>
</ref>
<ref id="B14">
<citation citation-type="book">
<person-group person-group-type="author">
<name>
<surname>Jansen</surname>
<given-names>M.</given-names>
</name>
<name>
<surname>Hdhili</surname>
<given-names>F.</given-names>
</name>
<name>
<surname>Gouiaa</surname>
<given-names>R.</given-names>
</name>
<name>
<surname>Qasem</surname>
<given-names>Z.</given-names>
</name>
</person-group> (<year>2019</year>). &#x201c;<article-title>Do smart Contract Languages Need to Be Turing Complete</article-title>,&#x201d; in <conf-name>Blockchain and Applications - International Congress, BLOCKCHAIN 2019</conf-name>, <conf-loc>Avila, Spain</conf-loc>, <conf-date>26-28 June, 2019</conf-date> (<publisher-name>Springer</publisher-name>), <fpage>19</fpage>&#x2013;<lpage>26</lpage>. <pub-id pub-id-type="doi">10.1007/978-3-030-23813-1_3</pub-id> </citation>
</ref>
<ref id="B15">
<citation citation-type="book">
<person-group person-group-type="author">
<name>
<surname>Klomp</surname>
<given-names>R.</given-names>
</name>
<name>
<surname>Bracciali</surname>
<given-names>A.</given-names>
</name>
</person-group> (<year>2018</year>). &#x201c;<article-title>On Symbolic Verification of Bitcoin&#x27;s Script Language</article-title>,&#x201d; in <conf-name>Data Privacy Management, Cryptocurrencies and Blockchain Technology - ESORICS 2018 International Workshops, DPM 2018 and CBT 2018</conf-name>, <conf-loc>Barcelona, Spain</conf-loc>, <conf-date>September 6-7, 2018</conf-date> (<publisher-name>Springer</publisher-name>), <fpage>38</fpage>&#x2013;<lpage>56</lpage>. <comment>Proceeding of Lecture Notes in Computer Science</comment>. <pub-id pub-id-type="doi">10.1007/978-3-030-00305-0_3</pub-id> </citation>
</ref>
<ref id="B16">
<citation citation-type="journal">
<person-group person-group-type="author">
<name>
<surname>Nakamoto</surname>
<given-names>S.</given-names>
</name>
</person-group> (<year>2008</year>). <article-title>Bitcoin: A Peer-To-Peer Electronic Cash System</article-title>. <comment>Technical Report</comment>, <comment>Manubot.</comment> </citation>
</ref>
<ref id="B17">
<citation citation-type="book">
<person-group person-group-type="author">
<name>
<surname>Narayanan</surname>
<given-names>A.</given-names>
</name>
<name>
<surname>Bonneau</surname>
<given-names>J.</given-names>
</name>
<name>
<surname>Felten</surname>
<given-names>E. W.</given-names>
</name>
<name>
<surname>Miller</surname>
<given-names>A.</given-names>
</name>
<name>
<surname>Goldfeder</surname>
<given-names>S.</given-names>
</name>
</person-group> (<year>2016</year>). <source>Bitcoin and Cryptocurrency Technologies - A Comprehensive Introduction</source>. (<publisher-loc>Princeton, NJ</publisher-loc>: <publisher-name>Princeton University Press</publisher-name>). </citation>
</ref>
<ref id="B18">
<citation citation-type="book">
<person-group person-group-type="author">
<name>
<surname>O&#x2019;Connor</surname>
<given-names>R.</given-names>
</name>
</person-group> (<year>2017</year>). &#x201c;<article-title>Simplicity: A New Language for Blockchains</article-title>,&#x201d; in <conf-name>Proceedings of the 2017 Workshop on Programming Languages and Analysis for Security, PLAS@CCS 2017</conf-name>, <conf-loc>Dallas, TX, USA</conf-loc>, <conf-date>October 30, 2017</conf-date> (<publisher-name>ACM</publisher-name>), <fpage>107</fpage>&#x2013;<lpage>120</lpage>. </citation>
</ref>
<ref id="B19">
<citation citation-type="journal">
<person-group person-group-type="author">
<name>
<surname>Singh</surname>
<given-names>A.</given-names>
</name>
<name>
<surname>Parizi</surname>
<given-names>R. M.</given-names>
</name>
<name>
<surname>Zhang</surname>
<given-names>Q.</given-names>
</name>
<name>
<surname>Choo</surname>
<given-names>K.-K. R.</given-names>
</name>
<name>
<surname>Dehghantanha</surname>
<given-names>A.</given-names>
</name>
</person-group> (<year>2020</year>). <article-title>Blockchain Smart Contracts Formalization: Approaches and Challenges to Address Vulnerabilities</article-title>. <source>Comput. Security</source> <volume>88</volume>, <fpage>101654</fpage>. <pub-id pub-id-type="doi">10.1016/j.cose.2019.101654</pub-id> </citation>
</ref>
</ref-list>
</back>
</article>