\documentclass[11pt]{article}

\def\shownotes{1}
\def\notesinmargins{0}

\usepackage{fullpage}

\usepackage{mathtools,color,xcolor,hyperref,graphicx,wrapfig,listings,array,xspace}

\ifnum\shownotes=1
\ifnum\notesinmargins=1
\newcommand{\authnote}[2]{\marginpar{\parbox{\marginparwidth}{\tiny %
  \textsf{#1 {\textcolor{blue}{notes: #2}}}}}%
  \textcolor{blue}{\textbf{\dag}}}
\else
\newcommand{\authnote}[2]{
  \textsf{#1 \textcolor{blue}{: #2}}}
\fi
\else
\newcommand{\authnote}[2]{}
\fi

\newcommand{\lnote}[1]{{\authnote{\textcolor{orange}{Leo notes}}{#1}}}
\newcommand{\knote}[1]{{\authnote{\textcolor{green}{kushti notes}}{#1}}}
\newcommand{\mnote}[1]{{\authnote{\textcolor{red}{Morphic}}{#1}}}
\newcommand{\dnote}[1]{{\authnote{\textcolor{brown}{Dima notes}}{#1}}}

\newcommand{\ret}{\mathsf{ret}}
\newcommand{\new}{\mathsf{new}}
\newcommand{\hnew}{h_\mathsf{new}}
\newcommand{\old}{\mathsf{old}}
\newcommand{\op}{\mathsf{op}}
\newcommand{\verifier}{\mathcal{V}}
\newcommand{\prover}{\mathcal{P}}
\newcommand{\key}{\mathsf{key}}
\newcommand{\nextkey}{\mathsf{nextKey}}
\newcommand{\node}{\mathsf{t}}
\newcommand{\parent}{\mathsf{p}}
\newcommand{\leaf}{\mathsf{f}}
\newcommand{\vl}{\mathsf{value}}
\newcommand{\balance}{\mathsf{balance}}
\newcommand{\lft}{\mathsf{left}}
\newcommand{\rgt}{\mathsf{right}}
\newcommand{\lbl}{\mathsf{label}}
\newcommand{\direction}{\mathsf{d}}
\newcommand{\oppositedirection}{\bar{\mathsf{d}}}
\newcommand{\found}{\mathsf{found}}
\newcommand{\mypar}[1]{\smallskip\noindent\textbf{#1.}\ \ \ }
\newcommand{\ignore}[1]{}

\newcommand{\langname}{ErgoScript\xspace}
\newcommand{\lst}[1]{\text{\lstinline[basicstyle={\ttfamily}]$#1$}}

\newcommand{\andnode}{\ensuremath{\mathsf{AND}}}
\newcommand{\ornode}{\ensuremath{\mathsf{OR}}}
\newcommand{\tnode}{\ensuremath{\mathsf{THRESHOLD}}}
\newcommand{\GF}{\ensuremath{\mathrm{GF}}}

\begin{document}

\title{\langname, a Cryptocurrency Scripting Language\\Supporting Noninteractive Zero-Knowledge Proofs}

\author{authors}

\maketitle

\begin{abstract}
This paper describes \langname, a powerful and protocol-friendly scripting language for cryptocurrencies. Programs in \langname are used to specify the conditions under which currency can be spent. The language supports a type of non-interactive zero-knowledge proofs called $\Sigma$-protocols and is flexible enough to allow for ring-signatures, multisignatures, multiple currencies, atomic transactions, self-replicating scripts, and long-term computation. \lnote{this list of features could use some improvement}
\end{abstract}

\section{Introduction}
\subsection{Background}

Since its early days, Bitcoin~\cite{Nak08} has allowed more than simple money transfers between two public keys: its Bitcoin Script scripting language has allowed participants to specify conditions for how money could be spent. A program written in Bitcoin Script is attached to every transaction output (i.e., amount received); this program protects the transaction by determining how the transaction output can be used as an input to (i.e., spent in) a future transaction. The simplest condition is specified by a program that contains the recipient's public key and states that the money can be spent by creating a signature that verifies under this key.  However, more general conditions are allowed by more sophisticated programs.

The Bitcoin Script language is a primitive stack-based language without loops. \lnote{link or reference needed for bitcoin script} To spend an output protected by a program, a spending transaction must provide a program in the same language, and the concatenation of the two programs must evaluate to \emph{true}. The creator of the spending transaction can be viewed as a prover (for example, proving knowledge of the secret key by producing a signature), where the statement that needs to be proven is specified by the output that is being spent. Transaction validity is verified by evaluating programs. Bounded validation time is ensured by the absence of loops in the programming language and a maximum program size of 10 kilobytes. Even so, some denial-of-service attacks exploiting script validation time have appeared. \knote{links} On the other hand, the deliberate simplicity of the programming language limits the kinds of contracts that can be created on the Bitcoin platform.

On other end of the generality spectrum, Ethereum allows for arbitrary Turing-complete programs \lnote{reference needed for the language}. This approach requires charging for computation in order to prevent denial-of-service attacks, because the running time of a Turing-complete program cannot, in general, be estimated without actually running the program.

A variety of cryptocurrency languages have appeared. We do not survey them here, but refer the reader to \cite[p. 11]{Scilla}. \lnote{if time, can talk about Simplicity, Plutus, TypeCoin, Rholang, Scilla \dots}

\subsection{Our Contribution: \langname}
In this paper we introduce a new language called \langname that is specifically designed to be friendly to cryptographic protocols and applications. \langname is considerably more powerful than Bitcoin Script. As \langname contains no looping or recursive constructs, individual scripts in \langname are not Turing-complete.  In fact, given a program in \langname, it is easy to obtain an estimate of its running time (see \ref{sec:runningtime}). However, because \langname allows for self-replication, \langname can be used to create Turing-complete processes in a blockchain, as shown in \cite{CKM18} (see  Section \ref{sec:self-replicating}).

\paragraph{Built-in $\Sigma$-protocols}
Our new language incorporates proving and verifying as first-class primitives, giving developers to a subclass of cryptographic proof systems known as non-interactive $\Sigma$-protocols (pronounced ``sigma-protocols'').   Thus, a script protecting a transaction output can contain statements ($\Sigma$-statements) that need to proven (by producing $\Sigma$-proofs) in order to spend the output.

Conceptually, $\Sigma$-proofs \cite{Cra96} are generalizations~\cite{CL06} of digital signatures.
In fact, Schnorr signature scheme~\cite{Sch91} (whose more recent version is popularly known as EdDSA \cite{BDLSY12,rfc8032}) is the canonical example of a $\Sigma$-proof: it proves that the recipient knows the discrete logarithm of the public key (the proof is attached to a specific message, such as a particular transaction, and thus becomes a signature on the message; all $\Sigma$-proofs described here are attached to specific messages). $\Sigma$-protocols exist for proving a variety of properties and, importantly for \langname, elementary $\Sigma$-protocols can be combined into more sophisticated ones using the techniques of \cite{CDS94}. For an introduction to $\Sigma$-protocols, we refer the reader to \cite{Dam10} and \cite[Chapter 6]{HL10}.

\langname provides two elementary $\Sigma$-protocols over a group of prime order (such as an elliptic curve), written here in multiplicative notation:
\begin{itemize}
\item A proof of knowledge of discrete logarithm with respect to a fixed group generator: given a group element $h$, the proof convinces a verifier that the prover knows $w$ such that $h=g^w$, where $g$ is the group generator (also known as base point), without revealing $w$. This is the same as a Schnorr signature with public key $h$.
\item A proof that of equality of discrete logarithms (i.e., a proof of a Diffie-Hellman tuple): given group elements $g_1, g_2, u_1, u_2$, the proof convinces a verifier that the prover knows $w$ such that $u_1=g_1^w$ and $u_2=g_2^w$, without revealing $w$
\end{itemize}
\lnote{This is not the notation used in the code, but in the code, $g$ is overloaded verloaded because it's the base point in item 1 and an arbitrary point in item 2; $h$ is also overloaded. Perhaps we should change the code to better notation and then make this text match it.}

\langname also provides the ability to build more sophisticated $\Sigma$-protocols by using connectives $\andnode$, $\ornode$, and $\tnode$ (also known as $k$-out-of-$n$).
Crucially, the proof for an $\ornode$ and a $\tnode$ connective does not reveal which of the relevant values the prover knows: for example, in \langname a ring signature by public keys $h_1, \dots, h_n$ can be specified as an $\ornode$ of $\Sigma$-protocols for proving knowledge of discrete logarithms of $h_1, \dots, h_n$. The proof can be constructed with the knowledge of just one such discrete logarithm, and does not reveal which one was used in its construction.

Our implementation of these protocols is in Scala \cite{scala} and Java \cite{java}. The implementation was informed by SCAPI \cite{scapi}, but does not use SCAPI code. \lnote{our code currently has subdirectories named ``scapi'' so it's hard to say we don't use it\dots} We use Bouncy Castle \cite{bouncycastle} for big integer and elliptic curve operations; the implementation of arithmetic in fields of characteristic 2 (for $\tnode$ connectives) is our own. \lnote{any other credits or background info?}

\paragraph{Rich context, enabling self-replication}
In addition to $\Sigma$-protocols, \langname allows for predicates over the state of the blockchain and the current transaction. These predicates can be combined, via Boolean connectives, with $\Sigma$-statements, and are used during transaction validation. The set of predicates is richer than in Bitcoin, but still lean in order to allow for efficient processing even by light clients. Like in Bitcoin, we allow the use of current height of the blockchain; unlike Bitcoin, we also allow the use of information contained in the spending transaction, such as inputs it is trying to spend and outputs it is trying to create. This feature enables self-replication and sophisticated (even Turing-complete) long-term script behaviour, as described in examples below.

\langname is statically typed (with compile-time type checking) and allows the usual operations, such as integer arithmetic.

\paragraph{Running time estimation and safety checks}
\lnote{someone should fill this in, because I know very little about it}
See Section \ref{sec:safety} for more details.

\section{\langname Language Description}

\lnote{Should we add, for every code example, a link to the code where it appears? That would help the reader.}

The language syntax is similar to Scala, and therefore many of the constructs are easy to read for those familiar with Scala.

Before we describe the language, let us fix some terminology. A \emph{box} (often called a ``coin'' in other literature) contains some amount (\emph{value}, measured in Ergo tokens) and is protected by a \emph{script} (boxes also contain additional information, such as other tokens; this information is described in detail in Section \ref{sec:box-registers}). A \emph{transaction} spends the value of boxes that are its \emph{inputs} (which are outputs of some earlier transaction) and produces boxes that are its \emph{outputs}. In a given transaction, the sum of the values of the inputs must equal the sum of the values of the outputs (as we describe below, the scripting language is rich enough to allow for payment transactions fees and for minting of new coins without violating this rule).

All the unspent transaction outputs (\emph{UTXO}) at a given time represent the value stored in the blockchain. A script for a box must evaluate to ``true'' when this box is used as an input to a transaction. This evaluation is helped by a \emph{proof} (for $\Sigma$-statements) and a \emph{context}, which are part of the transaction. The proof is produced by someone who knows the relevant secrets, such as secret keys; the context contains information about the transaction, such as details of its inputs and outputs, and the current state of the blockchain, such as the current number of blocks (height) and the root of the Merkle tree that contains the UTXO set.
\dnote{This should change in future, e.g. fixed number of last headers is going to be added here (and header contains height and root hash).} \lnote{adjust this as needed}

\subsection{$\Sigma$-Statements}

\lnote{every script example here should be also in our test code exactly as written, to make sure our own paper passes our own tests. These should be edited as the language evolves.}

\lnote{If we want to show examples of the underlying syntax tree to which the language gets compiled, we can to that here, in parallel with examples in the language}

The simplest script allows the owner of a public key to spend an output box in a future transaction by issuing a signature with the corresponding secret key. If the variable \texttt{pk} holds the public key, then this script is specified simply as a string
\begin{verbatim}
        pk
\end{verbatim}

In order for the compiler to know what value the variable \texttt{pk} is referring to, the compiler needs to be supplied with an \emph{environment}, which, in this case, is a single-element map, mapping the string \texttt{"pk"} to the object holding the public key.\footnote{This map is an object in Scala, and is passed to the compiler as a parameter together with the script (which is passed in as a string) when the compiler is invoked from within Scala code. We postpone the discussion of how to invoke the compiler outside of Scala code.\lnote{we should add this discussion at some point}}
Thus, the constant public key is hardwired into the script at compile time. When the script is later evaluated (i.e., when the box is used as a transaction input), a $\Sigma$-proof of knowledge of the corresponding secret key must be supplied by the prover.

A slightly more complex script may allow either one of two people to spend an box. If Alice owns public key \texttt{pkA}  and Bob owns public key \texttt{pkB} (with corresponding secret key \texttt{skA} and \texttt{skB}), then the script that would allow either one of them to spend the box is
\begin{verbatim}
        pkA || pkB
\end{verbatim}
Again, \texttt{pkA} and \texttt{pkB} need to mapped to public key objects by an environment map.
Note that Alice and Bob individually can construct the proof necessary to spend this box using just one of the two corresponding secret keys, and, by the zero-knowledge property of $\Sigma$-protocols, the proof will not reveal whether \texttt{skA} or \texttt{skB} was used. This construct is known as a \emph{ring} signature.

Naturally, this approach can be extended to more than two keys. If Carol's public and secret keys are \texttt{pkC} and \texttt{skC}, then a three-key ring signature can be similarly constructed as
\begin{verbatim}
        pkA || pkB || pkC
\end{verbatim}

For syntactic convenience, multiple keys can be placed into an array, and \texttt{anyOf} operator can be used instead of \texttt{||}, as follows:
\begin{verbatim}
        anyOf (Array (pkA, pkB, pkC))
\end{verbatim}

A conjunction is also possible: the script
\begin{verbatim}
        pkA && pkB
\end{verbatim}
requires Alice and Bob to use secret keys corresponding to \texttt{pkA} and \texttt{pkB} in order to spend the box. Note that Alice and Bob will have to communicate to produce the proof: separate signatures by Alice and Bob will not be sufficient (but Alice and Bob will not have to reveal their secret keys to each other; see Section~\ref{sec:proving}). Similarly to \texttt{||}, multiple \texttt{\&\&} can be used in sequence, and the operator \texttt{allOf} can be used for arrays.

Using these operators, it is possible to produce more sophisticated scripts. For example, here is a script stating that the box can be spent either by Carol or by a collaboration between Alice and Bob:

\begin{verbatim}
        (pkA && pkB) || pkC
\end{verbatim}

A valid proof (contained in the spending transaction) will not reveal which of two possibilities was used.

Operators \texttt{allOf} and \texttt{anyOf} are actually special cases of the operator \texttt{atLeast(bound, array)}, which requires the prover to know secrets for $\texttt{bound}$ elements of the \texttt{array} (just in like in \texttt{anyOf}, which secrets the prover used will not be revealed by the proof). \texttt{allOf(array)} is the same as \texttt{atLeast(array.size, array)} and $\texttt{anyOf(array)}$ is the same as \texttt{atLeast(1, array)}.

For example, here is a script stating that the box can be spent by any 3 out of the following 6 possibilities: Alice, Bob, Charlie, David and Edie, Fran and George, Helen and Irene:
\begin{verbatim}
        atLeast(3, Array (pkA, pkB, pkC, pkD && pkE, pkF && pkG, pkH && pkI))
\end{verbatim}
The same result could be achieved by writing an \texttt{anyOf} of all possible 3-out-of-6 (twenty) combinations.

\lnote{should probably do a diffie-hellman example, and maybe another one below with getting some of the DH values from a context. E.g., $g_1$ is just $g$, $g_2$ is $pk_A$, $h_1$ is a hash of a message in a context, and $h_2$ is from the context. }

\subsection{Mixing $\Sigma$-statements with other statements}
\langname allows combining statements that require proofs with other boolean statements. These statements can refer to the \emph{context}, which has predefined variables with information about the transaction in which the script is evaluated (i.e., the box is spent). For example,

\begin{verbatim}
   pkA || pkB || (pkC && HEIGHT > 500)
\end{verbatim}
uses the predefined variable HEIGHT, which is the sequential block number (since the beginning of the blockchain, starting at 0)
of the block in which the script is evaluated.
This script allows Alice or Bob to spend the box before \texttt{HEIGHT} reaches 501, and Alice, Bob, or Carol to spend the box after that. If the height has not reached 501 and the box is spent, then the proof reveals that \texttt{skA} or \texttt{skB} was used in its construction, but does not reveal which one of the two. If \texttt{HEIGHT} is greater than 500, then the proof does not reveal which of the three secret keys was used. Thus, depending on the value of \texttt{HEIGHT}, the script becomes either equivalent to \texttt{pkA || pkB} or equivalent to \texttt{pkA || pkB || pkC}.

In general, script evaluation reduces the script to a $\Sigma$-statement by first evaluating all the Boolean predicates that are not $\Sigma$-statements. As we saw in the above example, the resulting $\Sigma$-statement will, in general, depend on the values of the Boolean predicates (such as whether \texttt{HEIGHT > 500}).

We emphasize that this evaluation is not the same as the usual left-to-right lazy evaluation of logical expressions, because expressions involving $\Sigma$-statements are not treated the same way as usual boolean expressions: they are evaluated last and in zero-knowledge. In fact, $\texttt{pkA}$ is not of type \texttt{Boolean} \lnote{do we use \texttt{Boolean} or \texttt{Bool}?}. It is of type \texttt{GroupElement}; the compiler automatically converts it to \texttt{proveDlog(\texttt{pkA})}, which is of type \texttt{ProveDlog}. Type   \texttt{ProveDlog} is special because it is used differently by the prover (who constructs the proof) and the verifier (who checks it); moreover, variables of this type cannot be stored in boxes (Section \ref{sec:context}) or context extensions (Section \ref{sec:extension}). \lnote{the type system is undergoing changes, so this needs fixing}

\lnote{Should we have an example with fees? According to Dima, fees are implemented as boxes with TrueLeaf as a proposition, last transaction in a block consumes all this just created boxes and in favor of miner.}

\subsection{Accessing the Context and Box Contents}
\label{sec:context}
In addition to the predefined variable \texttt{HEIGHT}, the context contains predefined arrays \texttt{INPUTS} and \texttt{OUTPUTS}, which refer to the inputs and outputs of the transaction. Elements of these arrays are of type \texttt{Box}. The script also has access to its own box via the context variable \texttt{SELF} of type \texttt{Box}. Note that \texttt{SELF} is also an element of the \texttt{INPUTS} array, because the script is executed when the its box is being spent.

To access information inside a box \texttt{b}, scripts can use \texttt{b.value} for the amount, \texttt{b.propositionBytes} for the protecting script, and \texttt{b.id} for the identifier of the box, which is the BLAKE2b-256 hash of the contents of the box. Boxes include additional information in \emph{registers};  each box is unique, because ones of its registers includes the transaction id in which it was created as an output, and its own index in the \texttt{OUTPUTS} array, accessible through \texttt{b.R3} (see Section \ref{sec:box-registers} for more on registers).

\lnote{ The comments in ErgoBox.scala says something about a unique nonce, but that doesn't seem to be matched by code. }

\paragraph{Example: two boxes together}
Access to this information allows us, for example, to create an output box that can be spent only in the same transaction as another output box, and only if no other inputs are present in the transaction. If \texttt{friend} stands for an already existing box (per the environment mapping), then we create a new box that can be spent only together with \texttt{friend} and no other input by the following script (note that it uses the array property \texttt{size} and array indexing, starting at 0, denoted by parentheses):

\begin{verbatim}
        INPUTS.size == 2 && INPUTS(0).id == friend.id
\end{verbatim}

Note that the script does not prevent the \texttt{friend} box from being spent on its own, in which case the output box protected by the script above will become not spendable.

We can be more permissive and allow for other inputs in addition to the friend box. To do so, we will examine the input array using the \texttt{exists} operator, which applies a boolean function to each array element until it finds one that satisfies the function or finds that none exists. To define a function, we use \texttt{fun} keyword; the argument type (in this case \texttt{Box}) is specified with a colon after the argument name \texttt{inputBox}. We name the function using the \texttt{let} keyword.
\begin{verbatim}
        {
                let isFriend = fun (inputBox: Box) = {inputBox.id == friend.id}
                INPUTS.exists (isFriend)
        }
\end{verbatim}

This is our first example of a script with more than one statement; note that such scripts require braces, and their output is determined by the last statement.
It can also be written in one statement, as follows:
\begin{verbatim}
        INPUTS.exists (fun (inputBox: Box) = {inputBox.id == friend.id})
\end{verbatim}

\paragraph{Example: crowdfunding}
Access to the context allows us to create a script for the following crowdfunding situation: a project backer (with key  \texttt{backerPubKey}) wishes to give money to a project (with key \texttt{projectPubKey}), but only if the project raises enough money (at least \texttt{minToRaise}) from other sources by a deadline (expressed in terms of \texttt{HEIGHT}).

To give money to the project, the backer will create an output box protected by the following script. The script contains two conditions: one for the case the deadline has passed (enabling the backer to get the money back) and one for the case it succeeded (enabling the project to spend the money if the amount is at least \texttt{minToRaise} before the deadline).  In order to ensure enough money has been raised, the script will search the output array for a box with a sufficient value going to the \texttt{projectPubKey}. To check where the value of the output box is going, the script will read the script protecting the output box and compare it to the script corresponding to \texttt{proveDlog(projectPubKey)}; this script can be obtained by \texttt{projectPubKey.propBytes}.

\begin{verbatim}
        {
                let fundraisingFailure = HEIGHT >= deadline && backerPubKey
                let enoughRaised = fun(outBox: Box) = {
                        outBox.value >= minToRaise &&
                        outBox.propositionBytes == projectPubKey.propBytes
                }
                let fundraisingSuccess = HEIGHT < deadline &&
                         projectPubKey &&
                         OUTPUTS.exists(enoughRaised)

                fundraisingFailure || fundraisingSuccess
        }
\end{verbatim}

As before, the values of \texttt{deadline}, \texttt{minToRaise}, and the two public keys are defined by the environment map and hardwired into the script at compile time.

\subsection{Context Extension and Hashing}
\label{sec:extension}
A context can also contain typed variables that can be retrieved by numerical id using the operator \texttt{getVar}. These variables are supplied by the prover specifically for a given input box (via a \texttt{ContextExtension}) together with the proof for that box. The id can be any one-byte value (from -128 to 127) and is scoped for each box separately (so variable with id 17 for one input box in a transaction is not the same as variable with id 17 for another input box in the same transaction).

Such context enxtensions can be useful, for example, for requiring a spending transaction to produce hash preimages (the BLAKE2b-256 and SHA-256 hash functions can invoked in \langname, using keywords \texttt{blake2b256} and \texttt{sha256}). For example,
\begin{verbatim}
       pkA && blake2b256(getVar[Array[Byte]](1)) ==  hashOutput
\end{verbatim}
says that spending can be done only using the signature of Alice, and only if the preimage of \texttt{hashOutput} is written in the context. Specifically, the script requires that the context extension should contain a variable (with id \texttt{1}), which is an array of bytes that hashes to the value of \texttt{hashOutput} (the value of \texttt{hashOutput}, like \texttt{pkA}, is defined in the environment and is hardwired into the script at compile time).  Note that although the script requires both the secret key corresponding to \texttt{pkA} and the hash preimage corresponding to \texttt{hashOutput}, there is the stark difference between how these two values are used: the secret key is not revealed in the proof (by the zero-knowledge property of $\Sigma$-proofs), while the hash preimage is explicitly written into the context extension and can be seen by anyone once the transaction takes place.

\paragraph{Example: atomic transactions and cross-chain trading}
Suppose there are two separate blockchains, for two different asset types. Alice wants to receive some assets in her blockchain in exchange for giving some assets to Bob in his blockchain. \langname allows to accomplish in a simpler way than proposed for Bitcoin, for example, in \cite{Nol13}.
\lnote{is this the right text to go along with the reference to \cite{Nol13}?}

Alice creates a random secret \texttt{x} of 256 bits (32 bytes), hashes it to obtain the value \texttt{hx}, and creates a transaction in Bob's blockchain with the output box protected by the following script:
\begin{verbatim}
        anyOf( Array(
                HEIGHT > deadlineBob && pkA,
                pkB && blake2b256(getVar[Array[Byte]](1)) == hx
        ))
\end{verbatim}
Bob can receive the value of this box only upon presentation of a hash preimage of \texttt{hx}. Alice can reclaim it after \texttt{deadlineBob}.

From this output, Bob learns \texttt{hx}. He creates a transaction in Alice's blockchain with an output box protected by the following script:
\begin{verbatim}
        anyOf( Array(
                HEIGHT > deadlineAlice && pkB,
                allOf( Array(
                        pkA,
                        getVar[Array[Byte]](1).size<33,
                        blake2b256(getVar[Array[Byte]](1)) == hx
                ))
        ))
\end{verbatim}

If Alice is satisfied with the amount Bob is giving her, she claims the value of this box by revealing \texttt{x}. Alice is protected as long as the hash function is one-way and she keeps her \texttt{x} secret until she claims the value of this box. (She should be careful to submit her transaction in enough time before \texttt{deadlineAlice} to make sure it gets processed before Bob can reclaim this money, because once she submits the transaction, \texttt{x} is public and thus, if the \texttt{deadlineAlice} passes before the transaction is processed, Bob can both reclaim this box and claim the box Alice left in his blockchain.)

Bob is protected, because in order for Alice to claim the value of this box, she must present a hash preimage of \texttt{hx} as a context extension in the transaction that uses this box as input. But once she does, Bob also learns this hash preimage, and is able to claim the value of the box that Alice placed into his blockchain. Note that Bob needs to choose \texttt{deadlineAlice} early enough to make sure that he is able to learn the preimage of \texttt{hx} from the transaction in Alice's block chain, and create a transaction in his blockchain, all before \texttt{deadlineBob} that Alice chose. Note also that \texttt{HEIGHT} in the two scripts is with respect to two different blockchains, which may be growing at a different rate. Bob also needs to make sure that he can use Alice's \texttt{x} as a context extension; to make sure Alice cannot cheat by making this \texttt{x} so long that it will not be allowed as a context extension in his blockchain, he uses the constraint \texttt{getVar[Array[Byte]](1).size<33}.

The same approach can be used to trade different assets on the same blockchain, in case of multiasset blockchains. However, for transactions on a single blockchain, an alternative approach is also possible. We describe it below.

\subsection{Box Registers and Additional Tokens}
\label{sec:box-registers}
In addition to its value and protecting script, a box can contain up to 10 numbered registers, \texttt{R0} through \texttt{R9}. The first four of these have fixed meaning, as follows. For a box \texttt{b}, \texttt{b.R0} is the same as \texttt{b.value} and \texttt{b.R1} is the same as \texttt{b.propositionBytes}.

The third register, \texttt{b.R2}, is for specifying additional, secondary tokens contained in the box (the primary token amount is specified in \texttt{b.value}). \texttt{b.R2} contains an array of pairs, the first element of each pair specifying the token id (as a byte string) and the second element specifying the amount (as a long constant). The maximum number of tokens in a box is set to 4. For every token id, the sum of amounts in inputs boxes should equal the sum of amounts in output boxes. There is one exception to this rule for the creation of new tokens. When a new token type gets created in a transaction, its id is equal to the id of the input box 0. Thus, the exception for the creation of new tokens is that if the token id in some output box is equal to the id of input box 0, then an arbitrary amount of this token can be output. Because each box has a unique id (see Section~\ref{sec:context}, this exception can be applied exactly once per token type. A newly created token can be emitted in a time-controlled fashion---see Section~\ref{sec:self-replicating}.

The fourth register, \texttt{b.R3}, contains a 34-byte array. This array specifies the 32-byte transaction id \lnote{how is transaction id computed?} where this box appears as an output followed by a 2-byte sequence number of this box in the \texttt{OUTPUTS} array of that transaction. This ensures that each box has unique \texttt{R3} and therefore a unique \texttt{id} as long as there are no hash collisions (because the \texttt{id} of the box is computed by hashing its content, including \texttt{R3}).

The remaining six registers can be used arbitrarily.

To access a register, the type of the register needs to be specified in brackets following the register number (for example, \texttt{b.R4[Int]}). Note that \texttt{b.R4[T]} is of type \texttt{Option[T]}; \texttt{b.R4[T].isDefined} indicates whether it actually contains a value of type \texttt{T}, and \texttt{b.R4[T].get} obtains this value.

In addition to registers, scripts can access two serialized versions of the box: \texttt{b.bytes} is a serialization of the entire box including the value, all the registers, and the script \lnote{anything else?}, and \texttt{b.byteWithNoRef}, which the same but without \texttt{R3} (so that a box can be viewed independently of where it appeared \lnote{is there a good reason someone would need this? Can we explain it here?}). \lnote{Are there any other box properties that scripts can access?}

\paragraph{Example: atomic exchange on a single block chain}
These box registers provide additional capabilities to \langname. Consider, for example, Alice and Bob who want to exchange tokens: they agree that  Alice will give Bob 60 tokens of type \texttt{token1} (this type is mapped an actual token id in the environment map) in exchange for 100 Ergo tokens. Alice could create an output box with value 100 and protect it with following script:

\begin{verbatim}
  (HEIGHT > deadline && pkA) || {
    val tokenData = OUTPUTS(0).R2[Array[(Array[Byte], Long)]].get(0)
    allOf(Array(
        tokenData._1 == token1,
        tokenData._2 >= 60L,
        OUTPUTS(0).propositionBytes == pkA.propBytes,
        OUTPUTS(0).value >= 1L
    ))
  }
\end{verbatim}

This script ensures that the box can be spent only in a transaction that produces an output with 60 tokens of type token1 and gives them to Alice (Alice can reclaim the box after the deadline).

Bob, similarly, could create an output box with value 0
\lnote{for some reason the example in the code we want value 1 --- why? It's not explained. Similarly, why do we need \texttt{OUTPUTS(0).value >= 1L} in the script above? } and 60 tokens of type \texttt{token1} and protect it by the following script:
\begin{verbatim}
        (HEIGHT > deadline && pkB) ||
        allOf( Array(
                OUTPUTS(1).value >= 100,
                OUTPUTS(1).propositionBytes == pkB.propBytes
         ))
\end{verbatim}

\lnote{Is the \texttt{L} after constants 60, 1, and 100 necessary? Won't conversion happen automatically? Some constants in other scripts above that probably need to be long, like 100 for height, don't have it. We should be consistent and clarify this for the reader. Also, make sure that scripts here match testing code.}

A transaction containing these two boxes as inputs must produce two outputs: the first giving at least 60 tokens of type1 to Alice and the second giving at least 100 tokens of type2 to Bob. Once the two boxes are on the blockchain, anyone can create such a transaction using the two boxes as inputs, and thus effect the exchange between Alice and Bob. Unlike the cross-chain trading example above using hashing (which requires one side to go first), there are no potential problems with synchronization here, because the exchange will happen in a single transaction or will not happen at all.

We caution that for security, Alice cannot have two such boxes outstanding at any given time, because they can be both used in a single transaction that contains just one output with 60 tokens of type ``token1" --- the script of each box will be individually satisfied, but Alice will get less only half of what owed to her. Same for Bob.

\lnote{this seems like a pretty big security vulnerability and we should highlight it and show how to fix it. Restricting the number of inputs and outputs to just 2 is not enough. For example, suppose Alice has another box C in the UTXO with value 100 Ergo and 60 token1, and the following script:}
\begin{verbatim}
  (HEIGHT > deadline && pkA) || {
    val tokenData = OUTPUTS(0).R2[Array[(Array[Byte], Long)]].get(0)
    allOf(Array(
        tokenData._1 == token1,
        tokenData._2 >= 60L,
        OUTPUTS(0).propositionBytes == pkA.propBytes,
        OUTPUTS(0).value >= 100L
    ))
  }
  || ...
\end{verbatim}
\lnote{Basically, this script allows Alice to simply reclaim what she has in B; it may also also her to do other things, which is why  ``\texttt{|| ...}'' is there in the script. I don't know the purpose of such a script, but it seems plausible. Now, an adversary can create a transaction with two inputs: Alice's box above (which requires to give her 60 token1 in the output) and box C; and two outputs: output with value 100 Ergo + 60 token1 to Alice, and output with value 100 Ergo to the adversary). Alice just lost 100 Ergo.}

\lnote{Another question: why do this instead of hash-based example?}

\subsection{Self-Replicating Code}
\label{sec:self-replicating}
Access to box registers allow us to create self-replicating boxes, because a script can check that an output box contains the same script as \texttt{SELF}. As shown in \cite{CKM18}, this powerful tool allows for Turing-completeness as computation evolves from box to box, even if each individual script is not Turing-complete. We will demonstrate two examples of complex behavior via self-replication.

\paragraph{Example: time-controlled coin emission}
In this example, we will create a self-replicating box that emits new coins at each time step in order to add to the total amount of currency available. This box appears as an output in the genesis block (at height 0) of the blockchain; all "new" coins come from this box or its descendants, thus maintaining the invariant that for every transaction after the genesis block, the combined value of all inputs  is equal to the combined value of all outputs.

The value of this box initially is equal to the total amount of currency that will eventually be available. This value will go down by a prespecified amount each time this box is transacted. Because in each transaction, the sum of input values must equal the sum of output values, when the value of this box goes down, the difference must be claimed by someone. The box is set up to allow to the difference to go anyone---presumably, it will be claimed by the miner who created the block that contains the transaction. This box will store, in \texttt{R4}, the height at which it was created. Using this information, it will be able to determine how much value to emit. The box will be set to emit
a fixed amount specified by \texttt{fixedRate} per block until \texttt{HEIGHT} reaches \texttt{fixedRatePeriod}, and a linearly decreasing amount thereafter. The script will verify that the output box has the same script as itself, and that the new height stored in \texttt{R4} and the new value are correctly computed (and that the height has increased, so that a miner cannot emit more than once per block). The following script accomplishes this goal:
\begin{verbatim}
      {
              val epoch = 1 + ((HEIGHT - fixedRatePeriod) / epochLength)
              val out = OUTPUTS(0)
              val coinsToIssue = if(HEIGHT < fixedRatePeriod) fixedRate
                                 else fixedRate - (oneEpochReduction * epoch)
              val correctCoinsConsumed = coinsToIssue == (SELF.value - out.value)
              val sameScriptRule = SELF.propositionBytes == out.propositionBytes
              val heightIncreased = HEIGHT > SELF.R4[Long].get
              val heightCorrect = out.R4[Long].get == HEIGHT
              val lastCoins = SELF.value <= oneEpochReduction
              allOf(Array(
                      correctCoinsConsumed,
                      heightCorrect,
                      heightIncreased,
                      sameScriptRule))
              || (heightIncreased && lastCoins)
      }
\end{verbatim}

\lnote{Not including demurrage example because it required more explanation about checking from miners and consensus about what registers are for what}

\paragraph{Example: arbitrary computation via a simple cellular automaton}
The example in the paragraph is not meant for practical implementation; rather, it is here merely to demonstrate the Turing-complete power of self-replication. It implements the so-called ``rule 110'' one-dimensional cellular automaton \cite{wolfram1986theory}, which is known to be Turing-complete \cite{cook2004universality} (with only polynomial-time overheard --- i.e., $P$-complete \cite{NW06}). See \cite{CKM18}  for more details. The code for this example is too complex to be put here; it is available at \lnote{give a reference to the code once it is written in our \langname and is sitting online somewhere}.

\lnote{maybe give a the simple example from \url{https://github.com/ScorexFoundation/sigmastate-interpreter/blob/master/src/test/scala/sigmastate/utxo/examples/Rule110Specification.scala\#L40?}}

\subsection{Merkle Trees}
Explain \texttt{isMember} and provide an example of usage. Explain that the context also contains the root hash of the all the unspent output boxes in the previous block \lnote{check: previous or current block? It would seem that the current is not available, so it should be previous.}, available via the predefined variable \texttt{LastBlockUtxoRootHash}. Give examples of usage, such as oracle, MAST, FSM. (For the oracle, explain that our language is rich enough to support signature verification within the script.)

\lnote{All of this has to wait until there are working code examples in \langname (currently, the examples in \texttt{OracleExamplesSpecification} and \texttt{MASTExampleSpecification} and \texttt{FsmExampleSpecification} are all written as ASTs, not as compilable code.}

\section{Implementation}
\label{sec:impl}
A script is converted to an abstract syntax tree using standard compilation techniques. At evaluation time, values from the context are substituted for relevant variables and the tree is evaluated. There are two significant differences from standard compilation and evaluation techniques:

\begin{itemize}
\item We estimate the time required to process the script and, if it exceeds a certain bound, refuses to evaluate it in order to prevent a denial-of-service attack.
\item The evaluation converts the script not to a Boolean value, but to a $\Sigma$-statement. This statement is a tree, with  \texttt{proveDlog} or \texttt{proveDHtuple} nodes for leaves, and $\andnode$ (\texttt{\&\&}), $\ornode$ (\texttt{||}), or $\tnode$ (\lnote{insert \langname notation here}) for  non-leaves. The prover (when trying to use in a transaction the box that is protected by the script) generates a proof this $\Sigma$-statement. The verifier verifies it, obtaining a Boolean value.
\end{itemize}

\lnote{Is the above accurate about everything else being relatively standard? Is there anything we want to describe?}

We describe these two nonstandard steps in Section \ref{sec:safety} and Appendix \ref{app:crypto}. \lnote{Should they be both in the appendix or both in the main body?}

\section{Safety Guarantees}
\label{sec:safety}

We need to be sure that an adversary can not produce such a statement for
which the Verifier spends more time than it is safe to spend. \knote{links to
verifier dilemma, orphan rates etc}

In order to filter out malicious statements, Verifier needs to perform a
series of safety checks in particular consistency checks and cost
estimations. This safety checks by itself require Verifier to spend some
time. However, the idea is to strictly limit the check complexity to be
linear in the size of the statement tree and input data, which are strictly
limited in size.

Verification and safety checks are performed in stages.

\subsection{Verification and Safety Checks}
\label{sec:safety-checks}

Verifier performs the following safety checks:

\begin{enumerate}
\item \textbf{Deserialization of Statement.}
Verifier receives the statement as an array of bytes and checks that the size
of array is less than predefined constant $C_1$. Deserializer parses the
array of bytes and checks if it is according to the format. Deserializer also
controls the size of the constructed statement tree. It should be less than
predefined constant $C_2$. The tree being constricted is also checked to
satisfy typing rules. After deserialization stage we have valid tree of known
limited size $TreeSize$. We want the complexity of all subsequent checks to
be $O(TreeSize)$.

\item \textbf{Instantiation of the Cost Function.}
Cost Function is the function of the same input (Context, variables,
registers, etc.) as Statement function, but it computes Long value of the
computation cost of the Statement function, so it answer the question "How
many operations it is required to compute the statement?".

The Cost Function is instantiated by the following steps:
    \begin{enumerate}
        \item Cost Function Tree, CFT, is obtained by:
        \begin{itemize}
            \item reading from the bytes stream immediately after Statement
            Tree. In this case the CFT is integral part of the Statement.
            \item generating from Statement Tree using algorithm $genCFT$
        \end{itemize}
        Both of these cases provide equivalent guarantees and only differ by
        the time of CFT generatation
        \item After the CFT is obtained the standard interpreter is used to
        evaluate it and calculate an estimation of the computation cost of
        the Statement. (Section \ref{sec:gen-cost-function})
    \end{enumerate}

 The idea is that the complexity of the Cost Function is linear in the size
 of the Statement tree in most of the cases. In the worst case it is linear
 in the size of the input data of the Statement which is strictly limited in
 size.
 We also rely on the fact that the complexity of $genCFT$ is linear in the
 size of the Statement Tree.

\item \textbf{Evaluating the Statement cost.}
The Cost Function is applied immediately before evaluation of the Statement
by the following steps:
    \begin{enumerate}
        \item construct the context as it is required for Statement evaluation
        \item invoke the interpreter to evaluate the Cost Function Tree in the
        given context
    \end{enumerate}

The generation of the CFT is further described in
section~\ref{sec:gen-cost-function}. Upon computing the cost of Statement
using Cost Function the Verifier check that it is less than the predefined
constant $C_3$.
\end{enumerate}

Passing all three stages of safety checks above, the Verifier is safe to
evaluate the Statement tree in a current data context. This Statement
evaluation is guaranteed to terminate in the estimated amount of time.

\subsection{Generation of Cost Function Tree}
\label{sec:gen-cost-function}

Here we briefly describe an algorithm $genCF$ to construct a Cost Function
tree. The basic idea is that we perform single traversal of the Statement
tree, visiting all the nodes from leaves up to the root. During traversal
foreach Statement node $t$ with children ${c_1 \dots c_k}$ we
construct$genCF(t)$ using ${genCF(c_1) \dots genCF(c_n)}$. Algorithm $genCF$
is defined recursively over the tree structure as shown in
Figure~\ref{fig:genCFT}. In the figure $dataCost(v)$ is a function to compute
a cost of the evaluated value $v$ represented either by $ContextVar$ of
$Constant$ tree nodes.

\begin{figure}
\begin{center}
\begin{tabular}{>{$}l<{$} >{$}c<{$} >{$}l<{$}}
    \multicolumn{3}{@{}l}{\textbf{def} $genCF(D: Context, t: Value[T]): Value[Long]$}  \\
    D, v~@~ContextVar(\_) & \to & dataCost(v) \\
    D, c~@~Constant(\_) & \to & dataCost(c) \\
    D, t_1 \otimes t_2 & \to & genCF(D, t_1) + Cost_\otimes + genCF(D, t_2) \\
    arr.map(f) & \to &
        \begin{tabular}[t]{l}
            let $f_{cost}$ = $genCF(D, f)$ \\
            $sum(arr.map(\lambda x \to f_{cost}(x)))$ \\
        \end{tabular} \\
     & \to & $\mnote{arg}$ \\
    % v @ Constant(_) & \to &
    %     \begin{tabular}[t]{l}
    %         $v :=$ variable with $varId$ from data environment \\
    %         return $dataCost(v)$ \\
    %     \end{tabular} \\
\end{tabular}
\caption{Algorithm $genCFT$}
\label{fig:genCFT}
\end{center}
\end{figure}

\subsection{Storing Cost Function}
\label{sec:store-cost-function}

\subsection{Cost Interpreter}
\label{sec:cost-interpreter}

\subsection{Cost Model}
\label{sec:cost-model}

\bibliographystyle{alpha}
\bibliography{sigma.bib}

\appendix

\section{Implementation of Noninteractive $\Sigma$-protocols for an arbitrary And/Or/Threshold composition}
\label{app:crypto}
\subsection{Background}

In this section, we explain in detail how the $\Sigma$-protocol proving and verifying is implemented. Consider the tree after the evaluation process, as described in Section~\ref{sec:impl}, reduces it to only $\Sigma$-protocol nodes. Then the leaves of the tree are atomic $\Sigma$-protocols, and non-leaves are of one of three types: $\andnode$ (corresponding to \texttt{\&\&} or \texttt{allOf} in \langname), $\ornode$ (corresponding to \texttt{||} or \texttt{anyOf} in \langname), or $\tnode(k)$ (corresponding to \texttt{atLeast} in \langname).

The meaning of the proof corresponding to $\tnode(k)$ is ``the prover knows witnesses for at least $k$ children of this node''. Semantically, $\andnode$ and $\ornode$ are simply special cases of $\tnode$: the meaning  of the proof corresponding $\andnode$ (respectively, $\ornode)$ is ``the prover knows witnesses for all children (respectively, at least one child) of this node''. However, $\andnode$ and $\ornode$ are implemented differently from $\tnode$ for efficiency.

For the purposes of this description, it does not matter what specific atomic $\Sigma$-protocols are used at the leaves. They can be, for example, \texttt{proveDlog(x)} for proving knowledge of the discrete logarithm $w$ of $x=g^w$, or \texttt{proveDHtuple(g1, g2, u1, u2)} for proving that $(g_1, g_2, u_1, u_2)$ form a Diffie-Hellman tuple, i.e., $\exists w \mbox{\ such\  that\ } u_1 = g_1^w \, \wedge \, u_2 = h_2^w$. In general, we will assume the prover has some secret $w$ and wants to prove some property of it.

A $\Sigma$-protocol consist of three messages:

\begin{itemize}
\item a \emph{commitment} $a$ sent from the Prover to the Verifier (computed using the witness $w$ and some freshly generated secret randomness $r$ by the Prover's first step algorithm);
\item a uniformly random \emph{challenge} $e$ sent from the Verifier to the Prover;
\item and a \emph{response} $z$ sent from the Prover to the Verifier (computed using the randomness $r$, the challenge $e$, and the witness $w$ by the Prover's second step algorithm).
\end{itemize}
The verifier then checks that the triple $(a, e, z)$ satisfies some formula and, if so, accepts the proof.

In order to make an atomic $\Sigma$-protocol non-interactive using the so-called Fiat-Shamir heuristic, the Prover would compute $e$ by hashing $a$, and the Verifier would check that $e$ is indeed a hash of $a$. However, once atomic $\Sigma$-protocols are composed using $\andnode$, $\ornode$, and $\tnode$, the challenge computation becomes more involved, as we describe below.

$\Sigma$-protocols have the property of \emph{special honest-verifier zero-knowledge}. For the purposes of this description, it means that given a random $e$, it is possible to compute $a$ and $z$ without knowing the secret witness $w$ that is normally needed by the prover. This computation is called ``simulation''. Moreover, the triple $(a, e, z)$  computed via simulation is distributed identically to the triple $(a, e, z)$ that results form a $\Sigma$ protocol that is run by the honest prover (who knows the secret witness $w$) and verifier (who generates a uniform $e$). The trick that makes simulation possible is that the response $z$ is chosen by the simulator before commitment $a$, in contrast to the prover, who is forced to choose $a$ before $z$.

$\Sigma$-protocols used in this work must also satisfy a property of \emph{special soundness}, which means that given two triples $(a_1, e_1, z_1)$ and $(a_2, e_2, z_2)$ that are both accepted by the verifier, and $a_1=a_2$ while $e_1\neq e_2$, it is possible to compute the Prover's secret witness $w$ in polynomial time and thus directly verify that the statement claimed by the Prover is true.   Note that this computation is never performed, because the Prover will never actually answer two different challenges $e_1\neq e_2$ for the same commitment $a_1=a_2$.

In order for composition of $\Sigma$-protocols using $\andnode$, $\ornode$, and $\tnode$ to work, the challenge $e$ in all protocols must be a binary string of the same length, which we will call $t$.  (This implies that if the Verifier performs arithmetic modulo $q$ on $e$, then $2^t<q$; else it would be trivial to have $e_1\neq e_2$ by letting $e_2=e_1+q$, and the same $z$ would work for both $e_1$ and $e_2$, violating the special soundness property mentioned above, because such $a, e_1, z$ can be computed without knowledge of the witness $w$ by using the simulator.)  Note that $t$ is the \emph{soundness parameter}: the probability that a malicious Prover can fool the Verifier in a single attempt is $2^{-t}$.

 For ease of description, we will also impose the following limitation on the $\Sigma$ protocols: in the interactive version, the verification code must proceed by computing $a'$ from $z$ and $e$, and then checking if $a'=a$. That means that in the noninteractive version, the Prover needs to transmit only $z$ and $e$ (omitting $a$) to the Verifier, who will compute $a'$ from $z$ and $e$ and then check that $e$ was computed correctly as a function of $a'$. If the hashing is second-preimage-resistant, an incorrect $a'$ will lead to a mismatch of $e$, which will be detected by the Verifier. This limitation is satisfied by most common $\Sigma$-protocols; it is not essential and can be removed by having the Prover additionally send $a$.

We show the steps of the prover and verifier given such a tree. While $\andnode$, $\ornode$, and $\tnode$ composition of $\Sigma$-protocols has been addressed in the literature before \cite{CDS94}, prover and verifier algorithms have been described only for a single node, in terms of prover, verifier, and simulator algorithms for its children. Recursively constructing code for an entire tree by dynamically constructing prover, verifier, and simulator code for each node is inefficient. Here we take a different approach by explicitly describing how and in what order the protocol messages for each node of the tree need to be computed and verified. We are not aware of any similar descriptions in the literature.

Our description uses two kinds of tree traversal: bottom-up (also known as post-order) and top-down (also known as preorder). In a bottom-up traversal, for each node, operations are recursively applied to the children of the node before being applied to the node itself. In a top-down traversal, for each node, operations are applied to the node itself before being recursively applied to each of its children.

\subsection{Proving}
\label{sec:proving}

The Prover will know secret witnesses $w$ for some of the leaves; for such leaves, it will choose whether to produce real or simulated proofs according to the algorithm described in this section. The Prover will simulate proofs for all other leaves.

\paragraph{Multiple provers} There may be situations when the secret witnesses $w$ at the leaves are distributed among several different provers, who will have to cooperate but will not have to reveal the secrets to each other; in this case, we assume there is a main prover carrying out the steps below, and we explain what the other provers need to do in order for the main prover to construct the proof. We caution that the proofs will not be zero-knowledge to the other provers nor to an adversary who can observe the communication between the provers---even just the existence of communication will reveal which parts of the tree are real and which are simulated. Moreover, if the main prover is malicious, it may be able to attack the other provers --- see Step \ref{step:response} below. More sophisticated multi-party computation protocols to address this problem are available, but are outside the scope of this paper.

\paragraph{Side-channel attacks}
Note that the algorithm described below does not attempt to be secure against side channel attacks, such as, for example, timing attacks. It particular, it may take different amounts of time depending on which nodes are real and which are simulated; a timing attacker may therefore obtain information about the set of leaves for which the Prover knows the secrets. If timing attacks are a concern, it is not enough to make sure that simulation and proving take a similar amount of time for each atomic $\Sigma$-protocol used in the leaves; implementations should also make sure that tree traversals take the same amount of time regardless of where simulated and real $\Sigma$ protocols are located in the tree. In particular, implementations should avoid the use of lazy-evaluation constructs, such as ``forall'' and ``exists''.

\paragraph{The steps}
For each node in the tree, the prover will maintain a flag indicating whether it is real or simulated. Each node will also have a $t$-bit challenge. The leaves will additionally have two protocol values: a challenge and a response. The pseudocode below explains how these values are computed. In the pseudocode below, the word ``random'' should be read to also allow securely generated pseudorandom values.

The prover first has to decide which nodes will have real proofs (for which witnesses are required) and which will be simulated. For example, in an $\ornode$ proof, only one of the children will be real. The prover will do so based on witnesses that are available, in three steps:

\begin{enumerate}
    \item \label{step:initial-simulated} This step will mark as ``real'' every node for which the prover can produce a real proof. This step may mark as ``real'' more nodes than necessary if the prover has more than the minimal necessary number of witnesses (for example, more than one child of an $\ornode$).  This will be corrected in the next step. In a bottom-up traversal of the tree, do the following for each node:
        \begin{itemize}
            \item If the node is a leaf, mark it ``real'' if the witness for it is available; else mark it ``simulated''
            \item If the node is $\ornode$, mark it ``real'' if at least one child is marked real; else mark it ``simulated''
            \item If the node is $\andnode$, mark it ``real'' if all of its children are marked real; else mark it ``simulated''
            \item If the node is $\tnode(k)$, mark it ``real'' if at least $k$ of its children are marked real; else mark it ``simulated''
        \end{itemize}

    \item If the root of the tree is marked ``simulated'' then the prover does not have enough witnesses to perform the proof. Abort.

    \item This step will change some ``real'' nodes to ``simulated'' to make sure each node has the right number of simulated children.
          In a top-down traversal of the tree, do the following for each node:
        \begin{itemize}
            \item
            If the node is $\ornode$ marked ``real'',  mark all but one of its children ``simulated''
            (the node is guaranteed by step~\ref{step:initial-simulated} to have at least one ``real'' child).
            Which particular child is left ``real'' is not important for security; the choice can be guided by efficiency or convenience considerations.
            \item
            If  the node is $\tnode(k)$ marked ``real'', mark all but $k$ of its children ``simulated''
            (the node is guaranteed, by the previous step, to have at least $k$ ``real'' children).
            Which particular ones are left ``real'' is not important for security; the choice can be guided by efficiency or convenience considerations.
            \item
            If the node is marked ``simulated'', mark all of its children ``simulated''
        \end{itemize}
\end{enumerate}

\noindent
Now the prover will compute protocol values for every node, as follows:

\begin{enumerate}
\setcounter{enumi}{3}
    \item In a top-down traversal of the tree, compute the challenges $e$ for simulated children of every node, as follows:
    \begin{itemize}
        \item If the node is marked ``real'', then each of its simulated children gets  a fresh uniformly random challenge in $\{0,1\}^t$. (Note that a real $\andnode$ node has no simulated children, so this step applies only to real $\ornode$ and $\tnode$ nodes.)
        \item If the node is marked ``simulated'', let $e_0$ be the challenge computed for it.  All of its children are simulated, and thus we compute challenges for all of them, as follows:
        \begin{itemize}
            \item If the node is $\andnode$,  then all of its children get $e_0$ as the challenge
            \item If the node is $\ornode$, then each of its children except one gets a fresh uniformly random challenge in $\{0,1\}^t$. The remaining child gets a challenge computed as an XOR of the challenges of all the other children and $e_0$.
            \item If the node is $\tnode(k)$, assume it has $n$ children numbered from $1$ to $n$. There are two possible algorithms. The first algorithm is faster than the second. However, it is also faster than the algorithm for a ``real'' $\tnode$ node; therefore, if a timing attack on the prover is a possibility, then it should not be used, because the timing attack may be able to distinguish a ``real'' $\tnode$ node from a ``simulated'' one.
            \begin{enumerate}
            	\item The faster algorithm is as follows. Pick  $n-k$ fresh uniformly random values $q_1, \dots, q_{n-k}$ from $\{0,1\}^t$ and let
	         $q_0=e_0$. Viewing $1, 2, \dots, n$ and $q_0, \dots, q_{n-k}$ as elements of $\GF(2^t)$,
	         evaluate the polynomial $Q(x) = \sum {q_i x^i}$ over $\GF(2^t)$ at points $1, 2, \dots, n$
	         to get challenges for child $1, 2, \dots, n$, respectively.
	         \item The algorithm with better resistance to timing attacks is as follows. Pick $n-k$ fresh uniformly random values $e_1, \dots, e_{n-k}$
	         as challenges for the children number $1, \dots, n-k$.
	         Let $i_0 = 0$. Viewing $0, 1, 2, \dots, n$ and $e_0, \dots, e_{n-k}$ as elexments of $\GF(2^t)$, find (via polynomial interpolation) the
	          lowest-degree polynomial $Q(x)=\sum_{i=0}^{n-k} a_i x^i $ over $\GF(2^t)$ that is equal to $e_j$ at $j$ for each $j$ from
	          $0$ to $n-k$ (this polynomial will have $n-k+1$ coefficients, and the lowest coefficient will be $e_0$). Set the challenge at child
	          $j$ for $n-k<j\le n$ to equal $Q(j)$.
 	   \end{enumerate}
        \end{itemize}
    \end{itemize}

    \item For every leaf marked ``simulated'', use the simulator of the $\Sigma$-protocol for that leaf to compute the commitment $a$ and the response $z$, given the challenge $e$ that is already stored in the leaf.

    \item \label{step:realcom} For every leaf marked ``real'', use the first prover step of the $\Sigma$-protocol for that leaf to compute the necessary randomness $r$ and the commitment $a$. In case of multiple provers responsible for different leaves, each prover individually computes the randomness $r$ for that leaf; the provers send their commitments $a$ to the main prover (note that the existence of this communication, if observed the adversary, will reveal to the adversary which leaves are real).

    \item \label{step:fs}  Convert the tree to a string $s$ for input to the Fiat-Shamir hash function. The conversion should be such that the tree can be unambiguously parsed and restored given the string. For each non-leaf node, the string should contain its type ($\andnode$, $\ornode$, or $\tnode(k)$). For each leaf node, the string should contain the $\Sigma$-protocol statement being proven and the commitment. The string should not contain information on whether a node is marked ``real'' or ``simulated'', and should not contain challenges, responses, or the real/simulated flag for any node.

    \item Compute the challenge for the root of the tree as the Fiat-Shamir hash of $s$ (and, if applicable,  the associated data, such as the message being signed).

    \item \label{step:response} Perform a top-down traversal of only the portion of the tree marked ``real'' in order to compute the challenge $e$ for every node marked ``real'' below the root and, additionally, the response $z$ for every leaf marked ``real'' (note that nodes marked ``simulated'' have all their descendants marked ``simulated'' and all the challenges for these descendants already computed, so there is no need to recurse down ``simulated'' nodes, unless timing attacks are a concern). For every node, do the following:

    \begin{itemize}
        \item If the node is a non-leaf marked ``real'' whose challenge is $e_0$, proceed as follows:

        \begin{itemize}
            \item If the node is $\andnode$, let each of its children have the challenge $e_0$
            \item If the node is $\ornode$, it has only one child marked ``real''. Let this child have the challenge equal to the XOR of the challenges of all the other children and $e_0$
            \item If the node is $\tnode(k)$, number its children from $1$ to $n$. Let $i_1, \dots, i_{n-k}$ be the indices of the children marked ``simulated'' and $e_1, \dots,  e_{n-k}$ be their corresponding challenges. Let $i_0 = 0$. Viewing $0, 1, 2, \dots, n$ and $e_0, \dots, e_{n-k}$ as elements of $\GF(2^t)$, find (via polynomial interpolation) the lowest-degree polynomial $Q(x)=\sum_{i=0}^{n-k} a_i x^i $ over $\GF(2^t)$ that is equal to $e_j$ at $i_j$ for each $j$ from $0$ to $n-k$ (this polynomial will have $n-k+1$ coefficients, and the lowest coefficient will be $e_0$). For child number $i$ of the node, if the child is marked ``real'', compute its challenge as $Q(i)$ (if the child is marked ``simulated", its challenge is already $Q(i)$, by construction of $Q$).
        \end{itemize}

        \item If the node is a leaf marked ``real'', compute its response $z$ according to the second prover step of the $\Sigma$-protocol given the randomness $r$ used for the commitment $a$, the challenge $e$, and witness $w$. In case of multiple provers, the main prover will send the relevant challenges to other provers, who will respond with the relevant $z$. It is crucial for security that the provers do not respond to more than one challenge $e$ for a given commitment $a$. Again, like in Step \ref{step:realcom}, the mere existence of this communication reveals which leaves are real and which are simulated. Moreover, if the main prover chooses the challenge $e$ maliciously for another prover, the zero-knowledge property of the other prover's secret is not preserved (although, for most $\Sigma$-protocols, no useful information about the other prover's secret will be revealed for any, even maliciously chosen, $e$; but a malicious choice of $e$ may make side-channel attacks easier).

    \end{itemize}

    \item Output the proof consisting of the following information:
    \begin{itemize}
        \item The challenge of the root node
        \item For every $\ornode$ node: the challenges of all of its children but the rightmost
        \item For every $\tnode$ node: the coefficients $q_1 \dots q_{n-k}$ of the polynomial $Q(x)$ (excluding $a_0$)
        \item The responses for every leaf node
    \end{itemize}
\end{enumerate}

\subsection{Verifying}
\label{sec:verifying}

For each node in the tree, the verifier will obtain a $t$-bit challenge $e$ by either reading it directly from the proof or by using other information provided in the proof. For the leaves, the verifier will also read the response $z$ from the proof and will re-compute, using the challenge and the response, the commitment $a$.  Finally, verifier will hash the whole tree and will check that the hash value matches the challenge of the root node.

Note that, unlike the prover, the verifier has no way of knowing which nodes are real and which are simulated. In fact, making sure that the verifier cannot tell the difference between real and simulated nodes is one of the security goals of the protocol.

The pseudocode below details the verifier's steps.

\begin{enumerate}
\item Read the root challenge from in the proof.

\item In a top-down traversal of the tree, obtain the challenges for the children of every non-leaf node by reading them from the proof or computing them, as follows. Let $e_0$ be the challenge in the node.
        \begin{itemize}
            \item If the node is $\andnode$,  then all of its children get $e_0$ as the challenge
            \item If the node is $\ornode$, then each of its children except rightmost reads its challenge from the proof. The rightmost child gets a challenge computed as an XOR of the challenges of all the other children and $e_0$.
            \item If the node is $\tnode(k)$, let the number of its children be $n$. Assume the children are numbered from $1$ to $n$. Let $q_0=e_0$ and read the values $q_1, \dots, q_{n-k}$ from the proof. Viewing $1, 2, \dots, n$ and $q_0, \dots, q_{n-k}$ as elements of $\GF(2^t)$, evaluate the polynomial $Q(x) = \sum {q_i x^i}$ over $\GF(2^t)$ at points $1, 2, \dots, n$ to get challenges for child $1, 2, \dots, n$, respectively.
        \end{itemize}

 \item For every leaf node, read the response $z$ provided in the proof.

\item For every leaf node, compute the commitment $a$ from the challenge $e$ and response $z$, per the verifier algorithm of the leaf's $\Sigma$-protocol. If the verifier algorithm of the $\Sigma$-protocol for any of the leaves rejects, then reject the entire proof.

\item Convert the tree to a string $s$ for input to the Fiat-Shamir hash function, using the same conversion as the prover in Step~\ref{step:fs}

\item Accept the proof if the challenge at the root of the tree is equal to the Fiat-Shamir hash of $s$ (and, if applicable,  the associated data). Reject otherwise.
\end{enumerate}

\section{Old Intro Text -- not sure what's needed}

Much like digital signatures prove that the signer knows the secret key, $\Sigma$-protocols can be used to prove knowledge of a discrete logarithm.

The idea behind the language is that a subset of zero-knowledge protocols known as $\Sigma$-protocols (sigma protocols) could be combined via $\sqcap$ and $\sqcup$ connectives forming complex statements like ``prove me a knowledge of discrete logarithm of (publicly known) $x_1$ or knowledge of Pedersen commitment $x_2$ preimage''. We make an observation that sigma protocol statements and their conjectures are naturally correspond to propositional logic, and we can add arbitrary boolean predicates to statements provable via a $\Sigma$-protocol, if both prover and verifier are able to evaluate the predicates in exactly the same way. This is the case if predicates are evaluated deterministically in the same way by both the prover and the verifier, and inputs for the predicates are the same on both sides.
We assume prover and verifier can be different parties, e.g. prover is a creator of transactions (wallet application) and verifier is a miner validating incoming transactions.
We use predicates over state of blockchain system during script validation~(which happens when a transaction tries to spend an output protected by the script). To avoid inefficient processing and impossibility for a light client to validate a transaction, this state is very lean but nevertheless it is richer than in Bitcoin. Like in Bitcoin, we use current height of the blockchain, but also a spending transaction with outputs it creates and inputs it tries to spend. Unlike Bitcoin, we allow outputs to contain more fields than amount and protecting script, in a form of additional registers an output can have. In addition to $\land$ and $\lor$ connectives for boolean propositions we also introduce $\sqcap$ and $\sqcup$ connectives for sigma protocol statements. The language also have different operations over statically typed arguments. We reject out during compilation time expressions with type errors, like $2 + 2 > true$, thanks to a type system used.

In blockchain systems, there is a strict need to tackle the problem of denial-of-service attack carrying by crafting scripts which are too costly to validate. For example, if it is needed for more time to validate a script than average delay between blocks on commodity hardware, network could be obviously attacked, with nodes stuck in processing, and also increased number of forks as result.

\section{Old Language Design Section}

We assume that a {\em prover} and a {\em verifier} have a shared {\em context}. As we are designing a language for cryptocurrencies, the context is about current state of the blockchain (such as height $h$ of a best block in the blockchain, a spending transaction with outputs it spends and newly created outputs, etc). Please note that the language can be repurposed for other areas where shared context is possible, but this is out of scope of the paper.

\subsection{Notation}

We use $Dlog(x)$ to denote a statement ``prove a knowledge of such $w$ that $x = g^w$''. Proving is to be done by a prover in zero knowledge~(with no presenting the secret $w$ to a verifier). Statement $Dlog(x_1) \sqcap Dlog(x_2)$ means ``prove a knowledge of both $w_1$ and $w_2$, such as $x_1 = g^{w_1}, x_2 = g^{w_2}$'', similarly, $Dlog(x_1) \lor Dlog(x_2)$ is about a proof of knowledge of either $w_1$ or $w_2$.

\subsection{UTXO model}

We assume a transactional model close to Bitcoin's. That is, a transaction spends unspent outputs (pointed to by \emph{transaction inputs}) from previous transaction written into the blockchain, and creates new outputs. An output is associated with arbitrary amount of money, and also a protecting script. In Bitcoin, there is a special kind of transaction, so-called {\em coinbase transaction}, which can create some amount of money out of thin air~(to reward a block generator). In Bitcoin transaction fees money flow is not captured in outputs, a transaction fee is just a difference of amounts of outputs being spent and outputs being created. In Appendix~\ref{apx:unified} we provide a way to avoid coinbase transactions, and also express fees explicitly as outputs. In Appendix~\ref{apx:account} we discuss how to make a language for a cryptocurrency with account-based transactions~(such as Waves~\cite{Waves}).

\subsection{Logic of $\Sigma$-protocols}

Cryptocraphic propositions verifiable via $\Sigma$-protocols are represented by values of an algebraic data type $SigmaProp$,
which stands for \emph{sigma proposition} and can be described using the following declaration (using Idris/Agda ADT notation~\cite{Idris, Agda})

\begin{lstlisting}
data SigmaProp: Type where
  Dlog: GroupElement -> SigmaProp
  Dht: (gv, hv, uv, vv: GroupElement) -> SigmaProp
  ...
\end{lstlisting}

In the definition above, each constructor represents one of the cryptographic primitives, and the set of such constructors
can be extended (although this extensibility is out of paper's scope).

We want to be able to construct more complex statements out of basic primitive propositions.
There are two binary operations over $SigmaProp$ values:
\begin{itemize}
\item $\sqcup: (SigmaProp, SigmaProp) -> SigmaProp$
\item $\sqcap: (SigmaProp, SigmaProp) -> SigmaProp$
\end{itemize}

Any expression of $SigmaProp$ type can be efficiently verified using sigma protocol and thus mapped to a truth values.

We implement a verification procedure $V: SigmaProp -> Boolean$, which performs such mapping, and satisfies the following
naturality conditions with respect to SigmaProp and Boolean connectives.

For any two statements $sigma1, sigma2: SigmaProp$:
\begin{itemize}
    \item $V(s_1 \sqcup s_2) = V(s_1) \lor V(s_2)$
    \item $V(s_1 \sqcap s_2) = V(s_1) \land V(s_2)$
\end{itemize}

Bacause SigmaProp connectives and logical connectives satisfy naturality conditions we can reason about complex sigma statements
the same way we reason about logical statements.
However, unlike logical statements evaluation of sigma statements is done with zero knowledge about intermediate steps.
Thus, we can verify the truth of $s_1 \sqcup s_2$ (i.e. compute $V(s_1 \sqcup s_2)$) statement but we cannot know whether $s_1$ or $s_2$ or both is true. At the same time evaluation of $V(s_1) \lor V(s_2)$ discloses results of both $V(s_1)$ and $V(s_2)$ before execution of $\lor$.

There is a function $isValid: SigmaProp -> Boolean$ in Sigma-state language which implements the function $V$.
The type system of the language allows to explicitly delimit usages of zero knowledge evaluation
of sigma statements and classical evaluation of boolean statements.

This allows script designer to explicitly control security (zero-knowledge) guarantees where it is necessary.

\subsection{General Idea}

By using a $\Sigma$-protocol, a prover can prove a knowledge of secret information corresponding to publicly known values, in zero-knowledge(i.e. without disclosing a secret value), for some relations between secret and public values. Unlike generic proof systems, $\Sigma$-protocols are efficient~(for both the prover and the verifier). For a cryptocurrency setting, the pros of this class of protocols are generic transformation from an interactive protocol to non-interactive one~(by using Fiat-Shamir transformation), and also composability: we can combine statements provable with $\Sigma$-protocols via $\land$, $\lor$ and k-out-of-N conjectures, and the compound statement is also provable via a $\Sigma$-protocol. An observation which is lying in the foundation of our work is that we can view a (potentially complex) statement provable via a $\Sigma$-protocol as a formula over sigma values homomorphic to logical formula. For example, the statement $dlog(x_1) \lor dlog(x_2)$ could be viewed as a formula consisting of two sigma values connected by $\lor$ and which is homomorphic to the formula $b1 or b2$. Then we can enrich the language of $\Sigma$-protocols (which describes relations between prover's secrets and their publicly known images) with deterministic predicates over a context shared between the prover and the verifier. Still, we are using only $\land$, $\lor$ and k-out-of-N conjectures. By evaluating predicates over the context into concrete boolean values and then eliminating them, both (honest) the prover and verifier do agree on the same reduction procedure output, which could be one of the following: boolean value (true or false) or a statement provable via a $\Sigma$-protocol. However, in the light of denial-of-service attacks found against scripting capabilities of Bitcoin and Ethereum \knote{todo: links}, we need to limit possible complexity of the reduction procedure. For that, we have two measures against possible overload issues. In the first place, we have to use only context which is efficiently computable. For example, we can not have predicates over transactional history, as it is linearly growing with time, and also could not be hold by a light client. In opposite, we can use height of a block which contains the transaction spending the output of interest, access to this information is constant-time and available to light clients. If a validation state~(which is similar to UTXO set in Bitcoin for Bitcoin-like cryptocurrencies) is authenticated~(like proposed in the paper \knote{cite AVL paper}), we can construct a predicate for existence of an unspent output (with some conditions to be met), then the prover is providing a Merkle proof for an output satisfying the predicate, and even a light client can validate the predicate efficiently. In the second place, we put a limit on size of an initial logic formula which protects an output, and also we take care that the formula will not become too big due rewritings (as some transformations in our proposal could actually increase a size of the formula\mnote{For example? Looks like all the transforms are decreasing.}) and number of transformations is below an upper limit.

\subsection{Model}

An output to spend is protected by a logical expression, which we are also calling a {\em guarding expression}. An expression is a mix of predicates over publicly known context, and statements provable via sigma protocols. As a simplest example, consider the following statement:

\begin{equation}
\label{eq:example1}
dlog(x_1) \lor ((h > 5) \land dlog(x_2))
\end{equation}

which is to be read as ``proof of knowledge of a secret with public image $x_1$ is always enough, also, if height of a block containing spending transaction is more than 5, knowledge of a secret with public image $x_2$ is also enough'' to admit spending of the output.

Both the prover and the verifier are first reducing the statement by substituting shared context variables and evaluating parts of the expression which are possible to evaluate. Four outcomes of the reduction process are possible: {\em true}, {\em false}, failure to reduce~(if statement is invalid, or transformations of it are taking too much time or result in unreasonably big statement), which is equivalent to {\em false}; or statement which contains only cryptographic statements. For the example, if $h = 10$, the reduced statement is $dlog(x_1) \lor dlog(x_2)$. In this case, the prover is generating a proof, and verifier is checking validity of the proof, accepting or rejecting it. We use cryptographic statements which are provable via {\em sigma protocols}~(\knote{links}). These protocols are efficient zero-knowledge \knote{special honest verifier ZK actually} proof-of-knowledge protocols which are composable via $\land$, $\lor$ and k-out-of-N conjectures, also any sigma protocol has a standard way to be converted into a signature by using the Fiat-Shamir transformation.

In addition to secret information, which knowledge is to be proven in zero-knowledge, we allow prover to enhance context with custom variables. For example, for the statement:

$$dlog(x) \land (blake2b256(c) = C)$$

where $C$ is some constant~\footnote{we avoid providing a value for the constant due to column size limit}, and $blake2b256$ is operation which calculates hash value for function Blake2b256~(\knote{link}). The prover then needs to prove knowledge of discrete logarithm of $x$ and also to present value $c$ such as Blake2b256 on $c$ evaluates to $C$. Even if verifier does not know $c$ before being presented a proof, we can not count $c$ as secret, as it could be replayed by an eavesdropper.

\subsection{Language Details}
\label{sec:lang-details}

Here we provide details on building blocks of the language.
Both the prover and the verifier are doing the same first few steps, and they both are using the same deterministic interpreter. In the first place, the interpreter is parsing incoming expression~(in typical case of validating a transaction within a block, it is encoded in a binary form), building a tree from the expression, and checking that the expression is well-formed according to typing rules. We describe types and typing rules in Section~\ref{sec:types}. The interpreter then is reducing the expression by applying rewriting rules to the tree as described in the Section~\ref{sec:rewriting}. The possible result of the reduction is whether an abort, or a successfully reduced expression, which could be whether a boolean value or a statement provable via a $\Sigma$-protocol. For the latter case, the prover and the verifier are doing different jobs: the prover is proving knowledge of secrets associated with the statement, as described in Section~\ref{sec:proving}; the verifier is checking a proof generated by the prover against the statement, as described in the Section~\ref{sec:verifying}.

The interpreter is also checking that the expression is not exceeding by number of sub-expressions and their cumulative complexity some predefined limit~(which is the same for the prover and the verifier, e.g a constant of a blockchain system, or changed by miners in predictable and controllable fashion, like gas limit per block in Ethereum). As complexity is going beyond the limit, the interpreter aborts immediately.

\subsection{Types}
\label{sec:types}

All the operations as well as operands have types. For example, addition operation ``+'' may take two Int and returns an Int value. Comparison operation ``$>$'' takes two Int and returns a boolean value. Some operations may be overloaded so that the same symbol is reused for operations acting on different types, e.g. $+: (Int,Int) \to Int$, $+: (Long, Long) \to Long$ etc.
We consider statements provable via $\Sigma$-protocols, like $dlog(x)$ as instances of the boolean type. The interpreter checks that all the nodes in the tree have children of appropriate types, and the whole guarding expression~(the root node of the tree) has a boolean type and rejects the expression if the conditions are not met.

We have following types in the language:

\begin{itemize}
    \item{signed integer types of 8, 16, 32 and 64-bits size}
    \item{big integer type of arbitrary size}
    \item{boolean}
    \item{avl+ tree verification data}
    \item{cryptography group element}
    \item{box}
    \item{tuple of values of different types}
    \item{array of values of the same type}
    \item{optional value}
\end{itemize}

\knote{todo: improve description, also, add unsigned integer?}

\ignore{
\begin{center}
    \begin{tabular}{| l | l | l | l | l |}
    \hline
    Operation & bytes & ints & prop & bool \\ \hline
    $=$ & + & + & + & + \\
	$\neq$ & + & + & + & +\\
	$+$ & + & + & - & - \\
	$-$ & - & + & - & - \\
	$>$ & - & + & - & - \\
	$\ge$ & - & + & - & -\\
	$<$ & - & + & - & -\\
	$\le$ & - & + & - & -\\
	$\oplus$ & + & - & - & + \\
	$\lor$ & - & - & - & + \\
	$\land$ & - & - & - & + \\
	$blake2b256$ & + & - & - & -\\
	$dlog$ & - & - & - & -\\
	$dh$ & - & - & - & -\\
    \hline
    \end{tabular}
\end{center}
}

\subsection{Rewriting a Tree}
\label{sec:rewriting}

By parsing a statement, interpreter first builds a tree from a formula. For the example~\ref{eq:example1} the tree would be as following:

\knote{draw the tree}.

If the tree is well-formed according to the typing rules, and also has complexity no more than an allowed limit, interpreter is going to rewrite it, in potentially many steps. For every step, the interpreter tries, going from bottom to top of the tree, to replace nodes which are ready to be transformed~(operands are in place, and the transformation itself is known). The next step is about the same transformations in the same bottom-top order to be done. The process finishes in one of the following cases:

\begin{itemize}
    \item{abort: } happens if transformation process by its complexity exceeds an upper bound. The complexity estimation works as follows. The interpreter remembers initial cumulative complexity $C_0$, and for each replacement in the tree it calculates cumulative complexity of a subtree to be inserted instead of a subtree to be removed $\Delta C$, and adds $\Delta C$ to current cumulative complexity $C$, where $C = C_0$ initially.
    \item{success: } we finish with this status if during last step there are no any transformations done.
\end{itemize}

If the transformations are finishing with abortion, the result is considered as $false$ (we recall that the interpreter is giving a single boolean result finally, whether an output could be spent or not). Otherwise, if the tree could not be transformed anymore the interpreter is looking into it. If the tree is about just a single node which contains boolean constant value~($true$ or $false$), the value is the result of the interpretation. If the tree contains statements not provable via $\Sigma$-protocols, the interpreter finishes with $false$. Otherwise, if the tree contains only statements provable via $\Sigma$-protocols, the interpreter is continuing to work, and here execution is different for the prover and the verifier. The prover is generating a proof for the statement by using its secrets, as described in Section~\ref{sec:proving}, and the verifier checks the statement against the proof~(provided in a spending transaction), as described in Section~\ref{sec:verifying}. The verifier outputs $true$ if the proof is valid for the statement, $false$ otherwise. We are skipping for now the question how Fiat-Shamir transformation works in our setting, and how a message, which is used in a non-interactive protocol is formed; details are given further in Appendix~\ref{apx:tx-format}.

\section{Old Context Section}

Shared context of a blockchain system could be expressed in different ways, based on desired expressiveness, efficiency, planned use cases and so on. In this paper we focus on context for Ergo blockchain. The main priority for this blockchain is maximum efficiency of transaction validation process, safety, and friendliness to light clients. Considering this, we require that context should contain only spending transaction along with outputs it spends, and limited number of last block headers. Thus even a client which does not have all the headers of the blockchain~(for example, the client could be working in a light-SPV mode, where the client is holding only sublinear part of the headers-chain) is able to validate a transaction, by being shown it~(as well as outputs the transaction spends along with Merkle proofs for them).

\knote{brief context description, link to an appendix with details}

\section{Old Examples Section}

In this section we provide some examples of useful guarding scripts. We focus on examples which are impossible or much harder to express in Bitcoin Script.

\subsection{Crowdfunding}
\label{sec:crowdfunding}

We provide simple solution to crowdfunding here. In the example, a crowdfunding project associated with public key $x_P$ is considered successful if it can collect unspent outputs with total value not less than $to\_raise$ before height $timeout$. A project backer creates an output protected by the following statement:

\begin{equation*}
\begin{split}
(height \ge timeout \land dlog(x_B)) \lor \\
(height & < timeout \land dlog(x_P)\\
& \land Exists(Outputs, 20,\\
& \quad \quad \quad \quad ExtractAmount(TaggedBox(20)) \ge to\_raise \land \\
& \quad \quad \quad \quad ExtractScriptBytes(TaggedBox(20)) = ToBytes(dlog(x_P))))
\end{split}
\end{equation*}

Then the project can collect biggest outputs with total value not less than $to\_raise$ with a single transaction~(it is possible to collect up to ~22,000 outputs in Bitcoin, which is enough even for a big crowdfunding campaign). For remaining small outputs over $to\_raise$, it is possible to construct follow-up transactions.

Please note why such a guarding expression is not possible in Bitcoin: we use the condition on a spending transaction, namely, we require the transaction to have an output with value not less than required, and also with a particular statement protecting the output.

\subsection{Money With Scheduled Maintenance Payments}

\knote{description}

\begin{equation*}
\begin{split}
user\_statement \lor \\
(height & \ge (ExtractHeight(self) + period) \land \\
    & Exists(Outputs, 20, \\
    & \quad \quad \quad \quad ExtractAmount(TaggedBox(20)) \ge (ExtractAmount(self) - cost) \land \\
    & \quad \quad \quad \quad ExtractScriptBytes(TaggedBox(20)) = ExtractScriptBytes(self)))
\end{split}
\end{equation*}

We highlight impossibility of such a statement in the Bitcoin Script: similarly to the statement in the previous section~\ref{sec:crowdfunding}, we use a condition on a spending transaction. Another feature missed in the Bitcoin Script is that we also use an output to spend in the execution context. In particular, in the example above we require a spending transaction to have an output which has the same statement as an output it spends.

\subsection{Ring Signature}
\label{sec:ring}

Linear-sized ring signature is very straightforward in the language. Assume a ring consists of $m$ public keys $x_1, \dots, x_m$. If one wants an output to be spent by a ring signature associated with the ring, the output is to be protected by the following statement:

$$dlog(x_1) \lor \dots \lor dlog(x_m)$$

Please note that proving of the statement is to be done in zero-knowledge, so it is not possible to know which key signed, the only fact to conclude is that some key from the ring signed output spending.

\subsection{Complex Signature Schemes}

We can build more complex signature schemes than possible in Bitcoin. One particular example was provided in the previous Section~\ref{sec:ring}. Another example is a scheme where at least one out of (Alice, Bob), and at least one out of (Charles, Diana) are needed to sign, and it is not to be known who signed an output spending. The corresponding statement involving public keys $x_A, x_B, x_C, x_D$ of Alice, Bob, Charles and Diana respectively would be following:

$$(dlog(x_A) \lor dlog(x_B)) \land (dlog(x_C) \lor dlog(x_D))$$

\subsection{Simple Tumbler}
\label{sec:tumbler}

\knote{does the example makes sense? check other tumbler papers. also, update the scripts, now approach is more generic than using tx.outbytes}

Privacy is a tough problem for cryptocurrency users. Bitcoin is a pseudonymous cryptocurrency, so no real identities attached to a transaction. However, it is possible to reconstruct transactional graph for all the transactions ever entered into the Bitcoin blockchain, and often restore real identities by using auxiliary databases. \knote{link} To improve privacy, tumblers are being used. A tumbler is a scheme which us getting some money transfers as inputs, produces output money transfers, and has a property of unlinkability: it is not possible to draw a link from an input to an output. Thus a tumbler user is hiding herself amongst a ring of users sending inputs to the scheme. Privacy then depends on a ring size. For maximum privacy, there exists a cryptocurrency ZCash with inbuilt tumbler based on zkSnarks\knote{links}, where a user is hiding among all the users in the system. However, ZCash requires trusted setup, and transaction validation is relatively slow~(10 ms). In other cryptocurrencies users are usually using external services varying in security and efficiency.

Here we are describing simple tumbler service. It is very efficient and requires no trusted dealer. Its disadvantage is that from observing blockchain transactions it is possible to conclude that users are using a tumbler.

Assume Alice with public key $x_A$ and Bob with public key $x_B$ want to relocate funds to keys $y_1$ and $y_2$ respectively, with a property than external observer looking into blockchain is not capable to know beyond the fact that money flows from $x_A$ to whether $y_1$ or $y_2$~(and the same for $x_B$).

First, Alice and Bob communicate off-chain to construct collectively outputs of the final transaction~(payments to $y_1$ and $y_2$). Each of them then is calculating a hash value from outputs bytes $h$~(we assume that Blake2b-256 hash function is used). Then each of them is creating an output to spend~(possibly, in a dedicated transaction) with such a condition for Alice and Bob, respectively:

$blake2b256(tx.outbytes) = h \lor dlog(x_A)$

$blake2b256(tx.outbytes) = h \lor dlog(x_B)$

Then it is possible to make a refund at any moment of time~(right condition in the $\lor$ conjectures), and before a refund any of the them can construct a transaction which is spending the outputs, and it is impossible to construct an alternative transaction, for which hash of the output bytes is $h$, but bytes are different~(if chosen hash function is collision-resistant).

\subsection{Oracle Example}

\knote{Text below is just copied from code comments, polish it}

A trusted weather station is publishing temperature data on blockchain. Alice and Bob are making a contract based on the data:
they have locked coins in such way that if output from the station shows that temperature announced by the oracle is > 15 degrees, money are going to Alice, otherwise to Bob.

We consider that for validating transaction only limited number of last headers and the spending transaction should be enough, in addition to outputs being spent by the transaction. Thus there is no need for knowledge of an arbitrary output. To show the coin of the weather service in the spending transaction, outputs from Alice and Bob are referencing to the coin by using Merkle proofs against UTXO set root hash of the latest known block.

A tricky moment is how Alice and Bob can be sure that a coin is indeed created by the service, having just the coin (and also service's public key x = $g^w$, where service's secret w is not known.

For that, we consider that the service creates a coin with registers of following semantics (R0 and R1 are standard):

R1 - coin amount
R2 - protecting script, which is the pubkey of the service, $x = g^w$
R3 - temperature data, number
R4 - $a = g^r$, where r is secret random nonce
R5 - $z = r + ew mod q$
R6 - timestamp

Then Alice and Bob are requiring from the coin that the following equation holds: $g^z = a * x^e$, where $e = hash(R3 ++ R6)$

Thus Alice, for example, is created a coin with the following statement (we skip timeouts for simplicity):
"the coin is spendable by presenting a proof of Alice's private key knowledge if against UTXO set root hash for
the last known block there is a coin along with a Merkle proof, for which following requirements hold:
$R2 = dlog(x) /\ g^(R5) = R4 * x^(hash(R3 ++ R6)) /\ (R3) > 15$. Similarly, the coin is spendable by a proof of
knowledge of the Bob's private key if all the same conditions are met but $(R3) <= 15$.".

The Bob can create a box with the same guarding conditions. However, if Alice's box is already in the state, then Bob can stick to it by using the trick from the "along with a brother" test.

\section{Open Questions}

\begin{enumerate}
  \item Q: Let's use $\lor$, $\land$ for logical connectives, and $\sqcup$, $\sqcap$ for
           sigma-connectives correspondingly? \linebreak
        A:
  \item Q: Do we have "knowledge of Pedersen commitment $x_2$ preimage" somehow implemented? \linebreak
        A:
  \item Q: What are the limitations of \langname? \linebreak
        A: The following are the constraint of current implementation of \langname:
        \begin{itemize}
          \item Let bound expressions are copied in every usage site during compilation. This leads to repeated evaluation of the corresponding expressions.
          \item Lambdas are not first-class. After compilation all Lamdas should be inlined.
          \item Nested collections are not supported
        \end{itemize}
\end{enumerate}

\section{Types}

\[\begin{tabular}{@{}l c l l}
      $\mathcal{T} \ni \tau$			& ::= 	    &\
         \lst{Byte} $\mid$ \lst{Short} $\mid$
         \lst{Int} $\mid$ \lst{Long} $\mid$ \lst{BigInt}  & numeric types     \\
      &	$\mid$	& \lst{Boolean} 			& type of logical values true/false   \\
      &	$\mid$	& \lst{Unit} 				& type with single element   \\
      &	$\mid$	& \lst{GroupElement} 		& element of the cryptographic group  \\
      &	$\mid$	& \lst{Box} 				& value in a box protected by proposition  \\
      &	$\mid$	& \lst{AvlTree} 			&  Authenticated Dynamic Dictionary \\
      &	$\mid$	& $(\tau_1, \dots, \tau_n) $	& binary product type  \\
      & $\mid$  & $\text{\lst{Array}}[\tau]$	& array type       \\
      & $\mid$  & $\text{\lst{Option}}[\tau]$	& optional value (either $Some(\tau)$ or $None$)      \\
      & $\mid$  & \lst{Any}                     & type of any value (common supertype of all the types) \\
\end{tabular}\]

\section{Possible Other Sections, Not Currently Realized}
\begin{itemize}

\item Roadmap

\item Tree Nodes and Transformation Rules

\item Cost Table

\item Outputs vs Accounts OR A Language For An Account-Based Cryptocurrency

\item Unified Transactions

\item An Example of a Concrete Transaction Format \knote{Describe Ergo transaction format here. Malleability problems to be discussed here.}

\item Denial-of-Service Attacks

\item Extensibility : It is hard to predict which functions would be useful for blockchain applications.

\item Implementation and Evaluation

\item Further Work

\item Conclusion
\end{itemize}

\end{document}