0% found this document useful (0 votes)
71 views80 pages

Private Smart Contracts Framework

1. The document introduces Kachina, a new protocol for deploying private smart contracts. 2. Kachina aims to achieve the universality and uniformity of platforms like Ethereum for private contracts, allowing most contracts to be constructed under one framework. 3. The document outlines Kachina's contributions: providing a model for private smart contracts, realizing a class of private contracts, enabling concurrent interactions without compromising privacy, and demonstrating composable construction of contract systems.

Uploaded by

Bikash Khanal
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
71 views80 pages

Private Smart Contracts Framework

1. The document introduces Kachina, a new protocol for deploying private smart contracts. 2. Kachina aims to achieve the universality and uniformity of platforms like Ethereum for private contracts, allowing most contracts to be constructed under one framework. 3. The document outlines Kachina's contributions: providing a model for private smart contracts, realizing a class of private contracts, enabling concurrent interactions without compromising privacy, and demonstrating composable construction of contract systems.

Uploaded by

Bikash Khanal
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 80

Kachina – Foundations of Private Smart

Contracts

Thomas Kerber, Aggelos Kiayias, and Markulf Kohlweiss

The University of Edinburgh and IOHK


[email protected] [email protected] [email protected]

“v0.9” prerelease

Abstract. Smart contracts present a uniform approach for deploying


distributed computation and have become a popular means for develop-
ing security critical applications. A major barrier to adoption for many
applications is the inherently public nature of existing systems, such as
Ethereum. Several systems satisfying various definitions of privacy and
requiring various trust assumptions have been proposed; however, none
achieved the universality and uniformity that Ethereum achieved for non-
private contracts: One framework sufficing to construct most contracts.
We provide a unified security model for private smart contracts which is
based on the Universal Composition (UC) model and propose a novel
protocol, Kachina, for deploying privacy-preserving smart contracts,
which encompasses previous systems. We demonstrate the practicality
of Kachina by using it to construct a contract that implements privacy-
preserving payments, along the lines of Zerocash, which is provably se-
cure in the UC setting and facilitates concurrency.

1 Introduction
Distributed ledgers put forth a new paradigm for deploying Internet services that
transcends the classical client-server model. In this new model, it is no longer
the responsibility of a single organization or a small consortium of organizations
to provide the platform for deploying the relevant business logic. Instead, ser-
vice deployments can take advantage of decentralised “trustless” computation to
improve their transparency and security as well as reduce the need for trusted
third parties and intermediaries.
Bitcoin [25], the first successfully deployed distributed ledger protocol, does
not lend itself easily to the implementation of arbitrary protocol logic that can
support the above paradigm. This led to many adaptations of the basic protocol
for specific applications, such as NameCoin [18], a distributed domain regis-
tration protocol, or Bitmessage [29], a ledger-based communications protocol,
and many others. An obvious problem with this approach is that, even though
the Bitcoin source code can be copied arbitrary times, the Bitcoin community
of software developers and miners cannot, and hence such systems are typi-
cally not sustainable. Smart contracts, originally posited as a form of reactive
computation [27], were popularized by Ethereum [31], solving these problems
by providing a uniform and standardized approach for deploying decentralized
computation over the same back-end infrastructure.
Smart contract systems rely on a form of state-machine replication [26] – all
nodes involved in maintaining the smart contract keep a local copy of its state,
and advance this copy with a sequence of requests. This sequence of requests
needs to match for each node in the system – thus the need for consensus over
which requests are made, and their order. In practice, this is achieved through
distributed ledgers.
A seemingly inherent limitation of the decentralised computation paradigm
is the fact that protocol logic deployed as a smart contract has to be completely
non-private. This, naturally, is a major drawback for many of the applications
that can potentially take advantage of smart contracts. Promising cryptographic
techniques for lifting this limitation are zero-knowledge proofs [17], and secure-
computation [16,10]. Motivated by such cryptographic techniques, systems sat-
isfying various definitions of privacy – and requiring various trust assumptions –
have been proposed [4,22,32,19], as we detail in Subsection 1.2. Their reliance on
trust assumptions nevertheless, in one way or another, fundamentally limits the
decentralization features that are afforded by their non-private counterparts. For
instance, a common restriction of such systems is to assume a small, fixed set of
participants at the core of the system. This fundamentally clashes with the basic
principles of a decentralised platform like Bitcoin or Ethereum (collectively clas-
sified as Nakamoto consensus). In these systems, the set of parties maintaining
the system can be arbitrarily large and independent of all platform performance
parameters. This puts forth the following fundamental question that is the main
motivation for our work.

Is it feasible to achieve a privacy-preserving and general-purpose smart


contract functionality under the same availability and decentralization
characteristics exhibited by Nakamoto consensus?

In this work we carve out a large class of distributed computations that we


express as smart contracts, including contracts with privacy guarantees, that can
be implemented without additional trust assumptions beyond what is assumed
for Nakamoto consensus and the existence of a securely generated common ref-
erence string1 . The latter is not an assumption to be taken lightly – however,
it is a common requirement for privacy-preserving blockchain protocols with
strong cryptographic privacy guarantees. This class allows us to express the pro-
tocol logic of dedicated privacy-preserving, ledger-based protocols such as Zero-
cash [3] as smart contracts and subsumes existing smart contract systems such
as Zexe [4], Hawk [22], Zether [6], Enigma [32], and Arbitrum [19]. These pro-
tocols mainly rely on either zero-knowledge or signature authentication for their
security. The structure of Kachina is flexible enough to allow contract authors
1
Recent advances in zero-knowledge, especially for updateable reference strings, such
as [24] should allow such a reference string to be bootstrapped from consensus alone.

2
to express each of these systems together with a concise description of the pri-
vacy they afford. Thus, Kachina does not supersede these protocols, but rather
gives a common foundation on which one can build further privacy-preserving
systems.

1.1 Our Contributions


We make four contributions to the area of privacy-preserving smart contracts: (1)
We model privacy-preserving smart contracts, (2) we realise a large class of
such contracts, (3) we enable concurrent interactions with smart contracts,
without compromising on privacy, and (4) we demonstrate how to composably
build smart contract systems. Combined, they provide a practical foundation for
both reasoning about privacy in smart contracts, and constructing a practical,
real-world smart contract system with a good foundation for privacy.

Our model. We provide a universally composable model for smart contracts in


the form of an ideal functionality that is parameterised to model contracts both
with and without privacy. We designed out model to capture a broad range
of implementations of smart contracts while still remaining directly applicable
in practice. The expressiveness and relative simplicity of our model lends it-
self to further analyses of smart contracts and their privacy. Moreover, existing
privacy-preserving systems benefit from the model as a reference point for cross
comparison.
Concretely, we consider a smart contract to be specified by a transition func-
tion ∆ and a leakage function Λ, which parameterise the smart contract func-
∆,Λ
tionality Fsc . ∆ models the behaviour of the contract were it to run on a
local system or by a trusted party with perfect unobservable channels to the
parties that interact with it. It is a program that updates a shared state, and
∆,Λ
has its inputs provided by and outputs returned to the calling party. Fsc mod-
els network, ledger, and contract specific “imperfections” that also exist in the
ideal world by interacting with a Gledger -GUC functionality [9], and captures the
fundamental, ideal-world leakage through the parameterising function Λ.

Dealing with concurrency in a privacy-preserving manner. There exists a funda-


mental conflict between concurrency and privacy that needs to be accounted for
if we are to remain true to our objective of providing a smart contract function-
ality with the same decentralisation characteristics as Nakamoto consensus. To
illustrate, suppose an ideal smart contract is at a private internal state σ and two
parties wish to each apply a function f and g respectively to this state, such that
the result is independent of the order of application – i.e. f (g(σ)) = g(f (σ)) = σ 0 .
In any implementation of the above (which does not utilise coordination between
the parties), the first party (resp. the second) should take into account the pub-
licly known encoding [σ] of σ and facilitate its replacement with an encoded
state [f (σ)] (resp. [g(σ)]) as it results from the application of the desired tran-
sition in each case. It follows now that the encoded states [f (σ)], [g(σ)] must
be publicly reconciled to a single encoded state [σ 0 ] which necessarily must leak

3
some information about the transitions f and g. Being able to achieve this type
of public reconciliation while retaining some privacy requires a mechanism that
enables parties to predict transition conflicts and specify the expected leakage.
We achieve this through the novel concept of state oracle transcripts, which
are records of what operations and assumptions are performed on, and assumed
about, the contract’s state. These allow contract authors to optimise when trans-
actions are in conflict and when not, while also ensuring that the leakage is fixed
once the transaction is created. We further provide a mechanism for analysing
when reordering transactions is safe with respect to a user’s private state, by
specifying a sufficient condition for which transactions must be declared as de-
pendencies when creating a new transaction.

Our protocol. We construct a practical protocol for realising many privacy-


preserving smart contracts utilising only non-interactive zero-knowledge proof
systems. The primary goal of this protocol is to provide something sufficiently
low-level and general purpose to serve as a basis for building further privacy-
preserving systems on top of, without requiring the underlying system to be
upgraded with each new extension or upgrade. We focus on a setting where par-
ties may go offline at any time, and do not trust each other. The core idea behind
the protocol is to separate a smart contract’s state into shared public state, and
local private state, and prove the correctness of updates to the public state in
zero-knowledge.

Efficient modular construction. Kachina is designed to be deployed at scale:


Previous works using zero-knowledge, do not explicitly maintain a contract state.
If such a state σ was modelled anyway, (e.g. as inputs to these systems), the
zero-knowledge proofs involved would scale poorly, with a proving complexity of
Θ(|σ|) before any computation is performed. For this reason, a naïve approach
to state cannot scale to handle systems with a large state – such as a privacy-
preserving currency contract, without these being handled as special cases. Our
abstracting of state accesses solves this problem:
State oracles also help here, regardless of the size of our state. As the state
is never accessed directly, but only through oracles specified by the contract,
the complexity of what must be proven is under the full control of the contract
author and can be greatly decreased. As a result, a proving complexity of Θ(|T |)
prior to performing any computation can be expected in Kachina, where T is
either of the oracle transcripts involved. This constitutes a clear improvement,
as the state of smart contracts deployed in practice may be very large, however
transcripts similarly to the inputs and outputs of traditional, public contract are
generally short. This increase in efficiency allows us to present in Appendix J a
practical construction of an entire smart contract system, akin to Ethereum [31],
as a Kachina contract.
Not all contracts a user wishes to write will directly match the requirements
for realising a Kachina smart-contract. Our model is sufficiently flexible to allow
direct application of the transitivity of UC-emulation to solve this: Instead of just

4
specifying the contract (∆r , Λr ) which should be run, a security-conscious con-
tract author may also write a corresponding ideal contract (∆i , Λi ). Our model
gives great flexibility for the author to choose what leakage this contract incurs,
and what influence the adversary has over its behaviour. If the author then en-
sures that the implementation of this ideal contract fits Kachina’s realisation
requirements, then it is sufficient to prove that the real contract UC-emulates
∆r ,Λr ∆i ,Λi
the ideal one – that is, Fsc UC-emulates Fsc . By the fact that the real
contract meets Kachina’s preconditions, it in turn is UC-emulated by Kachina
– and consequently, by the transitivity of UC emulation, the contract author can
securely implement the original, ideal, contract. Te demonstrate this technique
we provide a UC realization of the salient features of Zerocash [3] – implemented
as a Kachina contract – in Section 5, and prove that it UC-emulates a much
simpler ideal payments contract.

1.2 Related Work

There has been an increasing amount of research into smart contracts and their
privacy over the past few years. The results of these often focus on specific use-
cases or trust assumptions. We briefly discuss how the most notable of these
relate to our work in Kachina.

Ethereum. As the first practically deployed smart contract system, Ethereum [31]
is the basis of a lot of our expectations and assumptions about smart contracts.
Ethereum provides no privacy guarantees of any kind, however we refer back to
it during this paper when arguing about modelling choices. We assume that the
reader has some familiarity with the basic flow of Ethereum, such as contract
creation, contract calls, and gas costs.

Zexe. Zerocash [3] is a well-known privacy-preserving payment system, allowing


direct private payments on a public ledger. Zexe [4] extends its expressiveness
by allowing arbitrary scripts, reminiscent of Bitcoin-scripts, to be evaluated in
zero-knowledge in order to spend coin outputs. Zexe itself does not discuss uni-
versal zero knowledge, and has no specified mechanism for using the structure
of unspent coins to construct larger systems, and therefore by itself suffers from
many of the same limitations of expressiveness that Bitcoin-script has. It is a
major improvement in expressiveness over Zerocash, which only permits a few
types of transactions.

Plutus. Plutus [11] provides a functional interpretation of UTXO ledgers and


generalises the UTXO model by introducing an extension that allows for per-
sistent state. While it does not itself consider privacy, it lends itself well to it
as a consideration – Plutus makes a similar distinction between off-chain and
on-chain code as Kachina does, and although it does not account for zero-
knowledge proofs, adding these is not far-fetched. The extended UTXO model is
of particular interest, as in combination with Zexe, and universal zero-knowledge,

5
it overcomes the former’s limits of expressiveness. A combination of these proto-
cols would arrive at a similar result as presented in this paper, although with a
more restrictive access to the shared state – due to the reliance on UTXOs, the
shared state of Plutus is a set allowing insertions and deletions, while Kachina
permits arbitrary operations.

Hawk. One of the earliest work on privacy in smart contracts, Hawk [22] is also
one of the most general. It describes how to compile private variants of smart
contracts, given that all participants of the contract trust the same party with its
privacy. This party, the “manager”, can break the contract’s privacy guarantees
if corrupt, however it cannot break the correctness of the contract’s rules. The
construction used in Hawk for the manager party relies of zero-knowledge proofs
of correct contract execution, and is closely related to the proofs parties perform
in Kachina. Kachina’s major difference is a greatly relaxed trust model, which
allows for contracts in settings where there no trusted third party to facilitate
privacy.

Zether. A lot of work on privacy in smart contracts has focused on retro-fitting


privacy into existing systems. Zether [6], for instance, constructs a privacy-
preserving currency within Ethereum, which can be utilised for a number of
more private applications, such as hidden auctions. As with most retro-fitted
systems, Zether is constrained by the system it is built for, and does not gener-
alise to many applications.

Enigma. There are two forms of Enigma: A paper discussing running secure
multi-party computation for smart contracts [32], and a system of the same
name designed to use Intel’s SGX enclave to guarantee privacy [14]. The former
has a lot of potential advantages, but is severely limited by the efficiency of
general-purpose MPC protocols. The latter is a practical construction, and can
claim much better performance than any cryptography-based protocol. The most
obvious drawbacks are the reliance on an external trust assumption, and the poor
track record of secure enclaves against side-channel attacks [5].

Arbitrum. Using a committee-based approach, Arbitrum [19] describes how to


perform and agree on off-chain executions of smart contracts. A committee of
managers is charged with execution, and, in the optimistic case, simply posts
commitments to state updates on-chain. In the case of a dispute, an on-chain
protocol can resolve the dispute with logarithmic complexity to the number of
computation steps taken. Arbitrum provides correctness guarantees even in the
case of a n − 1 out of n corrupt committee, however relies on a fully honest
committee for privacy.

State channels. State channels, such as those discussed in [13], occupy a similar
space to Arbitrum, due to their reliance on off-chain computation and on-chain
dispute resolution. The dispute resolution process is different, more aggressively

6
terminating the channel, and typically it considers only participants on the chan-
nel that interact with each other. The privacy given is almost co-incidental, due
to the interaction being local and off-chain in the optimistic case. State channels
are more restrictive in their expressiveness than Arbitrum, in that only few users
can interact with it, a drawback which allows for its main feature however: not
requiring on-chain transactions in the optimistic case.

2 Technical Overview

We first aim to establish informally the goals and core technical ideas of this
paper. These will be fleshed out in the remainder of the paper’s body, with some
of the technical details – primarily in-depth UC constructions and proofs – in
the appendix. We will discuss each of our contributions in turn, and discuss
how combined, they present a powerful tool for constructing privacy-preserving
smart contract systems.

Our model. When a user interacts with a smart contract system, two points
in time are important: The point where the user decides to query the smart
contract, and the point where this query has a lasting effect on the ledger.
Typically, and in our model, defined in Section 3, this takes the form of a user
creating a transaction at one point in time, and this transaction at some point
entering the confirmed ledger state.
At the core, a smart contract is a reactive state-machine, which alters its state
for each user query, according to a transition function ∆. A user can not know
what state the contract will be in, once one of their transactions is confirmed,
and it is quite possible for a transaction to no longer make sense – for instance,
two users cannot both spend the same coin. The adversary may provide its
own input to the transition function, that allows the adversary to influence the
contract’s execution as much – or as little – as the transition function allows.
When a user creates a transaction, in broadcasting it he likely leaks some-
thing about the transaction’s content. The transaction the user creates may also
depend not just in his original input, but the state of the system, as he sees it.
For instance, a user may be able to avoid conflicts with previous transactions
they made – such as in the case of spending UTXO-style coins, not spending
the same coin as a prior transaction. A leakage function Λ is responsible for
both deciding what information is leaked, and deciding which information from
the point of creating a transaction, may later affect its behaviour. This function
also generates a description of the leakage itself, which the user must sign off
on before the transaction is broadcast – this is not a technical requirement, but
an ethical one: As estimating leakage becomes more complex, users can not be
expected to predict the implications of their actions in advance.

The core protocol idea. The kernel of the Kachina protocol, as defined in Sec-
tion 4, is as follows: We restrict ourselves to contracts which divide their state
into a public state σ, and, for each party p, a private state ρp . Roughly these

7
correspond to the shared ledger, and a party’s local storage respectively. We
constrain the transition function to be over pairs (σ, ρp ) instead of over all pri-
vate states – i.e. a party may only change their own private state. Honest users
will maintain their own private state in accordance with the contracts’ rules,
while the contract must anticipate that dishonest parties may set it arbitrar-
ily (this can be circumvented by committing to private states, as descripted in
Appendix G).
In this setting, we can derive a clear image of what leakage is, and a nat-
ural construction based on zero-knowledge proof-systems presents itself: When
creating a transaction, a user may evaluate the transition function against the
current contract state, and prove the corresponding public state update σ 7→ σ 0
in zero-knowledge. Locally, the user updates his own private state, and publishes
a transaction consisting of the transition σ 7→ σ 0 , and a proof of this transitions
correctness.

State oracles. The core ideas as presented above is naïve in its construction,
primarily due to it proving transitions from one public state to another. In
practice, a contract does not exist in a vacuum, and other users will interact with
it. This is especially true for large systems – if I make an Ethereum transaction, it
will almost certainly be applied after many other transactions I do not even know
about. As these different states are not the same as the original, the transition
cannot be applied, as seen in Figure 1. Instead of capturing a transition from
σ 7→ σ 0 , we would rather want to capture a partial function from states to
successor states.

Transaction creation
σ π 7→σ n
σπ σn

σ π 7→σ n
σπ σn
···

Transaction application(s)

···
σ π 7→σ n
∅ ··· σo ··· σ1 7
···
·· σ π 7→σ n
· σ2 7
σ π 7→σ n
σ3 7
Fig. 1. Direct state-transition based transactions can be applied only in the state σ π
they were proven for.

Our approach for modelling this is to have contracts interact with the state
through oracle queries, instead of directly – see Subsection 4.1. A contract sub-
mits a function q to be run against the current state, this returns a result r, and

8
an updated state. Instead of proving the state transition correct, we prove that
the transition function makes a sequence of queries, given their responses match
a corresponding sequence of responses. We refer to this sequence of queries and
responses, ((q1 , r1 ), . . . , (qn , rn )), as an oracle transcript T . Transactions can be
used to determine if a transition makes sense in any given state, and if so, what
the new state should be: If each query, applied in turn, returns the expected
response, then the transition makes sense, and the same mechanism informs
what the resulting state will be. This allows a greater flexibility, sketched in
Figure 2, although it is worth noting that some conflicts are inherent, and can-
not be resolved. We illustrate our solution, and why it is necessary, in detail in
Subsection 4.1.

Transaction creation
T
σπ σn

T
σπ σn
···

Transaction application(s)
···
T
∅ ··· σ o ··· σ1 σ10
···
·· T
· σ2 7
T
σ3 σ30

Fig. 2. Oracle-transcript based transactions can be applied in any compatible state.

High-level usage. In practice privacy requirements may not fall within the bound-
aries of any general system, and will require some adjusting or combining with
novel research for their realisation. For instance, building a privacy-preserving
currency system is not possible in Kachina directly – after all, it needs the
balance to be a shared state, which a user cannot overwrite arbitrarily, but this
should also be private – being suitable for neither the shared public state σ, nor
the untrusted local private state ρ. In this case, the design of Zerocash [3] can
easily be adopted to overcome this issue – an example we work out in detail in
Section 5.2. This approach of adding additional layers of privacy is powerful, as
can be seen on this example.
This leaves an uncomfortable situation, however: The Zerocash protocol is a
poor ideal-world specification, but it is this we can realise directly. We propose
using multiple stages of UC-emulation instead: To begin with, we specify as an
ideal smart contract, what leakage and transitions a privacy-preserving payments
system should have. We then specify the core Zerocash design as a Kachina
contract, allowing us to conclude that the ideal Zerocash smart contract is UC-

9
emulated by Kachina, parameterised with the Zerocash definition. To bridge
the gap, we prove a further UC-emulation: the ideal private payments smart
contract is UC-emulated by the ideal Zerocash smart contract.
This allows us to rely solely on the transitivity of UC-emulation to extend
Kachina with additional privacy features – an approach that is made possible by
the design of the ideal smart contract functionality. This functionality provides
the abstraction of the leakage descriptor to ensure that the two worlds can have
the environment sign off on the same leakage, despite underlying differences.
Further, while the ideal smart contract’s adversarial input a is unused through-
out the Kachina protocol, it is crucial for this stage of the UC-emulation – it
affords the simulator a means to influence the ideal private payments contract’s
execution. In Section 5, where this full analysis is performed, this is used to
select party’s public keys in the ideal payments contract, for instance. Finally,
in Appendix J, we show how a system of multiple interacting contracts can be
constructed as an instance of a single, “system” smart-contract.

3 Defining Smart Contracts

In defining smart contracts, their typical implementation as replicated state


machines provides a simple solution: If a replicated state machine is the protocol,
the single state machine is the model. We assume that, as typically seen, inputs
are drawn from a ledger of transactions, and then passed as inputs to the state
machine.
Naturally, this definition is unsuitable for privacy-preserving smart contracts:
If the state machine’s behaviour is known, and its inputs are on a ledger, its
behaviour can be simulated by anyone. To allow for privacy then, we ensure that
the inputs themselves are not on the ledger – rather a token representing them.
The smart contract can ensure the correct input is executed, but an external
observer cannot.

3.1 Interactive Automata Interpretation

As mentioned above, smart contracts can be seen as “reactive computation”:


Parties supply input to the contract, which internally performs computation,
potentially involving hidden state. The contract updates its state and sends an
output in return back to the original caller. Models of smart contracts may
wish for results to be returned asynchronously, and to potentially depend on
interactions with other users. This fits less obviously into this model, which
assumes each interaction is atomic. However, such contract can be implemented
by a party repeatedly sending poll requests for the result. The assumptions
made about smart contracts, and those made of trusted third parties are –
almost – the same: they will carry out the computation given to them honestly.
Typical real-life systems have caveats here of course: 1. They leak all computation
done, 2. they allow for some adversarial influence, and 3. their behaviour may
depend on some context in addition to the input itself. 1. is a result of the

10
cryptographic simplicity of the construction, and does not necessarily hold for
privacy-preserving systems, although leakage is hard to eliminate completely). 2.
is a consequence of the usage of an underlying ledger, which permits adversarial
influence. Finally, 3. stems from it not always being possible for a transaction to
be applicable in any state. As a result, the state against which a user creates a
new transaction dictates partially when this transaction makes sense.
To represent the contract, we will consider its state σ, and a transition func-
tion ∆. We will adopt the convention that the initial state is denoted by ∅, even
though the contract itself may ascribe a different meaning to this. ∆ should be
a function which takes as inputs the old state, some input w, and the party
identifier of the submitter, p. It should return a new state, σ 0 , and an output y.
While this is sufficient for many things, we will also allow as inputs a context z,
and an adversarial input a. We assume ∆ to be deterministic – nondeterminism
can be simulated by including a randomness source in the context, as seen in
Subsection 4.3. In sum total, a contract is primarily defined by the following
transition function: (σ 0 , y) ← ∆(σ, p, w, z, a).
As mentioned previously, real implementations of smart contracts have some
leakage. Further, due to the ledger-based nature of them, this leakage occurs
separately, before the contract actually evaluates the input. We define a non-
deterministic leakage function Λ, which takes the input w, the party ID p, and
the state of the smart contract in the user’s current view, σp . This function
should return some leakage lkg, which is passed to the adversary.
At the same time, Λ can define what the context z used in the transition
function should be. This value is important for allowing the behaviour of a
contract depend on when a query was submitted, and not just when it is executed
– this will be detailed further in Subsection 4.1. As smart contracts are complex
objects, the user can not be expected to accurately anticipate what leakage a
given query might incur. As a result, we will also return a leakage descriptor
desc, which the user must sign off on before any leakage occurs, or the query is
fully submitted.
A few additional variables may affect what gets leaked. In particular, the
transactions a user previously made, but which are not yet in the confirmed
ledger state may affect the behaviour of new transactions by the same user. For
instance, if the user previously spent a coin, they will not attempt to spend it
again. For this purpose, each such unconfirmed transaction, identified by some
transaction handle τ , is passed to the leakage function, as the list of unconfirmed
transaction Up . Further, a mapping T is supplied, mapping each transaction
handle to the tuple (p, w, z, a, D), dictating the transaction’s owning party, input,
context, adversarial input, and lastly dependencies. These are all as discussed
before, except dependencies, which will be explained shortly. Finally, the leakage
function is given the length of p’s view of the ledger, t – named due to its
approximation of time.
D represents transaction dependencies, which in this work have proven to
be necessary to ensure transactions are executed in the correct order. At a high
level, each transaction has associated dependencies, specified as a list of other

11
transactions, and ideally being . If a new transaction is processed, each of its
dependencies must have previously been successfully processed in the same order,
or the new transaction is rejected. These allow enforcing ordering constraints on
transactions, and constitute a form of leakage. This is also the final purpose of Λ:
to determine which dependencies the new transaction should have. In summary,
a contracts leakage and context are computed as follows: (desc, lkg, D, z) ←
Λ(t, Up , T, σp , p, w).
We consider the pair (∆, Λ) to define a smart contract, and parameterise the
ideal smart contract functionality presented in Subsection 3.2 by both.
The general ideal world usage of this model of smart contracts follows this
pattern:
1. A party submits a contract input w.
2. The corresponding context and leakage are computed.
3. The party signs off on the leakage description desc, or cancels.
4. The adversary is given (lkg, D), and can supply the adversarial input a.
5. At some later point, the submitting party can retrieve the output of ∆ (if
any), while other parties can interact with the modified state.

3.2 UC Specification
∆,Λ
The ideal smart contract functionality Fsc formally captures this notion of
a contract as a leaky state transition function that can be queried by parties
via a ledger. It is parameterised by the transition function ∆ and the leakage
function Λ, and it operates in a hybrid world with a ledger functionality Gledger . A
candidate for such a ledger is GsimpleLedger , as introduced in Appendix B, although
any compatible functionality is sufficient. To avoid confusion with the various
∆,Λ
contract state in Fsc , we refer to both the authoritative ledger state as well as
the party specific prefixes of that state as ledger views.
∆,Λ
Functionality Fsc (sketch)

The smart contract functionality Fsc∆,Λ allows parties to query a deterministic


state machine determined by ∆ and Λ in a ledger-specified order.

Executing a ledger view:


Starting with an initial state σ ← ∅, and an empty set of confirmed trans-
actions, for each transaction in the ledger’s view, if the transaction is unknown,
allow the adversary to supply its inputs. Next, verify the transaction’s dependen-
cies, and that, for (σ 0 , y) ← ∆(σ, . . .), σ 0 6= ⊥. If both are satisfied, update σ to
σ 0 , and record the transaction as confirmed. If an execution output is requested,
return y. If, on the other hand, one of the preconditions is not satisfied, skip this
transaction and record the transaction as rejected.

Prior to any interaction by p:


Compute which transactions have been rejected in p’s view of the ledger state,
and remove any unconfirmed transactions for p that – directly or indirectly –
depend on them.

12
When receiving a message (post-query, w) from an honest party p:
Retrieve p’s current ledger view of length `, and compute the corresponding
smart-contract state using ∆. Feed this, together with p’s unconfirmed transac-
tions and their inputs, the length `, and the input w to Λ.
Ask p if the leakage description returned is acceptable. If so, query the ad-
versary for a unique transaction ID τ , and some adversarial input corresponding
to the leakage, and the transaction’s dependencies. Record the original input, the
adversarial input, the context returned by Λ, and the transaction’s dependencies
as being associated with τ and p. Record the transaction as unconfirmed by p,
and then send (submit, τ ) to Gledger , and return τ .

When receiving a message (check-query, τ ) from an honest party p:


If τ is owned by p, and in their current view of the ledger, compute and return
the output by executing the ledger view up to τ .

Some combinations of ∆ and Λ are not obviously realisable, in particular


the more restricted the leakage becomes. They do however give the flexibility
necessary to model existing smart contract systems, both privacy-preserving
and otherwise. For instance, a leakage function which leaks the input itself, has
no context, and no dependencies, corresponds closely to Ethereum [31], while
a leakage function returning no leakage makes many transition functions hard
or impossible to realise. We will focus on a more interesting middle ground in
the rest of this paper. By defining the ideal behaviour to involve the ledger, we
avoid having to duplicate the complex adversarial influence of ledger protocols
∆,Λ
to model the adversarial influence of smart contracts. Further, Fsc makes few
assumptions about the ledger, requiring only the common prefix property, and
interfaces for submitting and reading transactions to be well defined.

4 The Kachina Protocol

As mentioned in Section 2, a naïve construction divides a contracts state into a


shared public state, and a local private states for each party. A user may then
prove the validity of any public state transition – that is, that there exists some
private state, and some input, such that this transition takes place. This clearly
does not scale well, however, as it assumes that the ledger state does not change
between the submission and processing of a transaction.
In practice, a user’s query may not be evaluated immediately, and the ledger
may change drastically in the mean time. Simply proving a direct state transition
would lead to a high proportion of queries being rejected. An equally serious flaw
with this naïve approach is that NIZK proofs over the entirety of both the public
and private contract states may be infeasible in practice. In complex systems such
as Ethereum, the state is on the order of hundreds of Gigabytes [15], and only
increasing.
We utilise the same trick to circumvent both problems: We make the inter-
action with the state more abstract, ensuring both that it can be flexible enough
to tolerate reordering, and concise enough to allow efficient proofs.

13
4.1 State Oracles and Transcripts

We introduce the novel tools of state oracles, and state oracle transcripts to
abstract interaction with a contract’s state. When abstracting interaction with
the public and private states, many options are possible – we could constrain the
state to a specific type of data structure, and only support certain operations
over it for instance. This is in fact what the extended UTXO model [11], and
Zexe [4] do. While this has many practical benefits, and is easy to reason about,
it does not, however, enable the action performed on-chain to depend on the
chain’s most current state, which Ethereum permits.

An example. To better motivate the need for some further abstraction over state
interactions (i.e. not proving a state transition directly), we present a represen-
tative example of a smart contract, and discuss how different abstractions of its
state will affect its ability to function.
In particular, we consider a sealed bid auction contract2 . We will assume
that external to this contract exist a notion of time, and two separate privacy-
preserving on-chain assets3 , all within some large system the auction contract
may interact with (such as those presented in Appendix J). The auction is opened
by the seller party, and multiple buyer parties may bid on it. The structure of
this auction allows for the following interactions:

– At initialisation, the seller transfers ownership of asset A to the auction


contract, and publicly reveals it (i.e. the buyers can verify the authenticity
of the auction).
– Until time t1 , buyers may submit their bids, by transferring some amount of
asset B to the auction contract, which remains anonymous.
– Between time t1 and t2 , buyers may reveal their bid. If the buyer’s bid exceeds
the currently maximum revealed bid, he reveals his committed asset, and
both increases the maximum bid, and records himself as the winning bidder.
Otherwise, he withdraws his bid from the contract.
– After time t2 , buyers may withdraw any assets they own after the auction,
that is either their losing bids or the sold asset for the highest bidder. Sellers
on the other hand can withdraw either the highest bid or the original asset
if no bids were made.

What state must such an auction contract maintain? We are considering


time and asset management to be maintained externally, but nonetheless a little
bookkeeping is necessary: The contract will need to publicly maintain a reference
to the asset being sold, in order to correctly transfer it at the end. Further, it
will need to maintain what the currently winning bid is, along with its value,
2
This contract is designed to make a good example, not a good auction – we do not
recommend using it as presented.
3
These may be constructed similarly as in Section 5, however should be holdable and
spendable by other contracts. We do not go into detail of this construction; this idea
is fleshed out in detail in Zether [6].

14
and some identification of the current winner. It needs to maintain a set of
the bids themselves – these may just be some kind of reference for the asset
management system to verify, however there is a need to ensure that a buyer
cannot create a new bid after time t1 – something which is not the job of any
asset management system. Finally, we keep a further set: bids which have been
the maximum revealed at some point, but were then succeeded. Privately, the
contract has minimal bookkeeping to do: Parties need to remember which bids
are theirs, and what information is needed to open or withdraw them.
Suppose we adopted a naïve approach to state transitions, and proved the
transitioning from one state to another directly, with no abstraction of any kind.
During the bidding phase it is easily possible for multiple users to attempt to
bid simultaneously (especially considering the delay until transactions become
confirmed by an underlying ledger). In this case, only one of these transactions
will go through – as soon as this transaction changes the state by adding its own
bid, the proof of any other simultaneous transaction becomes invalid.
Often simple abstractions are used instead, such as byte-level access. This
would allow a buyer and the seller to withdraw concurrently – as their withdraws
affect different parts of the state. It does not work as desired in all cases even
in this example – assume a singly-linked list is used to store the set of bids. If
two users attempt to add their own bid to this set simultaneously, they will both
attempt to overwrite the same pointer.
Clearly this is not necessary – a smart abstraction would realise that whichever
user bids first, the resulting set of bids is the same, even if its binary represen-
tation may not be. It is not always the case that the order does not matter – for
instance when claiming the maximum bid later in the auction, if Alice wishes
to claim her bid of 5 is the maximum, she cannot do this after Bob has claimed
his bid of 7. Even here a smart abstraction buys us something however – while
Alice’s transaction may get rejected if placed after Bob’s, the other way around
is fine!

General-purpose state oracles. The solution we propose is to allow the contract


itself to define how state is updated – specifically, instead of sending the instruc-
tion (append, x), it may send a program encoding, for instance, “increment the
length l of the array by 1, and insert a pointer to x at position l − 1”. More for-
mally, the generalisation of an abstract data type that the contract may make
queries to, is that of a universal machine, operating over an internal state, which
the contract may query with contract specific programs.
We define O ← U(σ, z) to be a universal state oracle. It maintains internally
the current state σ, the context z, and a transcript T . Initially, these are set
to (σ, z, ). The oracle can be interactively queried with a sequence of inputs
q1 , . . . , qn . For each query qi that is made, the oracle in state (σ, z, T ) computes
(σ 0 , ri ) ← qi (σ, z), and updates its internal state to (σ 0 , z, T k (qi , ri )), before
finally returning ri as a response to the query. An exception to this is if σ = ⊥,
in which case σ 0 and ri will also be ⊥. This is the error state. We define state(O)
to return (σ, T ), out of its internal state.

15
The context z encodes additional information a party expects the oracle to
have access to. The need for this context will be detailed later, once the basic
functionality is established. If z = ∅, we may write qi (σ), and omit z. The
oracle may itself abort, in which case we assume any function using it directly
will return ⊥ (in particular Γ, as used in Subsection 4.3). An overview of the
interactions of Γ with public and private state oracles may be found in Figure 3.

z ρ w σ
Private
q1ρ q1σ
r1ρ r1σ
.. ..
U . Γ . U
qnρ qnσ
rnρ rnσ

Trusted
0 y
ρ σ0

Fig. 3. The interaction of Γ (see Subsection 4.3), with Γ having oracle-access to two
separate states: the public state σ, and the private state ρ, together with the context
z.

Crucially, we note that the definition above allows retrieving the queries made
to the oracle, and the responses given by it. We will refer to this sequence of
queries and responses as the oracle transcript T . This transcript is crucial in
the functioning of Kachina, as it provides a means to decouple the part of a
transaction which is proven in zero-knowledge from both the public and private
states entirely. Specifically, we prove that given some input, and a sequence of re-
sponses recorded in a transcript, the smart contract will make the corresponding
queries.

Revisiting our example. To see how this works in practice, we consider what
interactions (besides those verifying time, and the authenticity of the assets
transferred) are made through the public state oracle in our example of a sealed
bid auction. To be more concrete, let us assume that the public state σ consists
of the following elements: 1. A public key of the seller, allowing it to withdraw:
pks , 2. A non-private representation of asset B, the item for auction: b, 3. A
non-private representation of the current maximum bid of asset A: a, 4. The
value of the bid in 3.: v, 5. The public key of the current maximum bidder,
pkb , 6. A set of private representations of asset A of bids: S, and 7. A set of
non-private representations of asset A of previous maximum bids, R. We write
σ = (pks , b, a, v, pkb , S, R), initialised by the seller to (pks , b, ∅, 0, ∅, ∅, ∅).

16
The private state ρ by contrast consists of three variables describing an un-
opened bid: the opening pubBid that is eventually to be made public, a hiding
commitment which it is an opening for, bid, and its value v, all of which may be
set to ⊥: ρ = (pubBid, bid, v)
For each of the (non-initialising) interactions previously listed, we demon-
strate the corresponding oracle queries made:

– Bidding: Given a non-private asset pubBid, with value v, corresponding to


a private asset bid, which has been bound to the auction contract, Γ first
makes the following public oracle query:
function makeBidbid ((pks , b, a, v, pkb , S, R))
return ((pks , b, a, v, pkb , S ∪ {bid} , R), >)
Further, it makes the following private oracle query:
function recordBidpubBid,bid,v (·)
return ((pubBid, bid, v), >)
– Revealing: Given a public key to redeem the funds to in case of losing the
auction, Γ first makes a private oracle query to retrieve which bid is owned:
function retrieveBid((pubBid, bid, v))
return ((pubBid, bid, v), (pubBid, bid, v))
Next, the contract makes a public oracle query to determine if the buyer
holds the current maximum bid:
function isMaxv (σ = (. . . , vo , . . .))
return (σ, v > vo )
If this query returns >, the contract claims the maximum bid with the query:
function claimMaxpubBid,bid,v,pk ((pks , b, ao , ·, pko , S, R))
assert bid ∈ S
return ((pks , b, pubBid, v, pk, S \ {bid} , R ∪ {(ao , pko )}), >)
If the original value test fails, on the other hand, instead the contract trans-
fers the ownership of bid via the underlying asset system to pk, and runs:
function claimLoss((pks , b, a, v, pko , S, R))
return (>, (pks , b, a, v, pko , S \ {bid} , R))
– Withdrawing: Given a public key pk, which the caller knows the correspond-
ing secret key for, the contract will make an oracle query to determine which
assets to transfer ownership of, and to un-record them:
function withdraw((pks , b, a, v, pkb , S, R))
if pk = pks ∧ a 6= ∅ then return ((∅, b, ∅, ∅, pkb , S, R), a)
else if pk = pkb ∧ b 6= ∅ then return ((pks , ∅, a, v, ∅, S, R), b)
else if ∃c : (c, pk) ∈ R then return ((pks , b, a, v, pkb , S, R \ {(c, pk)}), c)

While this example does not fully handle all corner cases (such as a buyer
bidding multiple times), it is hopefully sufficient to illustrate the core idea: The
query made, and the response to it, will often be the same even if another party
has since interacted. Two bid do not conflict, as the oracle queries each makes
can be run even if the contract’s state has since changed. We also do not need to

17
concern ourselves with the representation: Whether the sets are implemented as
linked lists, arrays, or balanced trees does not matter – the abstract data type
behaves the same, after all.

Transcript application. We define some shorthand notations for talking about


transcripts: For a given transcript T , state σ, and context z, we write T (σ, z) as
a shorthand for the following operation:
function T (σ, z)
let O ← U (σ, z)
for (qi , ri ) ∈ T do
send qi to O and receive the reply r
if r 6= ri then return ⊥
let (σ 0 , ·) ← state(O)
return σ 0
If z = ∅, we may write T (σ), and omit z. If T is malformed (i.e. not a sequence
of pairs), we assume ⊥ is returned.
We further define the application of transcript sequences: Given a sequence X
of transcript and context pairs (T , z), we write TX∗ (σ) for the transcript sequence
application. Specifically, we define T∗ (σ) := σ, and TX∗ k (T ,z) (σ) := T (TX∗ (σ), z).

Transcript oracles. For a given transcript T , we define the transcript oracle O(T )
to act as an oracle with the following behaviour: Internally, it keeps a counter i,
initialised to 1. Let T = (q1 , r1 ) k . . . k (qn , rn ). Then, when receiving a query
q, check if q = qi . If so, increment i, and return ri . If q 6= qi , or i > n, abort.
For transcript oracles, we define the additional function consumed(O), which
returns > if and only if i + 1 = n, i.e. each recorded query has been processed
by the oracle. We refer to a transcript as minimal in some usage context, if once
the usage context, given oracle access to the transcript oracle returns, consumed
holds.

Oracles, transcripts, and interchangeability. The core premise of Kachina relies


on a few key observations on how transcripts relate with the original, universal
state oracles. First, we observe that if σ 0 = T (σ, z) 6= ⊥, then σ 0 is indistinguish-
able to having been produced with the universal oracle U(σ, z), by the nature
of the definition of transcript application. This lets us, given the transcript and
context, reproduce the behaviour of some function which was parameterised by
the transcript, even if we do not know why this function made the queries it did.
In the protocol, this is primarily used to replicate the affects other users’ queries
have on the public state.
Further, we observe that if the transcript oracle O(T ) doesn’t abort when
used as an oracle in some function, then it behaves identically to the original
universal oracle that was used to generate the transcript. We use this fact to gen-
erate zero-knowledge proofs about transactions – we prove that each oracle query
in a transcript was made, and that the behaviour is correct, given the responses
the transcript claims. As a caveat here, we further prove that consumed(O), in

18
order to be able to claim that the transcript doesn’t just start with the queries
an honest execution would make, but matches them exactly.
To tie things together, the basic function is that Alice generates a transcript
for the oracle accesses that her private computation performs. She proves this
transcript correct, and minimal. She sends the transcript and proof to Bob, who
is convinced of the correctness and minimality, and can therefore replicate the
effects of the transcript by applying it to the state directly.

Inherent conflicts. While the approach of abstracting the interaction with the
state away has many benefits, it relies on the contract itself making use of them in
such a way that the original problems of resilience to reorderings are not simply
pushed down the line. For instance, a contract which offers some currency to
the first party to interact with it clearly is not resilient to reordering, by its
very design. Nonetheless, two parties may both see the contract, see the funds it
holds unclaimed, and both decide to claim them. This inherent conflict cannot
be resolved, simply because the parties are acting concurrently.
It is further possible for a contract to be poorly designed, and introduce
conflicts through that. Suppose a contract is auctioning an item, and two parties
wish to bid. A poorly programmed design may have an array of bids in the public
state, and may see both parties attempting to place their bid into the first cell
of the array. A functionally equivalent approach, minimising conflicts, would
instead instruct the public state to insert at the end of the array, regardless of
how many items are occupied.

A note on context. The design of oracles for interacting with the state of the
contract is convenient when this response of the oracles is unlikely to change
over time. In some cases, however this is just not feasible, and the contract may
need advice about highly volatile state. For instance, the Merkle tree roots used
in the Zerocash [3] protocol change with every transaction processed, but need
to have statements proved about them.
To solve this problem, we run the private state oracle in the context of the
view of the submitting party at the point of transaction creation. Specifically,
it can not only read and write the current private state, but can also read the
public and private states at the time when the query was submitted. We also
provide the contract access to “optimistic projections” of the state, which are
the public and private states if all unconfirmed transactions were to appear in
order immediately after the parties current ledger state. This allows the party
to avoid conflicting with their own unconfirmed transactions – for instance in
the Zerocash contract described in Section 5.2.
Finally, we provide a randomness source η as part of the context – this is
chosen as well at the time of query, and ensures that – for honest parties – the
private state oracle may behave nondeterministically. Formally, the context z in
Kachina is a tuple (σ o , ρo , σ π , ρπ , η), where (σ o , ρo ) is the querying parties view
of the contract state at the time of submission, and (σ π , ρπ ) is their projected
view of the contract.

19
4.2 The Challenge of Dependencies

Consider two transactions, τ1 and τ2 being reordered. If τ1 moves funds from


Alice to Bob, and τ2 from Bob to Charlie, it is clear that the sequence τ2 . . . τ1
may not be valid, if Bob’s transfer relies on the funds he receives from Alice.
Fortunately, if conflicts occur on the public state, such as in this case, the ledger
protocol catches them, and ensures that the invalid transactions are ignored.
The possible effects on a users private state are more challenging to under-
stand, however. While two different parties cannot conflict with each other on
private state changes, due to their domain separation, parties can encounter in-
ternal conflicts. Consider that p, starting with the private state ρ1 , makes the
transaction τ1 which advances their private state to ρ2 . Afterwards, they make
transaction τ2 , ending in private state ρ3 . Now, if these transactions are made
close to each other, it is possible for them to be reordered on the ledger. How-
ever the transaction τ2 may – from the perspective of private state updates –
make no sense coming first. Indeed, the corresponding private state transcript
Tρ,2 may be such that Tρ,2 (ρ1 , z2 ) = ⊥. What then? Should the user act as if the
transactions had happened in the right order, potentially leading to confusing
inconsistencies between the private state, and the shared public state? Should
the user faithfully apply Tρ,2 , and accept that the contract has encountered a
catastrophic failure? Obviously both are not ideal, and the more practical solu-
tion is to claim that τ2 depends on τ1 . This information can be published as part
of the transaction, and their ordering enforced by the on-chain validation.
What remains unclear is what the dependencies of a new transaction should
be. If a user has a set of unconfirmed transaction U , and is adding the new
transaction τ in the ledger state Σ, naïvely what dependencies should capture
a constraint over which permutations of the unconfirmed transactions are per-
missible. More precisely, suppose we are given a sequence of transactions Σ 0 ,
where Σ is a prefix of Σ 0 , and Σ 0 both contains all transactions in U ∪ {τ },
and they are all “valid”. Then taking the permutation of U ∪ {τ } of transactions
from Σ 0 , and applying the corresponding private state oracle transcripts in order
to the current private state should give a sane, non-⊥, result regardless of the
permutation.
As proving that some transactions are non-conflicting may be application
specific, instead of having a general-purpose means to capture what a trans-
actions dependencies are, we instead allow a dependency function dep to be a
parameter, and constrain how this must behave. We can also provide a “fall-
back” dependency function, which is overly aggressive in which transactions it
depends on.

Formal definition. More formally, dep is a pure function, over the following items:
a) a set of unconfirmed transactions, their associated private state transcript,
their associated context, and their respective dependencies. b) the new transac-
tion’s private state transcript, and c) the new transaction’s context (including
the confirmed private state, ρo . It returns a sequence of transactions which must

20
all proceed the new transaction, in the specified order. In mathematical notation,
D ← dep(X, T , z), where ∀x ∈ X : ∃τ, Tτ , zτ , Dτ : x = (τ, Tτ , zτ , Dτ ).
To begin with, we introduce some mathematical notation: First, we write SX
for the set of all permutations of the set X, where each permutation is assumed
to be a list. Second, we write X v Y for the subsequence relation, where one list
is a subsequence of another if and only if the items of the first are found in the
second in the same order:

X v Y := X ⊆ Y ∧ (∀a, b ∈ X : idx(X, a) < idx(X, b) =⇒ idx(Y, a) < idx(Y, b))

To define the constraints of dep, we also define dependency satisfaction. In


the actual protocol, a transactions dependencies are satisfied if two conditions
hold: a) Each of the dependencies are confirmed transactions, and b) D v Σ,
where Σ is the ledger of transactions. In the context of generating dependencies,
we have a more relaxed approach, and want to consider only the permutations of
unconfirmed transactions which could possibly be satisfied. We therefore ignore
dependencies outside of this set of unconfirmed transactions. For instance, if we
have two unconfirmed transactions, a and b, where b depends on ac, we ignore the
dependency on c, and we consider the sequence ab to satisfy dependencies, but ba
to not do so. Formally, the predicate sat(X, U ) takes some form of permutation
of X in dep, and a set of unconfirmed transactions U . We define sat(, U ) := >,
and sat(X k (·, ·, ·, D), U ) := sat(X, U ) ∧ (D ∩ U ) v map(proj1 , X).
We now define the invariant J(X, ρ), stating that given the sequence X, and
state ρ, for any permutation of any subset of X, if dependencies are satisfied,
the corresponding private state transcripts can be applied in the permutation
order without aborting: J(X, ρ) := ∀Y ⊆ X, Z ∈ SY : sat(Z, map(proj1 , X)) =⇒

Tmap(proj (ρ) 6= ⊥.
2 ×proj3 ,Z)
We can now define the constraints on dep:

1. If called with non-honestly generated transcripts or contexts, no constraints


need to hold.
2. The result must be a subsequence of the transactions in X:
dep(X, T , z) v map(proj1 , X)
3. When adding a new transaction τ , with the corresponding transcript T and
context z, the invariant J is preserved:

let Y = X k (τ, T , z = (·, ρo , ·, ·, ·), dep(X, T , z)) in Tmap(proj (ρo ) 6=
2 ×proj3 ),Y
o o
⊥ ∧ J(X, ρ ) =⇒ J(Y, ρ )

Finally, we note that the following dependency function will always satisfy
the constraints: dep(X, T , z) = map(proj1 , X). This is as it maximally constrains
the possible permutations which satisfy the dependencies.

4.3 The Contract Class

The class of contracts achievable by Kachina, CKachina , is defined primarily by


constraining them to a modified transition function, Γ. This transition function

21
is given oracle access to the calling user’s private state ρp , and a shared public
state σ, with oracle accesses functioning as described in Subsection 4.1, and
Subsection 4.1. The adversary is permitted to program its own private state
oracle arbitrarily – this corresponds to local computation, after all. In addition to
Γ, the protocol is parameterised by a leakage descriptor desc, which receives the
time t, the sequence of unconfirmed transactions, their private state transcripts
and dependencies, X, both public and private state transcripts Tσ and Tρ , the
original input w, and the context z. Finally, it is parameterised by a dependency
function dep, which is under the constraints noted in Subsection 4.2.
Formally, (∆Kachina , ΛKachina ) ∈ CKachina if and only if there exist corre-
sponding Γ, desc, and dep, such that they are derived approximately as follows:

Transition Function ∆Kachina (sketch)

When receiving an input ((σ, ρ), p, w, (Tσ , z), ·):


if Tσ (σ) = ⊥ then return (⊥, ⊥)
let (σ, ·, ρ[p], ·, y) ← run-Γ(σ, ρ[p], w, z, p ∈ H)
return ((σ, ρ), y)
Where run-Γ(σ, ρ, w, z, ·) runs ΓOσ ,Oρ (w), and returns (σ 0 , Tσ , ρ0 , Tρ , y) (see Ap-
pendix C for a full specification).

Leakage Function ΛKachina (sketch)

When receiving an input (t, U, T, (σ o , ρo ), p, w):


Simulate applying all unconfirmed transactions in order, for a new projected
state (σ π , ρπ ). Select a randomness stream η, and set the context z to the old
state (σ o , ρo [p]), the projected state (σ π , ρπ ), and η. Run Γ against this pro-
jected state and context, and retrieve the new states and transcripts Tσ , Tρ .
Compute the dependencies D and leakage description description, and return
(description, Tσ , D, (Tσ , z)).

Some corner cases have been omitted; the full version of these functions may
be found in Appendix C.

4.4 The Kachina Protocol

The construction of the protocol itself is now fairly straightforward – as already


noted, instead of proving statements about transition functions directly inter-
acting with the state, it uses non-interactive zero-knowledge to prove statements
about transition functions interacting with an oracle. Specifically, when creating
a transaction, users prove that the generated transcript is consistent with the
transition function and initial input. Instead of evaluating transactions, users ap-
ply the public (and, if available, private) state transcripts associated with them.
We sketch the protocol here, the full details can be found in Appendix C.

22
Protocol Kachina (sketch)

The Kachina protocol realises the ideal smart contract functionality when pa-
rameterised by a transition function Γ, a leakage descriptor desc, and a depen-
dency function dep, such that the corresponding (∆, Λ) pair is in CKachina . It
L
operates in the (Fnizk , GsimpleLedger )-hybrid model, where ((Tσ , ·), (w, Tρ )) ∈ L iff
ΓO(Tσ ),O(Tρ ) (w) does not abort, and exists normally.

Executing a ledger state:


Starting with an initial state (σ, ρ) ← (∅, ∅), and an empty set of confirmed
transactions, for each transaction in the ledger verify their dependencies, and that
Tσ (σ) 6= ⊥. If both are satisfied, apply Tσ , and if available, the corresponding Tρ ,
and mark the transaction as confirmed. Otherwise, skip it.

Prior to any interaction:


Compute which transactions have been rejected in the ledger state, and remove
any unconfirmed transactions that – directly or indirectly – depend on them.

When receiving a message (post-query, w) from a party p:


Read the ledger state, and compute the corresponding smart-contract state
(σ o , ρo ). Create a projected contract state (σ π , ρπ ) by applying in order the tran-
scripts from unconfirmed transactions to the already computed contract state.
Select a randomness stream η, and set the context z to the old state (σ o , ρo ),
the projected state (σ π , ρπ ), and η. Run Γ against against this projected state and
context, and retrieve the new states and transcripts Tσ , Tρ , as well as the output
y. Compute the dependencies D and leakage description description.
Ask p if description is an acceptable leakage. If so, create a NIZK proof π that
((Tσ , D), (Tρ , w)) ∈ L. Record Tρ and z, and the result y, and publish on Gledger ,
record as unconfirmed, and return the transaction (Tσ , D, π).

When receiving a message (check-query, τ ) from a party p:


If τ is in the current view of the ledger, execute the ledger and check if τ
is confirmed, and an output for it has been recorded. If so, return the recorded
value.

∆,Λ
Theorem 1. For any contract (∆, Λ) ∈ CKachina , Kachina UC-emulates Fsc ,
L
in the Fnizk -hybrid world, in the presence of GsimpleLedger .

We prove Theorem 1 through a detailed case-analysis of any action an en-


vironment, in conjunction with the dummy adversary, may take. The full case
analysis may be found in Appendix D, however we provide a general intuition
here. We define an invariant I between the real and ideal executions in the UC
security statement, roughly encoding that “the real and ideal states are equiva-
lent”. This ranges from simple equivalences, such as them having the same ledger
states, or the same NIZK proofs considered valid, to complex invariants, such as
all unconfirmed honest transactions satisfying the sub-invariant for dependencies
defined in Subsection 4.2. This invariant is used to argue that the environment,
in combination with a dummy adversary, cannot distinguishing between the real
and ideal worlds. Specifically, for any action the environment takes, I is pre-

23
served, and from I holding, we can conclude that the information revealed to it,
or the dummy adversary, is insufficient to distinguish the two worlds.
The simulator for Kachina is quite straight forward; it simply creates simu-
lated NIZK proofs for all honest transactions, and forces the adversary to reveal
witnesses to the simulated NIZK functionality in time for these to be input to
the ideal smart contract. Fundamentally, the security proof relies on state tran-
scripts, as defined in Subsection 4.1, being interchangeable with full state oracles
in the same setting, and this setting being enforced by both the protocol and
functionality.
While a lot of factors must be formally considered, this is derived from re-
ceiving NIZK proofs as part of valid transactions, which prove precisely that if
the preconditions for the transaction are met, then the update performed on the
public state is the same. The private state is a little more tricky, but is guar-
anteed by the dependency invariant J holding for honest parties. This lets us
similarly argue that the private state transcript will have the same effect as the
ideal-world execution.

5 A Case Study: Private Payments

In order to demonstrate the versatility of the Kachina protocol, we take a closer


look at a specific smart contract which is prone to many of the issues Kachina
addresses: The token contract. Token contracts are well understood when no
privacy is desired, with well established standards such as ERC-20 [28] defining
their usage. While this standard has its complexities, the basic idea is simply
to maintain a mapping of “addresses” (hashes of public keys) to balances in
the contracts public state. It is clear that this can be used to construct public
currencies in smart contracts, given some means of distributing tokens. We write
the first provably private token contract to demonstrate the expressive power of
Kachina.
Having a private token contract also means that we do not have assume
the existence of an external private currency, simplifying our model. Without
a currency to back it, smart contracts can hardly exist. First users would lack
an asset to write contracts about. Second, the well established mechanism of
transaction fees and gas costs for denial-of-service mitigation requires a currency
system. Even with these, denial of service is a delicate act, as seen in attacks
on a bad cost model in Ethereum [30]. A private token system allows such a
mechanism to be implemented within our model, as we discuss in Subsection J.5.

5.1 Indirect Construction

Given that Kachina is concerned with privacy, it is a natural question whether


it allows for constructing a private variant of such a token contract. Following
the design of Zerocash [3], it is possible to write a contract that maintains the
necessary Zerocash secrets: coin randomnesses, commitment openings, and se-
cret keys. The private state oracle can then compute the off-chain information

24
required to make a Zerocash transaction: Merkle-paths to your own commit-
ments, the selection of randomness for new coins, and the encryption of the
secret information of these coins. This information can then be handed to the
central, provable core of the contract, which computes a coin’s serial number,
verifies the Merkle-path, and verifies the integrity of the transaction. Finally, the
serial number and new commitment are sent to the public state oracle, which
ensures the former is new, and adds the latter to the current tree.
A reasonable objection to this design may be that the contract itself is no
longer self-evidently correct – indeed specifying what this Zerocash contract
does, and proving that it achieves this is a separate issue. This is something
that applies in many cases – few problems fall neatly into the state separation
model of Kachina. We can see the Kachina contract here as a middle ground
in the UC emulation proof, and define ideal transition and leakage function for a
∆,Λ
private payments system. We can then show that Fsc parameterised with these
∆,Λ
is UC-emulated by Fsc parameterised with the Zerocash contract. Finally, the
actual realisation is achieved by applying the Kachina protocol itself to this
contract – by the transitivity of UC-emulation.
This has the advantage of having a standardised format and interface for pri-
vacy preserving smart contracts, while acknowledging that often privacy is non-
trivial, and requires substantial additional cryptographic work. Private payments
systems are precisely such a scenario, where fortunately the work has already
been done by Zerocash – which we can precisely capture in our model.

5.2 Simplified Construction of Private Payments


For simplicity, in particular on the external interface, we make use only of single
denomination coins, although we note that the same technique – with some
caveats about leakage – applies for the full Zerocash protocol.

Ideal Private Payments We present first the formal specification of the ideal
private payments smart contract. This consists of the corresponding transition
and leakage functions, ∆pp , and Λpp , and supports the following operations: a)
init, giving a party a unique public key, b) (send, pk), sending one of the parties
own coins to the public key pk, c) mint, creating a new coin for the calling party,
and d) balance, returning the calling party’s balance.

Transition Function ∆pp (sketch)

The state transition function for a private payments system. Parties have asso-
ciated public keys, and balances. The payments system allows for parties with-
out a public key to generate one, and for parties to transfer and mint single-
denomination coins, as well as query their own balance.

When receiving an input (σ, p, init, ·, pk):

25
Assert that p’s public key is not set, and ensure the uniqueness of the adver-
sarial input pk (e.g. by incrementing it until it is an unused public key). Record
pk as p’s public key, and return it.
When receiving an input (σ, p, (send, pk) , ·, a):
If p is honest, spend from their associated public key. If not, the adversarial
input is the public key to spend from, asserting it is not associated with any
honest party. Assert the spending public key’s balance is positive, and decrease it
by 1. Increase the receiving public key pk’s balance by 1.
When receiving an input (σ, p, mint, pk, ·):
Increase pk’s balance by 1.
When receiving an input (σ, p, balance, B, ·):
Return the balance B.

Leakage Function Λpp (sketch)

Each operation on ∆pp has minimal leakage, revealing only which operation was
performed, and in the case of a transfer, the time and the recipient – if and only
if the recipient is corrupted.

When receiving an input (t, U, T, σ, p, w):


Reject initialisation transaction if σ is already initialised, or a transaction in
U is an initialising transaction. Reject spending transactions if the coins held in
σ, minus the coins spend in each transaction in U is not greater than zero.
Leak the type of transaction (init, send, mint, or balance). If the transaction
is send, leak the time t, and, if the receiving public key is adversarial, the recipient.
There are no dependencies. In the case of minting, provide the calling party’s
public key as a context, in the case of balance queries, combine the available
balance and provide this as a context.

The Zerocash Kachina Contract The corresponding contract of Zerocash,


which is both in the Kachina class of contracts, and realises the private pay-
ments contract, is presented below, along with a proof of it belonging to the
Kachina class – mainly consisting of proving the lack of dependencies to be
permissible.

Transition Function Γzc (sketch)

The state transition function for a Zerocash-based token contract.

When receiving an input init:


Instruct the private state oracle to sample new Zerocash secret keys, and
record them in the private state. Return the corresponding public keys.
When receiving an input (send, (pkz , pke )):
Instruct the private state oracle to process new messages in the public state
context for both the confirmed and project state. Have the oracle select a coin
held in both states to spend, and return all corresponding secrets, as well as a

26
Merkle tree root it is contained in, and a path to it. Assert the validity of the
Merkle path, and the correct computation of the coin. Compute it’s serial number,
and instruct the public state oracle to mark this serial number as spent (asserting
its uniqueness), and assert that the provided Merkle tree root exists. Finally,
the private state oracle computes a coin commitment owned by pkz , with the
commitment secrets encrypted with pke . The public state oracle inserts this new
commitment to the set of commitments, and appends the message to the list of
messages, updating the set of past Merkle tree roots.
When receiving an input mint:
Instruct the private state oracle to assert the existence of secret keys. It must
then sample a new coin commitment owned by the recorded private key, and
record the commitment and associated secrets as a held coin. The commitment
is passed to the public state oracle, which is instructed to record it in the set of
commitments, and update the list of past Merkle roots.
When receiving an input balance:
Instruct the private state oracle to process new messages in the public state
context for both the confirmed and projected state. The oracle then returns the
size of the intersection of the sets of held coins in the confirmed and projected
private states. This is returned by this query.

function depzc (X, T , z)


return 
function desczc (t, ·, ·, ·, w, ·)
if w = init then return init
else if ∃pk : w = (send, pk) then return (send, t, pk)
else if w = mint then return mint
else if w = balance then return balance
else return ⊥

Lemma 1. Γzc , depzc , desczc define (∆zc , Λzc ) ∈ CKachina .

Proof (sketch). desczc is a pure function, and Γzc is a function with oracle access
to public and private state variables. More tricky is showing that depzc satisfies
its requirements. Transcripts generated by run-Γ fall into three categories: They
set a private key (initialisation), they insert a coin (minting), or they remove a
coin, and insert some number of coins (sending).
Consider first a new initialisation transaction. It does not affect the behaviour
of unconfirmed minting and sending transactions, as these do not use the current
private state’s secret key. Further, it cannot co-exist with another unconfirmed
initialisation transaction, as this would initialise the private keys, ensuring an
abort, which violates the preconditions of dependencies.
If the new transaction is a minting or balance transaction, this happily func-
tions independently of other transactions, not having any requirements on the
current private state. Likewise for sending transactions, the state transcript itself
only depends on ρo and ρπ , not the dynamic ρ. Specifically, the only thing vary-
ing there is which coins get added and removed from ρ.C, ~ but this information
is not directly used – its only purpose is to reduce the necessary re-computation
the next time around. u
t

27
UC Emulation
∆ ,Λpp ∆zc ,Λzc
Theorem 2. Fsc pp is UC-emulated by Fsc in presence of GsimpleLedger .
This proof can also be carried out via invariants. Here the invariant tracking
is simple: The real and ideal world have the same coins owned by the same
users at any time. Our simulator, described in Subsection C.3, has a lot of book-
keeping to do, mostly to conjure up fake commitments and encryptions for the
real-world adversary, and replicating them in the real world. We provide a full
proof sketch in Appendix E.
∆ ,Λ
Corollary 1. Fsc pp pp is UC-emulated by Kachina, parameterised by Γzc , depzc ,
L
and desczc , in the Fnizk -hybrid world, in the presence of GsimpleLedger .

6 Conclusion

We have shown in this paper how to build a large class of smart contracts with
only zero-knowledge and distributed ledgers, and outline how this can be used
and extended upon. To do so we have modelled formally what smart contracts
with privacy are, represented as a state transition function that is fed inputs
from a ledger, and a leakage function that decides what parts of the input are
visible on this ledger. We have then defined which class of such contracts we will
consider in this paper, and presented a protocol, Kachina, which utilises non-
interactive zero-knowledge proofs and state oracles to achieve the desired smart
contract behaviour, while leaking only part of the computation performed.
While the designs are largely theoretical and detached from any actual imple-
mentation, we stress that they were designed with real-life constraints in mind:
The use of state oracles allows moving most computationally hard, or storage
intensive operations outside of the NIZK itself, reducing their cost. While the
NIZK must still be universal, zero-knowledge constructions with universal refer-
ence strings exist [24], and are practical to use in this setting, although they are
not directly provable in the UC model.
The concrete semantics of programming a smart contract, as well as the
corresponding oracles, have been deliberately left unspecified, as many candi-
dates are possible, and a well suited language may be domain specific. That
said, most existing (public) smart contracts are small and simple in size, and
would translate and run well even within a zero knowledge proof, if compiled
into appropriate constraints.
In ending this paper, we would like to make clear that this problem space is
by no means solved. We have shown how to realise a specific class of privacy-
preserving smart contracts, however privacy is not such a simple issue to be
addressed by a single paper. In Appendix I, we sketch the relation of trust models
with privacy, and we believe this taxonomy of trust, and how each level can be
addressed, formalised, and brought into a unified model, is a crucial long-term
research question for providing meaningful privacy to users of smart contract
systems.

28
References
1. Christian Badertscher, Peter Gazi, Aggelos Kiayias, Alexander Russell, and Vassilis
Zikas. Ouroboros genesis: Composable proof-of-stake blockchains with dynamic
availability. In David Lie, Mohammad Mannan, Michael Backes, and XiaoFeng
Wang, editors, ACM CCS 2018, pages 913–930. ACM Press, October 2018.
2. Christian Badertscher, Ueli Maurer, Daniel Tschudi, and Vassilis Zikas. Bitcoin
as a transaction ledger: A composable treatment. In Jonathan Katz and Hovav
Shacham, editors, CRYPTO 2017, Part I, volume 10401 of LNCS, pages 324–356.
Springer, Heidelberg, August 2017.
3. Eli Ben-Sasson, Alessandro Chiesa, Christina Garman, Matthew Green, Ian Miers,
Eran Tromer, and Madars Virza. Zerocash: Decentralized anonymous payments
from bitcoin. In 2014 IEEE Symposium on Security and Privacy, pages 459–474.
IEEE Computer Society Press, May 2014.
4. Sean Bowe, Alessandro Chiesa, Matthew Green, Ian Miers, Pratyush Mishra, and
Howard Wu. Zexe: Enabling decentralized private computation. IACR Cryptology
ePrint Archive, 2018:962, 2018.
5. Jo Van Bulck, Marina Minkin, Ofir Weisse, Daniel Genkin, Baris Kasikci, Frank
Piessens, Mark Silberstein, Thomas F. Wenisch, Yuval Yarom, and Raoul Strackx.
Foreshadow: Extracting the keys to the intel SGX kingdom with transient out-of-
order execution. In William Enck and Adrienne Porter Felt, editors, 27th USENIX
Security Symposium, USENIX Security 2018, Baltimore, MD, USA, August 15-17,
2018., pages 991–1008. USENIX Association, 2018.
6. Benedikt Bünz, Shashank Agrawal, Mahdi Zamani, and Dan Boneh. Zether: To-
wards privacy in a smart contract world. Cryptology ePrint Archive, Report
2019/191, 2019. https://eprint.iacr.org/2019/191.
7. Jan Camenisch, Robert R. Enderlein, Stephan Krenn, Ralf Küsters, and Daniel
Rausch. Universal composition with responsive environments. In Jung Hee Cheon
and Tsuyoshi Takagi, editors, ASIACRYPT 2016, Part II, volume 10032 of LNCS,
pages 807–840. Springer, Heidelberg, December 2016.
8. Ran Canetti. Universally composable security: A new paradigm for cryptographic
protocols. In 42nd FOCS, pages 136–145. IEEE Computer Society Press, October
2001.
9. Ran Canetti, Yevgeniy Dodis, Rafael Pass, and Shabsi Walfish. Universally com-
posable security with global setup. In Salil P. Vadhan, editor, TCC 2007, volume
4392 of LNCS, pages 61–85. Springer, Heidelberg, February 2007.
10. Ran Canetti, Yehuda Lindell, Rafail Ostrovsky, and Amit Sahai. Universally com-
posable two-party and multi-party secure computation. In 34th ACM STOC, 2002.
11. Manuel Chakravarty, Roman Kireev, Kenneth MacKenzie, Vanessa McHale, Jann
Müller, Alexander Nemish, Chad Nester, Michael Peyton Jones, Simon Thomp-
sona, Rebecca Valentine, and Philip Wadler. Functional blockchain contracts.
https://iohk.io/research/papers/#functional-blockchain-contracts, 2019.
12. Stefan Dziembowski, Lisa Eckey, Sebastian Faust, and Daniel Malinowski. Perun:
Virtual payment hubs over cryptocurrencies. In 2019 IEEE Symposium on Security
and Privacy, 2019.
13. Stefan Dziembowski, Sebastian Faust, and Kristina Hostáková. General state chan-
nel networks. In David Lie, Mohammad Mannan, Michael Backes, and XiaoFeng
Wang, editors, ACM CCS 2018, pages 949–966. ACM Press, October 2018.
14. The Enigma Project Team. What is Enigma? https://enigma.co/discovery-
documentation/, 2019.

29
15. Etherscan. Ethereum sync (default) chart. https://etherscan.io/chartsync/
chaindefault, 2019.
16. Oded Goldreich, Silvio Micali, and Avi Wigderson. How to play any mental game
or A completeness theorem for protocols with honest majority. In Alfred Aho,
editor, 19th ACM STOC, pages 218–229. ACM Press, May 1987.
17. Shafi Goldwasser, Silvio Micali, and Charles Rackoff. The knowledge complexity of
interactive proof-systems (extended abstract). In 17th ACM STOC, pages 291–304.
ACM Press, May 1985.
18. Harry A. Kalodner, Miles Carlsten, Paul Ellenbogen, Joseph Bonneau, and Arvind
Narayanan. An empirical study of namecoin and lessons for decentralized names-
pace design. In 14th Annual Workshop on the Economics of Information Security,
WEIS 2015, Delft, The Netherlands, 22-23 June, 2015, 2015.
19. Harry A. Kalodner, Steven Goldfeder, Xiaoqi Chen, S. Matthew Weinberg, and Ed-
ward W. Felten. Arbitrum: Scalable, private smart contracts. In William Enck and
Adrienne Porter Felt, editors, USENIX Security 2018, pages 1353–1370. USENIX
Association, August 2018.
20. Thomas Kerber, Markulf Kohlweiss, Aggelos Kiayias, and Vassilis Zikas.
Ouroboros crypsinous: Privacy-preserving proof-of-stake. In 2019 IEEE Sympo-
sium on Security and Privacy, 2019.
21. Aggelos Kiayias, Hong-Sheng Zhou, and Vassilis Zikas. Fair and robust multi-party
computation using a global transaction ledger. In Marc Fischlin and Jean-Sébastien
Coron, editors, EUROCRYPT 2016, Part II, volume 9666 of LNCS, pages 705–734.
Springer, Heidelberg, May 2016.
22. Ahmed E. Kosba, Andrew Miller, Elaine Shi, Zikai Wen, and Charalampos Pa-
pamanthou. Hawk: The blockchain model of cryptography and privacy-preserving
smart contracts. In 2016 IEEE Symposium on Security and Privacy, pages 839–858.
IEEE Computer Society Press, May 2016.
23. Kevin Liao, Matthew A. Hammer, and Andrew Miller. Ilc: A calculus for compos-
able, computational cryptography. Cryptology ePrint Archive, Report 2019/402,
2019. https://eprint.iacr.org/2019/402.
24. Mary Maller, Sean Bowe, Markulf Kohlweiss, and Sarah Meiklejohn. Sonic: Zero-
knowledge snarks from linear-size universal and updateable structured reference
strings. Cryptology ePrint Archive, Report 2019/099, 2019. https://eprint.
iacr.org/2019/099.
25. Satoshi Nakamoto. Bitcoin: A peer-to-peer electronic cash system. 2008.
26. Fred B. Schneider. Implementing fault-tolerant services using the state machine
approach: A tutorial. ACM Comput. Surv., 22(4):299–319, 1990.
27. Nick Szabo. Formalizing and securing relationships on public networks. First
Monday, 2(9), 1997.
28. Fabian Vogelsteller and Vitalik Buterin. ERC-20 token standard. https://github.
com/ethereum/EIPs/blob/master/EIPS/eip-20.md, 2015.
29. Jonathan Warren. Bitmessage: A peer-to-peer message authentication and delivery
system. white paper (27 November 2012), https://bitmessage. org/bitmessage. pdf,
2012.
30. Jeffrey Wilcke. The Ethereum network is currently undergoing a DoS at-
tack. https://blog.ethereum.org/2016/09/22/ethereum-network-currently-
undergoing-dos-attack/, September 2016.
31. Gavin Wood. Ethereum: A secure decentralised generalised transaction ledger.
2014.
32. Guy Zyskind, Oz Nathan, and Alex Pentland. Enigma: Decentralized Computation
Platform with Guaranteed Privacy. arXiv e-prints, June 2015.

30
A UC Conventions

This paper is modelled and proven in the Universal Composability Framework


[8], with global functionalities [9]. Although we assume a basic familiarity with
these concepts from the reader, the style of writing UC protocols and functional-
ities may differ greatly from author to author. As a result potentially important
corner cases may be overlooked, as the exact behaviour of a given functionality
is sometimes unclear. We adopt a more explicit style, while at the same time
attempting to avoid writing unnecessary information in the definition of the
functionalities. While the proofs, protocols and functionalities can be read and
understood without explicit knowledge of the notation described in this section,
we define what behaviour our notation leaves implicit in this section.
In this section we describe the implicit behaviour of the functionalities and
protocols presented in this paper, as well as touching on miscellaneous conven-
tions adopted to increase the formal clarity of the model. Further, we introduce
some notations used throughout the paper that simplify our code but are unre-
lated to UC.

Flow of execution. Session identifiers are formally used in UC to shield a protocol


from external calls, except when allowed by the control function. While they are
effectively a technical detail of the description in UC, they are often replicated
in the description of functionalities and protocols. We leave all session identifiers
implicit instead. In a similar vein, it is often a convention to replicate (part of)
the input to a functionality when returning the result, to ensure that it is clear
which query is being answered. We omit this as well, in favour of simply stating
the actual value returned. Both of these are how a protocol would be written
in a channel-based communications model, such as that of [23], rather than the
tape-based model of UC itself.
When a functionality is processing something, it is always processing on
behalf of some party, which may be the adversary itself, or may be corrupted.
Likewise when a protocol is processing something, it is processing this on behalf
of its owning party. When a functionality or protocol hands off execution to
another entity, by making a query to another functionality, or the adversary,
execution for this party is suspended, and resumes only when the query returns.
Attempts by the environment to make queries to a suspended protocol will be
ignored. Likewise, if the environment attempts to query a functionality with a
party which is currently suspended, the query will also be ignored. Crucially,
the environment may still query a functionality with another party while one is
suspended, ensuring that parties may still act concurrently. We observe that this
behaves equally in protocols and functionalities, as the functionality is suspended
in the same situation is the corresponding party’s protocol is suspended. Finally,
we assume that queries will eventually return – this is equivalent to queries which
do not return, as we allow the environment and adversary to hold off indefinitely
until returning. While this is possible, in practice, due to the implicit suspension
mechanism described above, this means disabling a party permanently.

31
This above mechanism is not a great deviation from UC – it can easily be
implemented by having a functionality or protocol record locally the suspension,
and reject new queries from the suspended party until it receives an input of
a specified form. We simply omit this mechanism when writing our protocols.
Something similar is in fact necessary for our security, as parties could otherwise
easily shoot themselves in the foot by concurrently creating conflicting transac-
tions. Responsive environments [7] are a strictly stronger form of this idea.
We assume the existence of a set of all parties P, of which there is a subset of
honest parties H ⊆ P. We assume H 6= ∅. Correspondingly, the set of corrupted
parties is P \H. In this paper, static corruption is assumed, and all functionalities
are assumed to have knowledge of these sets.
As a slight note, we use a somewhat unconventional model of having multiple
functionalities interacting with each other in the ideal world. This is largely to
avoid monolithic functionality design, using composition as a software design
primitive, rather than a security one.

Notation. In terms of notation, we will explicitly declare and initialize all state
variables of functionalities and protocols, to make formal statements about them
more precise. For the same reason, the behaviour of functionalities and proto-
cols is described via detailed pseudocode, instead of text. Most of the notation
is self-explanatory, however adversarial queries are not. As the adversary may
respond arbitrarily to queries, we include with each query a well-formedness
condition, and a fallback distribution. In particular, we write query A with x
and receive the reply y, satisfying P , else sampling from D to mean the
following: Send x to A, then wait for the response y. If P (y) does not hold,
instead randomly sample y from D. This allows us to ensure responses are well-
formed, while avoiding the common technique of aborting in the ideal world on
receiving unexpected input, something we try to avoid, as it effectively permits
denial-of-service in the “ideal” world. Finally, we use the period (“.”) as a mem-
bership access operator, to talk about variables of simulated functionalities, or
in the proof, to talk about state variables of various functionalities and protocol
instances. For instance, we write F.X to mean the state variable X within the
(possibly simulated) functionality F.

Functional Programming Constructs. Besides understanding the message pass-


ing mechanics of UC, we assume only the basic programming knowledge needed
to read pseudo-code. We sometimes use functional programming expressions,
including the following for precision:
– Lambda expressions: (λx : 2x)(2) = 4
– List and tuple literals: [1, 2], and (1, 2).
– The higher-order function map: map(λx : 2x, [1, 2]) = [2, 4]
– The higher-order function filter: filter(λx : x ≡ 0 mod 2, [1, 2]) = [2]
– The tuple projection function proji : proj1 ((a, b)) = a

We interpret maps as functions from keys to values. The symbols ⊥ and


∅ are overloaded, with the former representing both “false”, and “error/abort”,

32
while the latter represents the empty set, empty map, and in the case of contract
states, the initial state (which the contract itself may ascribe a different format
to). Further, for a map M , we will write k ∈ M to mean that the map contains
the key k. A key is not in the map iff M (k) := ⊥. For lists, we use  to denote
the empty list, and k to denote list concatenation. Single non-list items can be
interpreted as a singleton list.
We will use the following functions throughout the paper. prefix(L, x) returns
the longest prefix of L containing x, or L itself, if not such prefix exists. idx(L, x)
returns the index of the first occurrence of x in L, or ⊥ if x ∈ / L.
function prefix(L, x)
let L0 ← 
for y ∈ L do
L0 ← L0 k y
if y = x then break
return L0
function idx(L, x)
let i ← 0
for y ∈ L do
if y = x then return i
let i ← i + 1
return ⊥
Finally, we write a ≺ b for the list prefix operation, where we assume reflex-
ivity.

B Ledger Functionalities
As smart contracts utilize an inderection layer of an underlying ledger, for com-
pleteness we will define the behaviour of this underlying ledger. The key char-
acteristics of the ledgers used here are that they maintain a sequence of trans-
actions, which any user may submit new transactions to, which may then even-
tually appear in this sequence. The sequence itself is public, and can be read by
anyone.
We note in particular that for the purposes of this paper, many common
features of ledgers are not required – in particular liveness is optional, although
the ideal-world guarantees for a ledger without liveness are naturally lessened.
Further, we do not specify a validation predicate, instead performing the valida-
tion in our definition of smart contracts. This is solely to have a clean separation
between the consensus system and the semantics of transactions – to prevent
denial-of-service attacks in a real system, this line would need to be blurred, and
transaction validation partially done in the consensus algorithm.
One feature typical ledger functionalities do not have, which we do explicitly
use here, is that of transactional privacy. Typically ledgers leak which party
created a new transaction, something we wish to avoid to strengthen the privacy
of our protocols. It is worth noting that this leakage is entirely network based,
and using a sender-anonymous network is sufficient to adapt “leaky” ledgers to
this more private variant.

33
Finally, readers may be surprised that the “private ledger” of [20] is not used.
This is largely for the same reason that validation predicates are avoided – the
separation of the ledger and transaction semantics is not possible in this private
ledger. While it would be possible to encode ideal smart contracts as specific
ledger blinding functions, this does not accurately model what we intend to
capture, and results in a large, monolithic, and hard-to-understand functionality
– decidedly not ideal.

B.1 The Perfect Ledger

The perfect ledger is a Platonic ideal form of a distributed ledger – it allows any
party to instantly append to its record, and allows any party to read the current
sequence of recorded transactions. This ledger is very similar to that used in [21],
however it is not realised by existing distributed ledger protocols – not least as
there is by necessity some network delay.

Functionality GperfectLedger

The perfect ledger is strictly more powerful than actual ledger implementations.

State variables and initialisation values:

Variable Description
Σ :=  Authoritative ledger state

When receiving a message (submit, τ ) from a party p:


let Σ ← Σ k τ
When receiving a message read from a party p:
return Σ

B.2 The Simplified Practical Ledger

The simplified ledger captures the essence of the traditional persistence property
of ledgers, although it does not capture liveness. Any user may post transactions,
which are deemed unconfirmed. The adversary may decide when and which
unconfirmed transactions to move to an append-only ledger, and may decide
how long a prefix of this ledger honest parties see – provided it does not remove
anything previously revealed to them.
While the liveness property is not captured by this ledger, due to the large
amount of adversarial control, it is straightforward to see – although we will
not demonstrate it here – that more complex ledgers, such as those defined in
[2,1], UC-emulate GsimpleLedger . In particular, this means that if replaced in the
ideal world with such a ledger, which does have the liveness property, we also in
practice have liveness for our protocol. We discuss the issue of liveness more in
Appendix F.

34
Functionality GsimpleLedger

The simplified interface to Gledger is strictly less powerful than actual ledger im-
plementations, allowing reasoning about a less complex ledger functionality.

State variables and initialisation values:

Variable Description
Σ :=  Authoritative ledger state
M := λp. Mapping of parties to ledger states

When receiving a message (submit, τ ) from a party p:


// The adversary is not required to ever put
// transactions on the ledger.
// Where it doesn’t, the execution is unlikely
// to be interesting, however.
query A with (transaction, τ )
When receiving a message read from a party p:
if p = A then return Σ
else return M (p)
When receiving a message (extend, Σ 0 ) from A:
let Σ ← Σ k Σ 0
When receiving a message (advance, p, Σ 0 ) from A:
if M (p) ≺ Σ 0 ≺ Σ then let M (p) ← Σ 0 .

C Fully Specified Functionalities and Protocols


C.1 Ideal World
∆,Λ
Functionality Fsc

The smart contract functionality Fsc∆,Λ allows parties to query a deterministic


state machine determined by ∆ and Λ in a ledger-specified order. The exact
semantics of the call are subject to adversarial influence, who is provided some
leakage, as defined in Λ.

State variables and initialisation values:

Variable Description
T := ∅ Mapping from transactions to their executing components.
Up :=  Sequence of unconfirmed transactions, for all parties p

When receiving a message (post-query, w) from an honest party p:


let Σp ← updateState(p)
let (desc, lkg, D, z) ← Λ(|Σp |, Up , filter(λ(τ, ·) : τ ∈ Up , T ), execState(Σp ), p, w)
if desc = ⊥ then

35
return rejected
send (leak, desc) to p and receive the reply b
if b then
query A with (transaction, lkg, D) and receive the reply (τ, a),
satisfying T (τ ) = ⊥ ∧ τ 6= ⊥, else sampling from ({0, 1}κ , ⊥)
let T (τ ) ← (p, w, z, a, D); Up ← Up k τ
send (submit, τ ) to Gledger on behalf of p
return (posted, τ )
else
return rejected
When receiving a message (check-query, τ ) from an honest party p:
let Σp ← updateState(p)
if τ ∈ Σp then
if T (τ ) = (p, . . .) then return execResult(prefix(Σp , τ ))
else return ⊥
else return not-found

Helper procedures:
procedure updateState(p)
send read to Gledger through p and receive the reply Σp
let C ← execConfirmed(Σp )
let Up0 ← Up
repeat
let Up ← Up0
for τ ∈ Up do
let (. . . , D) ← T (τ )
if D * (C ∪ Up ) ∨ (D ∩ C) 6v Σp then let Up0 ← Up0 \ {τ }
until Up = Up0
return Σp
procedure execState(Σ) = let (σ, ·, ·) ← exec(Σ) in return σ
procedure execResult(Σ) = let (·, y, ·) ← exec(Σ) in return y
procedure execConfirmed(Σ) = let (·, ·, C) ← exec(Σ) in return C
procedure exec(Σ)
let σ ← ∅; y ← ⊥; C ← ∅
for τ ∈ Σ do
if τ ∈ C then continue
if T (τ ) = ⊥ then
query A with (input, τ ) and receive the reply x = (p, w, z, a, D),
satisfying p ∈ / H, else sampling from {none}
if T (τ ) = ⊥ then
let T (τ ) ← x
y←⊥
if T (τ ) = none then continue
let (p, w, z, a, D) ← T (τ )
if D \ C 6= ∅ ∨ D 6v Σ then continue
let (σ 0 , y) ← ∆(σ, p, w, z, a)

36
if σ 0 6= ⊥ then let σ ← σ 0 ; C ← C ∪ {τ }
return (σ, y, C)

C.2 Kachina
Transition Function ∆Kachina

The Kachina transition function, running an internal transition function Γ with


oracle access to the public contract state, and the private state of the party making
the query. The query has an associated context z, which the private state oracle
may access, and an associated public state transcript Tσ , which must be consistent
with the current public state in order for the query to run successfully.

When receiving an input ((σ, ρ), p, w, (Tσ , z), ·):


if Tσ (σ) = ⊥ then return (⊥, ⊥)
let (σ, ·, ρ[p], ·, y) ← run-Γ(σ, ρ[p], w, z, p ∈ H)
return ((σ, ρ), y)

Helper procedures:
function run-Γ(σ, ρ, w, z, h)
Oσ ← U (σ, ∅); Oρ ← U (ρ, z)
if ¬h then let Oρ ← z
y ← ΓOσ ,Oρ (w)
(σ, Tσ ) ← state(Oσ ); (ρ, Tρ ) ← state(Oρ )
return (σ, Tσ , ρ, Tρ , y)

Leakage Function ΛKachina

The Kachina leakage function reveals the public state transcript generated by
Γ during the projected transition. This projected transition takes the state of the
contract as the party currently sees it, and first replays all currently unconfirmed
transactions from the same party. Both the initial (latest confirmed) contract
state, as well as the projected state, and a randomness stream are considered the
transaction’s context.

When receiving an input (t, U, T, (σ o , ρo ), p, w):


let (σ π , ρπ ) ← (σ o , ρo [p])
for u ∈ U do
let (p0 , w0 , (Tσ , z), ·, ·, D) ← T (u)
if Tσ (σ π ) = ⊥ then
return (⊥, ⊥, ⊥, ⊥, ⊥)
let (σ π , ·, ρπ , T , ·) ← run-Γ(σ π , ρπ , w0 , z, p0 ∈ H)
let X ← X k (u, T , z, D)
let η be a randomness stream.
let z ← (σ o , ρo [p], σ π , ρπ , η)

37
let (σ, Tσ , ρ, Tρ , ·) ← run-Γ(σ π , ρπ , w, z, >)
if σ = ⊥ ∨ ρ = ⊥ then
return (⊥, ⊥, ⊥, ⊥, ⊥)
else
let D ← dep(X, Tρ , z)
return (desc(t, X, Tσ , Tρ , w, z), Tσ , D, (Tσ , z))

Protocol Kachina

The Kachina protocol realises the ideal smart contract functionality when pa-
rameterised by a transition function Γ, a leakage descriptor desc, and a depen-
dency function dep, such that the corresponding (∆, Λ) pair is in CKachina . It
L
operates in the (Fnizk , GsimpleLedger )-hybrid model, where L is defined below.
((Tσ , ·), (w, Tρ )) ∈ L if and only if, where Oσ ← O(Tσ ), and Oρ ← O(Tρ ),
ΓOσ ,Oρ (w) 6= ⊥, and after it is run, consumed(Oσ ) ∧ consumed(Oρ ) holds.

State variables and initialisation values:

Variable Description
T := ∅ Mapping from transactions to their private state transcripts
and contexts.
Y := ∅ Mapping from transactions to their outputs.
U :=  Sequence of unconfirmed transactions.

When receiving a message (post-query, w) from a party p:


let Σ ← updateState()
let (σ o , ρo ) ← execState(Σ)
let σ π ← σ o ; ρπ ← ρo ; X ← 
for u = (Tσ , D, ·) ∈ U do
let (Tρ , z) ← T (u)
let σ π ← Tσ (σ π ); ρπ ← Tρ (ρπ , z)
let X ← X k (u, Tρ , z, D)
let η be a randomness stream.
let z ← (σ o , ρo , σ π , ρπ , η)
let (σ, Tσ , ρ, Tρ , y) ← run-Γ(σ π , ρπ , w, z)
if σ = ⊥ ∨ ρ = ⊥ then
return rejected
let D ← dep(X, Tρ , z)
send (leak, desc(|Σ|, X, Tσ , Tρ , w, z)) to p and receive the reply b
if b then
L
send (prove, (Tσ , D), (w, Tρ )) to Fnizk and receive the reply π
let τ ← (Tσ , D, π)
let T (τ ) ← (Tρ , z); Y (τ ) ← y; U ← U k τ
send (submit, τ ) to GsimpleLedger
return (posted, τ )
else
return rejected

38
When receiving a message (check-query, τ ) from a party p:
let Σ ← updateState()
if τ ∈ Σ then return execResult(prefix(Σ, τ ))
else return not-found

Helper procedures:
procedure updateState(p)
send read to GsimpleLedger and receive the reply Σ
let C ← execConfirmed(Σ)
let U 0 ← U
repeat
let U ← U 0
for τ = (·, D, ·) ∈ U do
if D * (C ∪ U ) ∨ (D ∩ C) 6v Σ then let U 0 ← U 0 \ {τ }
until U = U 0
return Σ
procedure execState(Σ) = let (σ, ·, ·) ← exec(Σ) in return σ
procedure execResult(Σ) = let (·, y, ·) ← exec(Σ) in return y
procedure execConfirmed(Σ) = let (·, ·, C) ← exec(Σ) in return C
procedure exec(Σ)
let σ ← ∅; ρ ← ∅; y ← ⊥; C ← ∅
for τ = (Tσ , D, π) ∈ Σ do
if τ ∈ C then continue
let y ← ⊥
L
send (verify, (Tσ , D), π) to Fnizk and receive the reply b
if ¬b then continue
if D \ C 6= ∅ ∨ D 6v Σ then continue
if Tσ (σ) 6= ⊥ then
let σ ← Tσ (σ); C ← C ∪ {τ }
if T (τ ) 6= ⊥ then
let (T , z) ← T (τ )
let ρ ← T (ρ, z)
let y ← Y (τ )
return ((σ, ρ), y, C)

C.3 Private Payments

Transition Function ∆pp

The state transition function for a private payments system. Parties have asso-
ciated public keys, and balances. The payments system allows for parties with-
out a public key to generate one, and for parties to transfer and mint single-
denomination coins, as well as query their own balance.

State variables and initialisation values:

39
Variable Description
K := ∅ Mapping of parties to public keys
B := λp : 0 Mapping of parties to their spendable coins

When receiving an input (σ, p, init, ·, pk):


if σ.K(p) = ⊥ then
R
− {0, 1}κ
while ∃p0 : pk = σ.K(p0 ) ∨ pk ∈ {∅, ⊥} do let pk ←
let σ.K(p) ← pk
return (σ, pk)
else
return (⊥, ⊥)
When receiving an input (σ, p, (send, pk) , ·, a):
if p ∈
/ H ∧ a 6= ∅ then
let pk0 ← a
assert @p0 ∈ H : pk0 = σ.K(p0 )
else if σ.K(p) 6= ⊥ then let pk0 ← σ.K(p)
else return (⊥, ⊥)
if σ.B(pk0 ) > 0 then
let σ.B(pk0 ) ← σ.B(pk0 ) − 1
let σ.B(pk) ← σ.B(pk) + 1
return (σ, >)
else return (⊥, ⊥)
When receiving an input (σ, p, mint, pk, ·):
let σ.B(pk) ← σ.B(pk) + 1
return (σ, >)
When receiving an input (σ, p, balance, B, ·):
return (σ, B)

Leakage Function Λpp

Each operation on ∆pp has minimal leakage, revealing only which operation was
performed, and in the case of a transfer, the time and the recipient – if and only
if the recipient is corrupted.

When receiving an input (t, U, T, σ, p, w):


let σ π ← σ
let B − ← 0
for u ∈ U do
let (·, w0 , z, a, ·, ·) ← T (u)
if w0 = (send, ·) then let B − ← B − + 1
let (σ π , ·) ← ∆pp (σ π , p, w0 , z, a)
if w = init then
if σ.K(p) = σ π .K(p) = ⊥ then
return (init, init, , ∅)
else return (⊥, ⊥, ⊥, ⊥)

40
else if ∃pk : w = (send, pk) then
R
let c ←− {0, 1}κ
if σ.B(σ.K(p)) − B − > 0 ∧ σ.K(p) = σ π (p) 6= ⊥ then
let lkg ← t
if @p0 ∈ H : pk = σ.K(p0 ) then let lkg ← (t, pk)
return ((send, t, pk) , lkg, , ∅)
else return (⊥, ⊥, ⊥, ⊥)
else if w = mint ∧ σ.K(p) 6= ⊥ then
return (mint, mint, , σ.K(p))
else if w = balance ∧ σ.K(p) 6= ⊥ then
return (balance, balance, , σ.B(σ.K(p)) − B − )
else
return (⊥, ⊥, ⊥, ⊥)

Transition Function Γzc

The state transition function for a Zerocash-based token contract. In green are
parts run in the public state oracle, in red are parts run in the private state oracle.

Public state variables and initialisation values:

Variable Description
cms := ∅ Public coin commitment set
sns := ∅ Public serial number set
~ := 
R Vector of commitment Merkle tree roots
~
M :=  Vector of encrypted messages

Private state variables and initialisation values:

Variable Description
i := 0 Index of M~ processed.
C~ :=  Vector of coins available.
Ke := ⊥ Encryption secret key.
Kz := ⊥ Zero-knowledge secret key.

When receiving an input init:


send init to Oρ and receive the reply pk
return pk
When receiving an input (send, (pkz , pke )):
send (send, pke ) to Oρ and receive the reply (p, r, Kz , p0 , r0 , rt, path, M )
assert path is a valid Merkle tree path with root rt, to the element
commr ((prf pk
Kz (1), p))
let sn ← prf sn
Kz ((p, r))
let cm ← commr0 (pkz , p0 )
send (spend, sn, rt) to Oσ
send (msg, M ) to Oσ

41
send (mint, cm) to Oσ
return >
When receiving an input mint:
send mint to Oρ and receive the reply cm
send (mint, cm) to Oσ
return >
When receiving an input balance:
send balance to Oρ and receive the reply B
return B

When receiving an private oracle query init:


assert ρπ .Ke = ⊥ ∧ ρπ .Kz = ⊥
R
let ρ.Kz ← − {0, 1}κ
let (ρ.Ke , pke ) ← keyGen(1κ )
return (prf pk
skz (1), pke )
When receiving an private oracle query (send, pke ):
let ρo ← update(ρo , σ o )
let ρπ ← update(ρπ , σ π )
let ρ ← update(ρ, σ π )
assert (ρo .C~ ∩ ρπ .C)~ 6= 
o ~ ~
let (p, r) ← (ρ .C ∩ ρπ .C)[0]
let ρ.C~ ← ρ.C ~ \ {(p, r)}
let rt ← merkleroot(σ o .cms)
let path ← merklepath(commr ((prf pk
ρo .Kz (1), p)), rt)
R
let (p0 , r0 ) ←− {0, 1}κ × {0, 1}κ
let M ← enc((r0 , p0 ), pke )
let Kz ← ρo .Kz
return (p, r, ρo .Kz , p0 , r0 , rt, path, M )
When receiving an private oracle query mint:
assert ρo .Ke 6= ⊥ ∧ ρo .Kz 6= ⊥
R
let (p, r) ← − {0, 1}κ × {0, 1}κ
let cm ← commr (prf pk ρo .Kz (1), p)
~ ~
let ρ.C ← ρ.C k (p, r)
return cm
When receiving an private oracle query balance:
let ρo ← update(ρo , σ o )
let ρπ ← update(ρπ , σ π )
return |ρo .C ~ ∩ ρπ .C|
~

When receiving an public oracle query (spend, sn, rt):


assert sn ∈/ σ.sns
assert rt ∈ σ.R~
let σ.sns ← σ.sns ∪ {sn}
When receiving an public oracle query (msg, M ):

42
let σ.M~ ← σ.M~ kM
When receiving an public oracle query (mint, cm):
let σ.cms ← σ.cms ∪ {cm}
~ ← σ.R
let σ.R ~ k merkleroot(σ.cms)

Helper procedures:
function update(ρ, σ)
let N~ ← σ.M ~ [ρ.i:]; ρ.i ← max(ρ.i, |σ.M ~ |)
for M ∈ N ~ do
if ∃r, p : (r, p) = dec(M, ρ.Ke ) then
if commr ((prf pk ρ.Kz (1), p) ∈
/ σ.cms then continue
if prf sn
ρ.Kz (p) ∈ σ.sns then continue

let ρ.C ~ ← ρ.C ~ k (r, p)


return ρ

Simulator Szc

The fully detailed Zerocash simulator.

State variables and initialisation values:

Variable Description
B := ∅ Unspent adversarial coins.
K := ∅ Honest public/private key pairs.
T := ∅ Mapping of transactions to created coin commitments.

∆ ,Λ
When receiving a message (transaction, x, D) from Fsc pp pp :
if x = init then
let Tσ ← 
query A with (transaction, Tσ , D) and receive the reply (τ, ·),
satisfying T (τ ) = ⊥ ∧ τ 6= ⊥, else sampling from ({0, 1}κ , ⊥)
let (Ke , pke ) ← keyGen(1κ )
R
let Kz ← − {0, 1}κ
let pkz ← prf pk
Kz (1)
let K ← K ∪ {((Kz , Ke ), (pkz , pke ))}
let T (τ ) ← ∅
return (τ, (pkz , pke ))
else if x = (send, t, (pkz , pke )) then
R R
− {0, 1}κ ; r ←
let p ← − {0, 1}κ
R κ κ
let sn ←− prf sn
{0,1}κ ({0, 1} × {0, 1} )
let rt ← root(t)
let cm ← commr (pkz , p)
let B ← B ∪ {(pkz , pke , cm)}
let M ← enc((r, p), pke )
let Tσ ← ((spend, sn, rt) , ∅) k ((msg, M ) , ∅) k ((mint, cm) , ∅)

43
query A with (transaction, Tσ , D) and receive the reply (τ, ·),
satisfying T (τ ) = ⊥ ∧ τ 6= ⊥, else sampling from ({0, 1}κ , ⊥)
let T (τ ) ← {cm}
return (τ, ∅)
else if x = (send, t) then
R
− keyGen(1κ )
let (·, pk) ←
let rt ← root(t)
R κ
− comm{0,1}κ (prf pk
let cm ← {0,1}κ (1), {0, 1} )
R κ κ
− prf sn
let sn ← {0,1}κ ({0, 1} × {0, 1} )
R
let M ← − enc(({0, 1}κ , {0, 1}κ ), pk)
let Tσ ← ((spend, sn, rt) , ∅) k ((msg, M ) , ∅) k ((mint, cm) , ∅)
query A with (transaction, Tσ , D) and receive the reply (τ, ·),
satisfying T (τ ) = ⊥ ∧ τ 6= ⊥, else sampling from ({0, 1}κ , ⊥)
let T (τ ) ← {cm}
return (τ, ∅)
else if x = mint then
R κ
let cm ← − comm{0,1}κ (prf pk
{0,1}κ (1), {0, 1} )
let Tσ ← ((mint, cm) , ∅)
query A with (transaction, Tσ , D) and receive the reply (τ, ·),
satisfying T (τ ) = ⊥ ∧ τ 6= ⊥, else sampling from ({0, 1}κ , ⊥)
let T (τ ) ← {cm}
return (τ, ∅)
else if x = balance then
let Tσ ← 
query A with (transaction, Tσ , D) and receive the reply (τ, ·),
satisfying T (τ ) = ⊥ ∧ τ 6= ⊥, else sampling from ({0, 1}κ , ⊥)
return (τ, ∅)
else abort
return (τ, a0 )
∆ ,Λ
When receiving a message (input, τ ) from Fsc pp pp :
send (input, τ ) to A and receive the reply (p, w, (Tσ , Oρ ), ·, D)
if T (τ ) 6= ⊥ then return none
let T (τ ) ← ∅
if w = (send, (pkz , ·)) then
if Tσ = ((spend, sn, rt) , ∅) k ((msg, M ) , ∅) k ((mint, cm0 ) , ∅) then
send (send, pke ) to Oρ and
receive the reply (p, r, Kz , p0 , r0 , rt0 , path, M 0 )
let cm ← commr ((prf pk Kz , p))
let b ← >
send read to Gledger and receive the reply Σ
if @t : 0 ≤ t ≤ |Σ| ∧ rt = root(t) ∧ ∃τ : (T (τ ) = cm ∧ τ ∈ Σ[:t]) then
let b ← ⊥
0 0
if sn 6= prf sn
Kz ((p, r)) ∨ rt 6= rt ∨ M 6= M then let b ← ⊥
if cm0 6= commr0 (pkz , p0 ) then let b ← ⊥
if ¬b then return none

44
// We now know the transaction is valid.
// We must determine if M can be honestly decrypted,
// and which adversarial coin is being spent.
if ∃((·, Ke ), (pkz , pke )) ∈ K then
let d = dec(M, Ke )
if d = (r0 , p0 ) then
let w ← (send, (pkz , pke ))
else
let w ← (send, (simkey, ⊥))
else
let B ← B ∪ {(simkey, ⊥, cm0 )}
let w ← (send, (simkey, ⊥))
if ∃(pk0z , pk0e , cm) ∈ B : pk0z = prf pk
Kz then
let a ← (pk0z , pk0e )
else abort
let T (τ ) ← {cm0 }
let z ← ∅
else return none
else if w = mint ∧ Tσ = ((mint, cm) , ∅) then
let B ← B ∪ {(simkey, ⊥, cm)}
let T (τ ) ← {cm0 }
let z ← (simkey, ⊥); a ← ∅
else return none
return (p, w, z, a, D)

Helper procedures:
procedure root(t)
let cms ← ∅
send read to Gledger and receive the reply Σ
for τ ∈ Σ[:t] do
let cms ← cms ∪ T (τ )
return merkleroot(cms)

D Security Analysis

Proof (of Theorem 1). If an environment can distinguish between the ideal and
real executions in presence of our simulator (see Subsection D.1), then there
must exist some polynomial sequence of interactions permitting it to distinguish
with a non-negligible advantage. Broadly, each of the environment’s actions fall
into one of three categories: a) Honestly interacting with the protocol. b) Hon-
estly interacting with the ledger. c) Commanding the adversary to perform some
action in the real world. We will consider the responses the environment makes
to queries given to the dummy adversary separately, in each case at the point
where the query is made.
We will consider in parallel two random variables of the state of the ideal
world execution, and that of the real world execution at any time. We leave out

45
of our analysis the “stack” of partial executions (as described in Appendix A),
except to show that the flow of each party – i.e. when it is waiting for which
query to be answered – is the same in both worlds. In particular, we note that
the state of the ideal world has the following functionalities’ states as a part of it:
1. the state of the simulator, S, 2. the state of the smart contract functionality,
∆,Λ
Fsc , and finally 4. the state of the ledger GLi . In the real world, for each p ∈ H,
p’s protocol state, which we refer to as φp , is part of the state, along with
L,r
the (shared) NIZK hybrid functionality Fnizk , and the real-world ledger GLr . For
convenience, we will often talk about these states as concrete variables, and not
random variables.
We will prove inductively that any action the environment takes will do two
things: First, it will preserve an invariant I, which holds after the state of both
worlds at any point during the two experiments. Second, if the invariant holds,
the environment gains at most negligible advantage in distinguishing from its
next action. To begin, we will specify the simulator, the invariant I, followed by
a few lemmas helpful in the proof. Finally, we will perform the induction itself.

D.1 The Simulator

The simulator for Kachina has fairly little work to do. It creates simulated
transactions by creating a simulated NIZK proof, and attaching it to the leakage
x. Secondly, when presented with an unknown transaction, and asked for the
corresponding input, it attempts to extract the input from the simulated zero-
knowledge functionality.

Simulator SKachina

The simulator SKachina has two main points of interaction in the ideal world:
First, it gets notified of the leakage of honest submissions, in the form of the new
public state σ 0 , and decides their format on the ledger. Second, it gets queried
when an adversarial transaction is seen on the ledger, and must assign meaning
L
to them. Furthermore, it simulates the non-global functionality Fnizk , which the
adversary may interact with.

State variables and initialisation values:


Variable Description
L L
Fnizk Simulation of Fnizk

When receiving a message (transaction, Tσ , D) from Fsc∆,Λ :


query A with (prove, (Tσ , D)) and receive the reply π,
L L
satisfying π 6= ⊥ ∧ (·, π) ∈ / Fnizk .Π ∧ (x, π) ∈
/ Fnizk .Π, else
sampling from {0, 1}κ , on behalf of Fnizk L
L L
let Fnizk .Π ← Fnizk .Π ∪ {((Tσ , D), π)}
return ((Tσ , D, π), ∅)
When receiving a message (input, (Tσ , D, π)) from Fsc∆,Λ :

46
L
simulate sending (verify, (Tσ , D), π) to Fnizk and receive the reply b
L
if b ∧ ∃w, Tρ : Fnizk .W ((Tσ , D), π) = (w, Tρ ) then
return (A, w, (Tσ , O(Tρ )), ∅, D)
else
return none

L
Forward all queries to Fnizk to the simulated instance. Forward all queries, to
global functionalities directly.

D.2 The Invariant I.

We define I as the conjunction of each of the constraints over the state variables
over the two executions listed below.

(1) The ledgers are indistinguishable:


GLi .Σ = GLr .Σ ∧ ∀p ∈ H : GLi .M (p) = GLr .M (p)
(2) The simulated and real NIZKs consider the same statement/proof pairs valid
and invalid:
L L,r L L,r
S.Fnizk .Π = Fnizk .Π ∧ S.Fnizk .Π = Fnizk .Π
(3) Real world witnesses have a corresponding ideal world witness:
L,r L
∀Tσ , D, π : ∃Tρ , w : Fnizk .W (((Tσ , D), π)) = (Tρ , w) =⇒ S.Fnizk .W (((Tσ ,
o o π π
D), π)) = (Tρ , w) ∨ [∃p ∈ H, z = (σ , ρ , σ , ρ , η) : φp .T ((Tσ , D, π)) =
∆,Λ
(Tρ , z) ∧ Fsc .T ((Tσ , D, π)) = (p, w, (Tσ , z), ∅, D) ∧ run-Γ(σ π , ρπ , w, z, >) =
(·, Tσ , ·, Tρ , φp .Y ((Tσ , D, π)))]
(4) Recorded transactions are proven, and only adversarial witnesses are known
by the simulator:
∆,Λ L,r
∀Tσ , D, π, p : Fsc .T ((Tσ , D, π)) = (p, . . .) =⇒ ((Tσ , D), π) ∈ Fnizk .Π∧(p ∈ /
L
H ⇐⇒ ((Tσ , D), π) ∈ S.Fnizk .W )
(5) Honest parties record transactions correctly:
∆,Λ
∀p ∈ H, τ : τ ∈ φp .T ⇐⇒ τ ∈ φp .Y ⇐⇒ Fsc .T (τ ) = (p, . . .) ∧ τ ∈
φp .U =⇒ τ ∈ φp .T
(6) All recorded transactions respect dependencies and transcripts:
∆,Λ ∆,Λ ∆,Λ
∀τ ∈ Fsc .T : Fsc .T (τ ) = none∨(∃T , D, π : τ = (T , D, π)∧Fsc .T (τ ) =
(·, ·, (T , ·), ∅, D))
(7) Recorded as rejected transactions are disproven:
∆,Λ L,r
∀Tσ , D, π : Fsc .T ((Tσ , D, π)) = none =⇒ ((Tσ , D), π) ∈ Fnizk .Π
(8) The dependency invariant J holds for all honest unconfirmed transactions:
∀p ∈ H, let Σ be the longest prefix of GLr .M (p) such that Σ∩φp .U = ∅; define
X(u = (·, D, ·)) := let (T , z) = φp .T (u) in (u, T , z, D), and ((·, ρ), ·, C) :=
φp .exec(Σ). Then J(map(X, φp .U ), ρ)∧sat(map(X, φp .U ), φp .U )∧∀(·, D, ·) ∈
φp .U : D \ C \ φp .U = ∅ holds.
(9) Transactions owned by an honest party, and not in their view of the ledger,
are considered unconfirmed, or can never be accepted: Let Σ be the longest
prefix of GLr .M (p) such that ∀τ ∈ Σ : τ ∈ Fsc ∆,Λ
.T .
∀p ∈ H, τ ∈ / Σ : Fsc .T (τ ) = (p, . . .) =⇒ τ ∈ φp .U ∨ (@Σ 0  GLr .M (p) : τ ∈
∆,Λ

Fsc∆,Λ
.execConfirmed(Σ 0 k τ )

47
(10) All results and state updates are consistent with the input and transcripts:
∆,Λ
∀p ∈ H, Tσ , τ = (Tσ , ·, ·), w, z : Fsc .T (τ ) = (p, w, z, ∅, ·) =⇒ [∃Tρ :
φp .T (τ ) = (Tρ , z) ∧ φp .Y (τ ) = ΓO(Tσ ),O(Tρ ) (w) ∧ [∀σ, ρ : Tσ (σ) 6= ⊥ ∧
Tρ (ρ, z) 6= ⊥ =⇒ (Tσ (σ), ·, Tρ (ρ, z), ·, φp .Y (τ )) = run-Γ(σ, ρ, w, z, >)]]
(11) Execution results should be equivalent for prefixes and extensions of the
ledger state containing no new adversarial transactions:
∀Σ, p ∈ H : ((Σ ≺ GLr .Σ ∨ GLr .Σ ≺ Σ) ∧ ∀τ ∈ Σ : Fsc ∆,Λ
.T (τ ) 6= ⊥) =⇒
let ((σ , ρ ), y , C ) ← Fsc .exec(Σ); ((σ , ρ ), y , C ) ← φp .exec(Σ) in σ i =
i i i i ∆,Λ r r r r

ρi ∧ρi [p] = ρr ∧C i = C r ∧ if Fsc ∆,Λ


.T (Σ[−1]) = (p, . . .) then y r = y i else y r =

(12) Recorded transactions which are canonically preceeded by a (yet) unrecorded
transaction, are honest, and considered unconfirmed by their owner:
∀τ ∈ (Fsc ∆,Λ
.T ∩ GLr .Σ), τ 0 ∈ (GLr .Σ \ Fsc ∆,Λ
.T ), p ∈ H : idx(GLr .Σ, τ 0 ) <
idx(GL .Σ, τ ) ∧ Fsc .T (τ ) = (p, . . .) =⇒ τ ∈ φp .U ∨ (@Σ 0  GLr .Σ : τ ∈
r ∆,Λ
∆,Λ
Fsc .execConfirmed(Σ 0 k τ ))
(13) The ledger is ahead of any party’s ledger:
∀p ∈ H : GLr .M (p) ≺ GLr .Σ
(14) The same transactions are unconfirmed in both worlds:
∆,Λ
∀p ∈ H : φp .U = Fsc .Up
(15) NIZK proofs have witnesses:
L,r L,r L
∀x, π : (x, π) ∈ Fnizk .Π ⇐⇒ (∃w : Fnizk .W ((x, π)) = w∧S.Fnizk .W ((x, π)) ∈
{w, ⊥} ∧ (x, w) ∈ L)
(16) Recorded transactions are either on the ledger, considered unconfirmed by
an honest party, or can never be satisfied:
∆,Λ ∆,Λ
∀τ ∈ Fsc .T : τ ∈ GL .Σ ∨ (∃p ∈ H : τ ∈ φp .U ∧ Fsc .T (τ ) = (p, . . .)) ∨
0 ∆,Λ 0
(@Σ  GL .Σ : τ ∈ Fsc .execConfirmed(Σ k τ ))

Often many of these parts of the invariant are trivially preserved due to the
state variables constrained in them being left unchanged. Such trivial cases will
be omitted in our analysis.

D.3 Supporting Lemmas

Lemma 2 is the kernel of the proof of Kachina, but its formal statement is not
∆,Λ
particularly intuitive. The purpose is quite simple: Both Fsc and Kachina
have exec functions, which executes an entire ledger state given to it. Lemma 2
is a generalisation of invariant (11), and simply states that this execution will
preserve the invariant, and return the same values in the real and ideal world.

Lemma 2. For any p ∈ H, Σ where Σ ≺ GLr .Σ ∨ GLr .Σ ≺ Σ, and after sending


the message (extend, Σ \ GLr .Σ) to GL , ((σ i , ρi ), y i , C i ) is the result of running
∆,Λ
exec(Σ) in Fsc , and ((σ r , ρr ), y r , C r ) is the result of running exec(Σ) in φp ,
these interactions preserve I, and the returned values are equivalent: σ i = σ r ∧
ρi [p] = ρr . If the last transaction τ in Σ is owned by p (i.e. Fsc ∆,Λ
.T (τ ) =
i r r
(p, . . .)), then y = y , otherwise y = ⊥.

48
Proof. First, we consider the extend call. This will only extend if Σ is longer
than GL .Σ – otherwise it extends with , which is a no-op. This call preserves I,
as demonstrated in Subsection D.4.
We prove by induction over Σ. In the base case, Σ = . The invariant is
trivially preserved, and the returned values are equivalent (when ∅ is interpreted
as public/private state pairs). In the induction step, we proceed by case analysis
for the new transaction τ = (T , D, π):

∆,Λ
Case 1. The τ ∈ Fsc .T , and all processed transactions so far have been also
∆,Λ
been recorded (are in Fsc .T ). If so, then by (11), the return values are equiva-
lent. Further, this iteration does not change the state in the ideal world. By (4)
L,r L,r
and (7), we also know that the transaction is either in Fnizk .Π, or Fnizk .Π. As a
result, no state changes will be made in the real-world execution either, trivially
preserving I.

∆,Λ L,r
Case 2. τ ∈ / Fsc .T , but ((T , D), π) ∈ Fnizk .Π. In this case, the real world will
skip this transaction, and set y to ⊥. In the ideal world, the simulator will ensure
∆,Λ
that Fsc .T (τ ) is set to none, and equally this transaction is skipped, with y
set to ⊥. This affects and preserves the following invariants:

(3) As by (15), τ has no witness.


∆,Λ
(4) As Fsc .T (τ ) = none, not satisfying the precondition.
∆,Λ
(5) As τ was not in Fsc .T in the induction hypothesis, and is not associated
with an honest party.
∆,Λ
(6) By Fsc .T (τ ) being none, satisfying the postcondition.
L,r
(7) Due to ((T , D), π) ∈ Fnizk .Π.
∆,Λ
(9) As Fsc .T (τ ) = none, not satisfying the precondition.
∆,Λ
(10) As τ was not in Fsc .T in the induction hypothesis, it cannot be in any
φp .Y , by (5).
(11) By the output equivalence part of the induction step holding.
(12) By τ being previously unrecorded, further restricting the quantification do-
∆,Λ
main, and Fsc .T (τ ) = none, not satisfying the precondition.
(16) By the newly recorded transaction being in the ledger state, as this has been
extended if necessary.

∆,Λ L,r
Case 3. τ ∈ / Fsc .T , but ((T , D), π) ∈ Fnizk .Π. In this case, by (15) a witness
must be recorded, and by (3) this witness must be accessible to the simulator. As
a result, the simulator will ensure that T (τ ) is set to (A, w, (Tσ , O(Tρ )), ∅, D). As
this is an adversarial transactions, the ρ-value of the adversary is not constrained,
and neither is the output y-value. As a result, to show the execution equivalence
holds, it suffices to show that both worlds will have the same σ-value after
this new transaction is the same in both worlds. In the real world, Tσ (σ) is
applied, or if this is ⊥, the transaction is skipped. In the ideal world, Tσ (σ)
is first tested to be ⊥, and if it is, the transaction is also skipped. Otherwise,
run-Γ(σ, ·, w, O(Tρ ), ⊥) is run. Since Tσ (σ) 6= ⊥, and ((Tσ , D), (Tρ , w)) ∈ L (by
(15)), we know that the public state oracle used in run-Γ can be replaced with

49
O(Tσ ), and that the call ΓO(Tσ ),O(Tρ ) (w) will terminate successfully. As a result,
the value σ returned in the ideal world is the same as Tσ (σ), that is returned in
∆,Λ
the real world. As Fsc .T is set, the following parts of the invariant are affected
and preserved:

(3) By the left hand side of the disjunction already being satisfied.
(4) By the transaction being recorded in the NIZK, and the simulator knowing
its witness.
∆,Λ
(5) As τ was not in Fsc .T in the induction hypothesis, and is not associated
with an honest party.
(6) By the newly recorded transaction satisfying the postcondition.
(7) By the newly recorded transaction not being recorded as rejected.
(9) By the newly recorded transaction not being honestly owned, not satisfying
the precondition.
∆,Λ
(10) As τ was not in Fsc .T in the induction hypothesis, it cannot be in any
φp .Y , by (5).
(11) By the output equivalence part of the induction step holding.
(12) By τ being previously unrecorded, further restricting the quantification do-
∆,Λ
main, and Fsc .T (τ ) = (A, . . .), not satisfying the precondition.
(16) By the newly recorded transaction being in the ledger state, as this has been
extended if necessary.

∆,Λ
Case 4. The transaction has not been previously seen – that is τ ∈ / Fsc .T ,
L,r L,r
and ((T , D), π) ∈/ Fnizk .Π ∪ Fnizk .Π. In this case, both the real and ideal worlds
will attempt the same NIZK verification (simulated in the ideal world). By (2),
they will both query the adversary for a NIZK witness in the same way, handing
off execution. By the induction hypothesis, I holds as the point of execution
transfer, and as the query made is the same in both worlds, the environment
gains no means to distinguish.
As NIZK verification is the first thing done in both worlds, and NIZK verifi-
cation is agnostic as to which party is verifying, this is equivalent to the environ-
ment first manually verifying the same statement/proof pair. As will be shown in
Subsection D.4, this preserves the invariant, and returns the same result in both
worlds. Therefore, Case 4 is equivalent to either Case 2 (if the NIZK verification
failed), or Case 3 (if the NIZK verification succeeded), as if the NIZK verifica-
tion is done externally beforehand, the statement/proof pair must be either in
L,r L,r
Fnizk .Π, or in Fnizk .Π.

∆,Λ
Case 5. τ ∈ Fsc .T , however (11) cannot be applied, as other transactions have
since been added. By (12), we know that τ belongs to an honest party p0 , and
that τ ∈ φp0 .U . We will use (8) to argue that, where (Tρ , z) = φp0 .T (τ ), either
Tρ (ρi [p0 ], z) 6= ⊥, or the transaction is skipped in both worlds.
First, we consider the possibility that τ ∈ / φp0 .U . By (9) we know that τ can-
not ever be confirmed by a suffix of the ledger state referred to in the invariant.
As this is a prefix of GLr .Σ, such that it contains no unrecorded transactions, the
current induction is necessarily a suffix of it. As a result, we know that the ideal

50
world execution will fail. As transactions are rejected in both worlds under the
same conditions – either dependencies are not satisfied, or Tσ (σ) = ⊥, we can
conclude that these transactions are also skipped in the real world, preserving I
as no state variables are changed, and satisfying all conditions by the induction
hypothesis. We will now focus on the case that τ ∈ φp0 .U
Next, we determine that, given τ ∈ φp0 .U , the longest prefix Σ ∗ referred to
in (8) is a prefix of the ledger state Σ we are currently performing induction
over. We know it to be a prefix of GL .M (p0 ), such that this prefix contains none
of the transactions in φp0 .U . As τ ∈ φp0 .U , and is either a prefix or extension of
GLr .Σ, of which GLr .M (p0 ) is itself a prefix by (13), we can conclude that Σ ∗ ≺ Σ.
As, to apply (8), we are only concerned with the parties private state ρ, we
can observe all transactions in Σ \ Σ ∗ are either not owned by p0 , will not be
accepted in any context, or are in φp0 .U . We can ignore the first possibility, as
the real world execution of them will not affect ρ, regardless. The second can
also be ignored, as these will be skipped by the ideal world execution, and by
induction hypothesis, by the real world execution as well. Next, we consider
which of the transaction in Σ \ Σ ∗ owned by p0 have been successfully processed.
exec provides replay protection, ensuring that each unconfirmed transaction has
been processed at most once. By induction hypothesis, the sequence A of such
transactions that are accepted, and therefore confirmed, is the same in both
worlds. By virtue of exec rejecting transactions which would set the state to

⊥, we know that Tmap(φ (ρ∗ [p0 ]) 6= ⊥, where ρ∗ is taken to be the private
p0 .T,A)
state corresponding to the prefix Σ ∗ in the ideal world. As each transaction in
A got confirmed in order, we know that sat(map(X, A), φp0 .U ) holds, where X
is the function defined in (8), as this performs a more relaxed variant of the
confirmation check.
Now that τ is processed, we know by (8) that its dependencies are either in
confirmed, and in order, in Σ ∗ , or in φp0 .U . In either case, τ is skipped in both
worlds if it is a replayed transaction, or if would set Tσ (σ) = ⊥. In the ideal
world, additionally it gets skipped if it would set the contract state – either σ i
or ρi – to ⊥.
As τ ∈ φp0 .U , and is not a replay, B = A k τ is a permutation of a subset

of φp0 .U . As a result, by (8), we know that Tmap(φ (ρ∗ [p0 ]) 6= ⊥. As we’ve
p0 .T,B)
previously established this holds for A, by definition of T ∗ , this implies that
Tρ (ρ[p0 ]i , z) 6= ⊥, where ρ[p0 ] is the same as the ideal world private state for
the induction hypothesis, by repeated application of (10). Likewise, (10) allows
us to conclude that σ i will also be non-⊥, as the update applied to it will be
equivalent to Tσ (σ i ), which by case analysis is not ⊥.
If the transaction is skipped in both worlds, the induction hypothesis still
applies. Otherwise, both Tσ (σ i ) 6= ⊥ and Tρ (ρi [p0 ], z) 6= ⊥. As previously noted
in Subsection 4.1, we can conclude that the updated states in the ideal world
are equal to σ i ← Tσ (σ i ) and ρi [p0 ] ← Tρ (ρi [p0 ], z). Likewise, (10) applies (as by
(5), φp0 .Y (τ ) is set), and we know the ideal-world result y i = φp0 .Y (τ ).
As in the real world σ r ← Tσ (σ r ), their equality is preserved. If p = p0 ,
by (5), φp .T is defined, and as a result, the same update is carried out to ρ

51
in the real world, as to ρi [p] in the ideal world. Further, it will return the
same result y r as the ideal world, as φp .Y (τ ) = y i . If p 6= p0 , the ideal world
update does not affect ρi [p], and the correctness of the returned private state
is guaranteed by the induction hypothesis. y r = ⊥ is returned, which satisfies
the requirements. Finally, in both cases, as the transaction is not skipped, it is
added to C, ensuring the returned C is the same in both worlds. Neither world
makes any state updates, trivially preserving I. u
t
∆,Λ
Lemma 3. If I holds, then for all p ∈ H, running updateState(p) in Fsc , and
running updateState in φp preserves I.
Proof. To begin with, both worlds retrieve the same value Σ / Σp from GL , due
to (1). As seen in Subsection D.4, this preserves I. Next, by Lemma 2, both
worlds receive the same value C, and the execConfirmed call preserves I. The
∆,Λ
worlds now iterate over φp .U and Fsc .Up respectively, which by (14) are equal
in value. The operations performed are almost identical, with the exception of
the real world deconstructing u = (·, D, ·) for each u ∈ U , while the ideal world
∆,Λ ∆,Λ
extracts (. . . , D) = Fsc .T (u) instead. By (6), if u ∈ Fsc .T , the two are
∆,Λ
equivalent, and by (5), as u ∈ φp .U , it is also in both φp .T , and Fsc .T . We
conclude that both worlds perform the same operations. Updated is only φp .U
∆,Λ
and Fsc .Up respectively. The following parts of the invariant are affected and
preserved:

(5) By reducing the scope of φp .U .


(8) This consists of three sub-parts: The satisfaction of J, that of sat, and that
D\C\U = ∅. The first is trivial: J makes a statement about all permutations
of subsets. A smaller initial set merely reduces the scope of the quantifiers.
The second holds due to updateState ensuring that if a transaction is re-
moved from U , any transactions that depend on it are also removed, with
the remaining transactions being in the same order as before. As a result,
a previously satisfied transaction is either removed itself, or still satisfied,
as it does not depend on any removed transactions, and dependencies still
in U being in the same order as before. Finally, D \ C \ U = ∅ is also
preserved due to the recursive removal. Specifically, if D * (C ∪ U ) the cor-
responding transaction is removed. As a result, only transactions satisfying
this condition will remain.
(9) As the removed transactions either fail confirmation directly (it depends
on a transaction rejected in Σp , or a different transaction order than got
enforced), or depends on a transaction which fails. In either case, any state
Σ 0 , of which Σp is a prefix, cannot accept these for the same reasons.
(12) As in (9).
(14) By equal update. u
t

D.4 Proof of Theorem 1


We proceed with the main inductive proof of Theorem 1. We consider the base
case of the system initializations in the real and ideal worlds. The induction

52
hypothesis is that after k < 2κ interactions with any environment, the state of
both worlds satisfy the invariant I, and the environment has not gained a non-
negligible advantage in distinguishing. We will assume, without loss of generality,
the adversary being a dummy adversary. We provide a concrete list of actions
the environment may take before taking the induction step. We note that as at
any point the environment cannot distinguish, we can assume that it takes the
same action in both worlds without loss of generality.

Base Case.

Proof. Most base cases hold either due to equal initialization of variables con-
strained to be equal, or due to initialization leaving forall quantifiers to quantify
over the empty set. The former is the case for: (1), (2), (5), and (14). The latter
is the case for: (3), (4), (6), (7), (9), (10), (12), and (16). The remaining hold
for the following reasons:

(8) At initialisation, the only prefix of GLr .M (p) is . φp .execState() = (∅, ∅).
The base case therefore holds iff J(∅, ∅) holds. This in turn holds iff T∗ (∅) 6=
⊥, or ∅ 6= ⊥.
(11) At initialisation, the only ledger state Σ which satisfies the condition that
∆,Λ
∀τ ∈ Σ : Fsc .T (τ ) 6= ⊥ is . For this, as both world’s are initialised to
equivalent contract states, the outputs of exec will be equal.
(13) By the reflexivity of ≺. u
t

Induction Step.

Proof. We observe that the environment is capable of the following queries:

∆,Λ
– ∀p ∈ H, w:4 Sending (post-query, w) to Fsc or Kachina.
∆,Λ
– ∀p ∈ H, τ : Sending (check-query, τ ) to Fsc or Kachina.
– ∀p ∈ P, τ : Sending (submit, τ ) to GL .
– ∀p ∈ P: Sending read to GL .
– ∀Σ 0 : Sending (extend, Σ 0 ) to GL .
– ∀p, Σ 0 : Sending (advance, p, Σ 0 ) to GL .
L
– ∀p ∈ P \ H: Sending (prove, x, w) to Fnizk .
5 L
– ∀p ∈ P: Sending (verify, x, π) to Fnizk .

We will prove that I is preserved across any of these queries, and that they
reveal the same information in both worlds.
4
We omit without loss of generality the environments ability to make honest queries
with corrupted parties. The environment may simulate running the honest protocol
to replicate these.
5
Technically, as in prove, the environment can only instruct corrupted parties to
verify. As verification for honest parties preserves the invariant as well, and is a
useful lemma, we prove the more general statement.

53
Case (post-query, w). We proceed by sub-case analysis. We identify the fol-
lowing cases: 1. The transaction is rejected by the contract. 2. The transaction
is rejected by the user. 3. The transaction is posted. In all cases, updateState is
first run. By Lemma 3, this preserves the invariant, and also ensures that the
returned value Σp = GL .M (p) is the value returned in both worlds (by (1)). In
the ideal world, Λ is called. The real world largely emulates the same, computing
most of the same values identically. Of note are the values σ o and ρo /ρo [p], which
are computed in both worlds using execState(Σp ). By Lemma 2, this preserves
the invariant, and returns the same values.
The only place where the two worlds diverge in their computation is in han-
dling the unconfirmed transactions – the ideal world executes run-Γ, and updates
σ π , ρπ , and X accordingly, while the real world applies Tσ and Tρ to the states.
Before we go into the main three cases, we will argue that, if the transaction
is not rejected by the contract, then these two approaches will yield the same
result, and that they will reject equally.
To begin with, the ideal world does also apply the public state transcript,
specifically to check that the result is non-⊥. If this is not satisfied, it immediately
results in the new query being rejected. Correspondingly, the real world will
actually apply this transcript, resulting in σ π = ⊥. As a ⊥ state will remain ⊥,
this will further in the execution result in the final public state σ also being ⊥,
and the real world execution rejecting this query.
Further, we observe that in the real world, the final value of ρπ cannot be
⊥ – to begin with, updateState guarantees that Σp ∩ φp .U = ∅. This in turn,
along with (8) ensures that J(X) holds, as well as that sat(X, U ) holds. It follows
T ∗ (ρo ) 6= ⊥, where T ∗ performs the same repeated applications of Tρ (ρ, z) as
the loop in the main protocol, using the same values. Further, by (3) and (4),
we can conclude that the transcripts Tρ , and contexts z are the same in both
worlds. By (10) , we can conclude that the final ρπ values are also the same in
both worlds. Further, as Tρ and z are equal in both worlds, and by (6) D is also
equal, the sequence X is also equal. Subsequently, σ, ρ, and D are computed
equivalently in both worlds.
We now consider the main case analysis: If the contract rejects the transaction
in the ideal world, the returned description is ⊥. This happens if and only if
σ = ⊥∨ρ = ⊥, the same condition as the real world protocol has for rejecting the
transaction before querying the user. If the transaction is rejected, no variables
are modified, preserving I, and the same value is returned in both worlds, giving
the environment no means to distinguish.
If the contract does not automatically reject the query, the leakage descrip-
tor is computed equally in both worlds, and sent to the party to acknowledge.
The party has the opportunity to accept the described leakage, or cancel the
transaction. At the point of handing over execution to the environment, no state
has been modified, trivially preserving I, and as the same leakage descriptor is
given, it has no means to distinguishing.

54
In the case of the environment subsequently cancelling the transaction, both
worlds immediately return with rejected, again trivially preserving I, and
giving no means to distinguish.
Finally, if the environment accepts the leakage, both worlds obtain the trans-
action identifier τ : The simulator ensures that the real-world adversary is queried
for the same NIZK proof as it is in the real-world, and that the transaction for-
mat matches that of real-world transactions. At the time of the proof query, no
state has been modified, trivially preserving I. As the same statement is queried
for, the environment gains no information to distinguish.
∆,Λ
Subsequently, both worlds record the transaction’s information (in Fsc .T
∆,Λ
and φp .T ), and note is as unconfirmed (in Fsc .U and φp .U ). In the real world,
the result is further recorded in φp .Y . The following parts of I are affected and
preserved (including the prove query):

(2) By ((Tσ , D), π) being added to both worlds’ Π equally.


∆,Λ
(3) As φp .T , Fsc .T , and φp .Y are appropriately set to satisfy the RHS of the
disjunction.
L
(4) As for the newly added transaction, p ∈ H, and ((Tσ , D), π) ∈ / S.Fnizk .W (by
the uniqueness of statement/proof pairs).
∆,Λ
(5) As the newly added transaction is added to all of φp .T , φp .U , and Fsc .T ,
where it is associated with p.
(6) As the newly added transaction does consist of transcript, dependencies and
∆,Λ
proof, and the former two are recorded in Fsc .T correctly, and S returns
∅ for a.
(7) As the newly recorded transaction is not recorded as none.
(8) By J being preserved when appending a new transaction, J holds after the
induction step (as ρ remains unaffected). sat holds by induction hypothesis,
and as D v U \ {τ }. For the new transaction, D \ C \ φp .U = ∅ as D ⊆ φp .U ;
for previously transactions this still holds, as φp .U is expanded.
(9) As the newly added transaction is also unconfirmed by the owning party.
(10) By Tσ , Tρ , and y having been extracting from run-Γ, operating in the context
of w, z, and some σ, ρ, with these values being recorded in the correspond-
ing state variables (except σ and ρ). As the transcripts are transcripts of
oracle evaluations against w, and y is the result of Γ operating with these
oracles, executing ΓO(Tσ ),O(Tρ ) (w) has the same effect. Further, as the tran-
scripts accurately reproduce the state change in the original state context,
by definition of transcript execution, and if an applied transcript is not ⊥,
it is indistinguishable from making the original queries to the state oracle,
combined with the sequence of queries made depending only on w and the
state oracle itself, we can conclude that the transcript application is the same
as executing against the state oracles, regardless of which initial state the
transcript could be successfully applied to.
(11) As a new transaction has been recorded, we must now additionally consider
transaction sequences Σ which contain this new transaction at some point.
We cannot directly use Lemma 2, however we can make use of its induction:
If we can show that any Σ ending with the new transaction τ satisfies the

55
execution equivalences, then induction from Lemma 2 can apply on that as a
base case (in particular, the precondition for Case 5 applies for all subsequent
transactions). The execution equivalence holds for this new base case, as we
know that this new transaction is both honest, and considered unconfirmed
for this party. Therefore, the argument for Case 5 holds for τ itself as well.
As the execution equivalence defined in Lemma 2 is the same as that of (11),
this part of the invariant is preserved.
(12) By the newly added transaction being unconfirmed, it satisfies any quantifi-
cation where τ is set to it. By now being recorded, the range of quantifications
for τ 0 is restricted, relaxing the condition.
(14) By equal update.
(16) By the newly recorded transaction being considered unconfirmed by an hon-
est party.

Finally, both worlds submit to the ledger the same transaction τ , which sim-
ply sent to the adversary. At this point I holds as argued above, and as the same
transaction is sent, the environment cannot distinguish. Finally, (posted, τ ) is
returned, giving the environment no information to distinguish for the same
reasons.

Case (check-query, τ ). After running updateState, Lemma 3 preserves the


invariant, but also ensures that Σp = GL .M (p), where Σp is the value returned
in both worlds (by (1)).
∆,Λ
We consider three cases: 1. τ ∈ / Σp , 2. Fsc .T (τ ) = (p, . . .), and 3. otherwise.
In Case 1, both worlds return not-found without updating any state, not al-
lowing the environment to distinguish, and preserving I. In Case 2, both worlds
run execResult(prefix(Σp , τ )), preserving I according to Lemma 2, and returning
the same value in both worlds, giving the environment no information to dis-
tinguish. Finally, in Case 3, only the real world runs execResult, while the ideal
world returns ⊥. As previously in updateState the sub-function execConfirmed
was run, we know that all NIZK-verifications performed in this exec call have
previously been made – as a result the call modifies no state, and preserved I.
Further, by Lemma 2, it returns ⊥, as in the ideal world, giving the environment
no information to distinguish.

Case (submit, τ ). In both worlds τ is handed to the adversary, and no other


action is taken. As the same information is relayed, the environment cannot
distinguish, and as no state is changed, I is preserved.

Case read. By (1), both worlds will return the same result; therefore the envi-
ronment cannot distinguish. As no state is changed, I is preserved.

Case (extend, Σ 0 ). As nothing is returned, the environment gains no informa-


tion allowing it to distinguish. By (1), the updates done are the same in both
worlds. The parts of the invariant affected and preserved are the following:

(1) By equal update.

56
(11) Extending GL .Σ further constrains the possible Σ values quantified over.
(12) Without loss of generality, we can assume single-transaction appends to
GLr .Σ. If a new unrecorded transaction is added, it (at first) does not pre-
ceed any transactions, leaving the quantification unchanged, and relaxing
the non-existance quantifier. If a recorded honest transaction is added, then
by (9) and (13), this transaction satisfies the conditions.
(13) By the append-only nature of extend.
(16) By relaxing the constraint.

Case (advance, p, Σ 0 ). As nothing is returned, the environment gains no infor-


mation allowing it to distinguish. By (1), the updates done are the same in both
worlds. The parts of the invariant affected and preserved are the following:

(1) By equal update.


(8) Without loss of generality, we can assume single-transaction advances. If
GL .M (p) ∩ φp .U 6= ∅, or the newly added transaction τ ∈ φp .U , this is pre-
served as the longest prefix remains equal. Otherwise, Σ in the induction step
is that of the induction hypothesis, with one transaction τ ∈ / φp .U appended.
If τ is not owned by p, by (5), φp .T (τ ) = ⊥, and therefore execState(Σ k τ )
returns the same ρ as execState(Σ), preserving the invariant. If τ is owned
by p, by (9), this transaction will be rejected, likewise returning the same ρ.
Further, as D \ C \ U is already ∅ for all dependency lists D, and extending
Σ can only lead to C growing, this condition remains satisfied.
(9) By further restricting all-quantification and non-existance quantification.
(13) By condition that GLr .M (p) ≺ GLr .Σ.

Case (prove, x, w). In the ideal world, this query is handled by the simulated
L
functionality S.Fnizk . If (x, w) ∈
/ L the call returns immediately with ⊥ in both
worlds, and no variables are modified, giving the environment no information to
distinguish, and preserving I. Otherwise, the adversary is immediately queried
with (prove, x) in both worlds. Again, at this point no variables have been mod-
ified, preserving I, and the information handed to the adversary is the same in
both worlds, giving the environment no information to distinguish. The adver-
sary will eventually respond with a proof π, which is verified against constraints
in both worlds, and randomly sampled if it does not meet them. By (2), the con-
straints are identical in both worlds. Finally Π and W are set, and π returned
in both worlds, giving no distinguishing information to the environment. The
following parts of the invariant are affected and preserved:

(2) By equal update.


L,r L
(3) By equal insertion into Fnizk .W , and S.Fnizk .W .
(4) By relaxing the constraint.
(9) As the possible results of executing transactions consisting of unrecorded
statement/proof pairs is constrained – the environment can no longer decide
if they should be processed or not.
(11) As in (9).

57
(12) As in (9).
(15) As only members of L are recorded.
(16) As in (9).

Case (verify, x, π). The flow for verification is only slightly more complex than
that for proving. At a high level, the adversary may be given a chance to produce
a last-moment witness for the statement being verified. If it refuses to do so, the
proof is recorded as definitively invalid. We consider three sub-cases: 1. The
statement/proof pair is recorded as either valid or invalid. 2. The adversary
returns a valid witness. 3. The adversary does not return a valid witness.
In Case 1, verify returns the same value in both worlds by (2), giving
the environment no means to distinguish. Case 2 is equivalent to the adversary
first sending a prove query for the given statement, and supplying it with the
corresponding proof, and then running the verify query. We therefore refer to
Case 1, and the case of prove. In Cases 1 and 2, no state is changed, preserving I.
L,r
Finally, for Case 3, Fnizk .Π is updated equally in both worlds, and ⊥ is returned
in both worlds, giving the environment no information to distinguish. In this
case, the following parts of the invariant are affected and preserved:

(2) By equal update.


L,r
(7) By relaxing the condition on Fnizk .Π.
(9) As the possible results of executing transactions consisting of unrecorded
statement/proof pairs is constrained – the environment can no longer decide
if they should be processed or not.
(11) As in (9).
(12) As in (9).
(16) As in (9). u
t

As the environment cannot with non-negligible probability between the real


and ideal world in any single action if I is preserved, and as I is preserved with
overwhelming probability across each action by the environment, and holds at
protocol initialization, we conclude that the environment cannot distinguish in
the UC game. u
t

E Proof Sketch of the Zerocash Contract

Proof (sketch of Theorem 2). To begin with, observe that from the collision resis-
κ
tance of PRFs, commitments, and sampling from {0, 1} , all coin commitments,
serial numbers, and public keys will be unique with overwhelming probability.
The environment can perform the following primary actions: a) For any hon-
est party, run (post-query, w). b) For any honest party, run (check-query, τ ).
c) For any party, run (submit, τ ) against GL . d) For any party, run read against
GL . e) Run (advance, p, Σ 0 ) against GL , and e) for any party, run (extend, Σ 0 )
against GL .

58
All but the first two of these are trivial. The simulator forwards all queries
to GL , and the state of GL depends on no other functionality (transactions “sub-
mitted” in the ideal functionality are only passed to the adversary). As a direct
result, the state and return value of GL follow the same distribution in both
worlds, giving the environment no means to distinguish.
During the running of check-query the environment does have a signifi-
cant additional means of input, in the form of being able to assign meaning to
adversarial transactions as they get executed for the first time. It is sufficient to
show the following: a) From the ideal-world leakage, the simulator can create
indistinguishable real-world leakage. b) Ideal-world transactions have the same
leakage descriptions sent to the environment (and are rejected under the same
conditions). c) An invariant holds between the ideal and real-world contract
state, such that it is preserved across both honest and adversarial transactions’
transition function executions.
We omit the full detail of this invariant. To sketch the idea behind it, we
must prove that the following are preserved: The public keys recorded in the
ideal contract state, and the simulator must correspond directly to secret keys
recorded in the real contract state, and the same public keys returned by the real
contract. Further, the coins held by honest parties in the real contract should be
valid at any time, and correspond directly to the balance of the same party in
the ideal contract. Honest unconfirmed transactions in both the real and ideal
contracts should still be valid when they are finally executed (also implying they
do not conflict with each other).
These are preserved across honest init calls, as the simulator ensures the keys
it stores, and the public keys returned in the ideal contract, are generated in the
same way as in the real contract. They are preserved across honest send calls,
as they remove one commitment from an honest party’s coins, and potentially
add it to the respective recipient party. Further, the leakage functions of honest
sends in the real contract ensures the same coin cannot be spend again. They
are preserved across honest mints, as again the balance is incremented alongside
a new coin being recorded. For adversarial transactions, as the simulator has all
honest private keys, it can, and does, check if an honest party would register
receiving a new coin. If a coin is sent, but no honest party receives it, the simu-
lator records it as adversarial – even if it may not be spendable by the real-world
adversary. Further, the simulator manages which real-world coin commitments
are associated with which adversarial public key in the ideal world. This ensures
it can always spend a corresponding ideal coin to whatever was spent in the real
world (assuming the real world adversary doesn’t spend a coin he doesn’t own,
violating the one-wayness of the PRF).
Transactions remaining valid in the ideal world is guaranteed by ensuring the
balance of a party cannot fall below zero – by assuming the worst case of only
balance removing transactions becoming confirmed. Likewise, in the real world,
the coins eligible for spending are those received in confirmed transactions, but
not spent in unconfirmed ones, ensuring they will not conflict. In both cases, key

59
generation will be refused if one is currently unconfirmed. mint and balance
queries both only require initialisation to have taken place in either world.
To observe that the simulator creates indistinguishable leakage, we first note
that the leakage for real-world init transactions is an empty transcript, which
the simulator indeed recreates. For send transactions, the simulator creates a
public state transcript following the same structure of one in the real contract
execution – spending a coin, creating a new one, and sending a message. Here
there are two cases: either the recipient is adversarial, or it is honest. In the
case of an honest recipient, the simulator does not know the exact public key of
the recipient. Fortunately, however, the environment does not know their secret
keys for the same reason. As a result, it is sufficient to commit to an arbitrary
coin, and encrypt arbitrary secrets. Due to the hiding of the commitments, and
the key-privacy of the encryption scheme, the environment cannot distinguish
this from a real transaction. The simulator creates a random serial number –
revealing nothing due to collision resistance, and from the leakage of the length
of the ledger, can reconstruct the corresponding Merkle tree root, revealing the
same root as the corresponding real-world transaction.
If the adversary is the recipient, the simulator is given the actual public keys
– and can use these directly as in the real protocol, creating a valid spendable
commitment, and a message the adversary can decrypt. Minting is similar to
the case of sending to an honest party – except no message is encrypted. For
the same reason, the leakage is indistinguishable. Finally, honest balance queries
have no leakage in the real world.
For honest parties, the leakage descriptor the environment is asked to sign off
on is identical – for init, mint, and balance consisting of just this string, and
for send, it is (send, t, pk), where pk is the recipient, if it is adversarial, and oth-
erwise is omitted. In each case, assertions made about the current and projected
states are satisfied in either both worlds, or neither, ensuring the transaction is
rejected or posted equally in both worlds. Specifically, all have tests for whether
keys are initialised (asserting negatively in init, and positively everywhere else).
During spending, a positive spendable balance is also asserted in both worlds.
These holding simultaneously is guaranteed by the invariant holding.
Finally, the transaction outputs the environment receives are the same in
both worlds: For init, the simulator ensures it sees equally distributed public
keys. For balance, the equal distribution is guaranteed by the invariant. For
all other messages, it will only see if they are in the ledger state – as the honest
transactions cannot fail, and return nothing. u
t

F Liveness of Smart Contracts

We have presented Kachina in a model without liveness guarantees. In this


section, we discuss how to model, and prove Kachina secure in the presence of
such liveness guarantees. Similar principles can be used to argue for the security
of Kachina for further modifications to the ledger protocol, such as adding
consensus-level validation predicates.

60
F.1 The δ-delay Ledger

While the simplified ledger GsimpleLedger is nice for the analysis of protocols build-
ing on it as a global functionality, in practice users would like to take advantage
δ
of some liveness guarantees. We present a ledger GdelayLedger , which annotates
transactions with a time at which they were received. This time is never re-
turned to parties, however it asserts that every party can see a transaction, once
it is δ time slots in the past. This ledger operates under the assumption of a
global clock Gclock , which is also presented here. We posit without proof that
δ
GdelayLedger UC-emulates GsimpleLedger , by virtue of the latter having far greater
adversarial power.

δ
Functionality GdelayLedger

The δ-delay ledger adds liveness guarantees to GsimpleLedger , ensuring that suffi-
ciently old transactions are always visible to honest parties.

State variables and initialisation values:

Variable Description
Σ :=  Authoritative ledger state
M := λp. Mapping of parties to ledger states
U := ∅ Multiset of unconfirmed transactions

When receiving a message (submit, τ ) from a party p:


send read to Gclock and receive the reply t
let U ← U ∪ {(τ, t)}
query A with (transaction, τ, t)
When receiving a message read from a party p:
assert liveness
return map(proj1 , M (p))
When receiving a message (extend, Σ 0 ) from A:
if Σ 0 ⊆ U then
let U ← U \ Σ 0
let Σ ← Σ k Σ 0
When receiving a message (advance, p, Σ 0 ) from A:
if M (p) ≺ Σ 0 ≺ Σ then
let M (p) ← Σ 0 .

Helper procedures:
procedure liveness
send read to Gclock and receive the reply t
if ∃(τ, t0 ) ∈ U : |t − t0 | > δ then return ⊥
else if ∃(τ, t0 ) ∈ Σ : |t − t0 | > δ ∧ ∃p ∈ H : (τ, t0 ) ∈
/ M (p) then return ⊥
else return >

61
Functionality Gclock

The global clock allows parties to agree on some discrete notion of time.

State variables and initialisation values:

Variable Description
t := 0 Current time
T := ∅ Timekeepers
A := ∅ Agreements to advance

When receiving a message register from a party p:


let T ← T ∪ {p}
When receiving a message deregister from a party p:
let T ← T \ {p}
When receiving a message update from a party p:
let A(p) ← >
if ∀p ∈ T.A(t) then
let t ← t + 1; A ← λp.⊥
query A with tick-tock
When receiving a message read from a party p:
return t

F.2 Commutativity of Ledger Realisations

It is of note that since the ledger exists in both the ideal and real world, we would
ideally wish to be able to utilise the stronger δ-delay ledger (and others) in the
ideal world as well. This is not trivial, however – the UC proof presented in this
paper holds for the simple ledger, and while the transitivity and composability of
UC proofs implies that the simple ledger can be replaced by the stronger ledger
in the real world, this is not the only goal.
In order to enable ideal-world replacement, we consider when UC replace-
ments are commutative. Specifically, consider we have four functionalities, A, B,
C, and D, such that: a) A and B both have C as a global functionality, b) A is
UC-emulated by B with the simulator SB , and c) C is UC-emulated by D with
the simulator SD . Observe that this is a generalisation of our situation, where
∆,Λ
A is Fsc , B is Kachina, C is GsimpleLedger , and D is some other ledger GL .
When can we conclude that A is still UC-emulated by B even if the global
functionality is replaced by D in both worlds? I.e. when can we perform the
inner UC-replacement first, and still be able to perform the outer one?

Theorem 3. Given A, B, C, D, SB , SC as defined in Subsection F.2, if SB


forwards all adversarial queries to C unchanged, and makes no queries of its
own to C, then A is UC-emulated by B with the global functionality D in place
of C.

62
Proof. We will provide this proof largely visually. The environment has a num-
ber of actions it can perform in any given world, in tandem with the dummy
adversary. We will represent these as unconnected wires in a circuit represen-
tation of the different UC functionalities. Each wire is coloured in accordance
with its purpose; these colours serve only to differentiate the wires. We visualise
the preconditions of Theorem 3 in Figure 4 and Figure 5. This crucially includes
the precondition that SB forwards adversarial queries to C, which is represented
equivalently by these queries being made directly instead.

SB A C ≈ B C

Fig. 4. The first part of the precondition: B UC-emulates A.

SD C ≈ D

Fig. 5. The second part of the precondition: D UC-emulates C.

By the UC emulation theorem, for all environments, executions with the


simulator and the ideal-world protocol are equivalent to executions with the
real-world protocol. Due to the all-quantification of the environment, we can
replace any part of a circuit diagram which matches exactly one of the two sides
of the equivalence with the other – this is the foundation of the compositionality
in UC.
We first make use of this in the non-standard direction, of making our ideal-
world protocol more ideal. Specifically, replace the right-hand side of Figure 5
with the left. We start similarly to the left-hand side of Figure 4, however using
D instead of C. Visually, Figure 6 demonstrates the result, which includes two
independent simulators.

SB A D ≈ SB A C SD

Fig. 6. Visual equivalence for idealising the sub-protocol D.

63
From here, we can realise both the ideal-world functionalities, provided it is
in the correct order: We must first realise A, as it relies on the presence of C.
We can directly apply the equivalence of Figure 4, as can be seen in Figure 7.

SB A C SD ≈ B C SD

Fig. 7. Visual equivalence for substituting the main protocol B.

Finally, nothing stands in the way of realising C with D, using the equivalence
of Figure 5 again, this time in the more typical direction. As a result, we get in
Figure 8 the final step, leading us to the intended equivalence, and proving the
related UC-emulation statement.

B C SD ≈ B D

Fig. 8. Visual equivalence for re-substituting D.

As a final remark, we observe that Kachina satisfies the preconditions for


commutativity, as SKachina does not make adversarial queries to Gledger .

G Enforcing Private State Consistency


The protocol presented so far allows an adversary to arbitrarily set his own
private state. Often it may be desirable to ensure that parties must follow the
rules of the contract, even when it comes to the private state, however. This
is possible, although it also introduces extra costs, and has the caveat of not
functioning with nondeterminism.
The core idea is to store commitments to private states within the public
state of the contract. The contract itself can then verify that the private state
is consistent with this commitment, update it, and then re-commit to the new
state, proving the correctness of every step along the way. Clearly this adds more
work to be verified about the contract, however a more worrying change is that
again the contract needs to be able to process the entirety of the private contract
state. Fortunately using slightly more complex updateable cryptographic datas-
tructures, such as Merkle trees, can mitigate this problem – although it cannot
be eliminated entirely, as computation which aggregates the entire private state
will still be as costly.

64
H Non-Atomic Executions

Smart contracts are typically closely linked with transactions made on the un-
derlying ledger, and indeed we explicitly make the same link in this paper. That
being said, there are numerous applications which do not rely on a single transac-
tion per interaction with a contract, from Hawk [22], which requires at least two
transactions per round of interaction, to state channels [13], which have many
of the same properties of smart contracts, but may (under optimal conditions)
not require transactions at all.
While the model of smart contracts presented in Section 3 technically ex-
cludes both of these, and a full treatment of both would require further work, it
is nonetheless worth considering how they can be – albeit imperfectly – embed-
ded in this model. First, let us consider contract queries which require multiple
on-chain interactions to “complete”. As an example from Hawk, consider Alice
posts a query to a Hawk-style contract. Naturally, this will not immediately re-
turn – even if Alice’s transaction has made it on-chain. Instead, the transaction
could return a “future object” – a concept often used in concurrent program-
ming design, essentially just being a reference ID, and a promise to associate
some data with it later. Both Alice and the manager party would have to reg-
ularly poll the contract – e.g. send a contract query poll every 10 minutes.
On the manager’s next poll query, he would update the Hawk private state,
and encrypt and post the result for Alice. Finally, when Alice next polls, she
would retrieve the result, and associate it with the previous “future object” as
an output. This sketches a protocol running on top of Kachina, which achieves
this style of interaction. It is worth noting that this requirement for end-users to
interact is also a limitation of the underlying model of universal composability:
The environment must manually instruct parties to resume, or messages to be
forwarded by the adversary.
In a similar vein, we can observe that some transactions need not be placed
on a ledger. In particular, if the shared, public state is not used, the transac-
tion is essentially “offchain”, and there is no need to publicly post it. Further,
if the public state is used for message passing (such as in the construction of
a Zerocash contract above), this part of the transaction need not be on-chain
– sending an out of band message is cheaper. Using the same UC-based ap-
proach described above, it would therefore be possible, for example, to first
define an ideal payment-channel contract, and prove that this is UC-emulated
by a contract implementing, for instance, Perun [12]. Finally, we can argue that
most transactions in this contract can be omitted from the ledger, as they are
just two-party channel interactions. This is a rather roundabout means of con-
structing off-chain communication, however it brings a crucial guarantee with it,
namely that it behaves the same under ledger reorderings as a purely on-chain
contract.

65
I Meta-Parties and Their Relation to Alternative Trust
Models

So far we have presented, and argued for, a model of smart contracts with clear
black-and-white privacy: Users have their own perfectly private local state, and
access to a perfectly public shared state. While we believe this to be the best
starting point for approaching the issue of privacy in smart contracts, reality is
not so simple: Often users have more complex relations with each other.
To consider this more carefully, we can consider that any piece of data in
a smart contract must have a set of owners O, who can interact with it. Fur-
thermore, in any real system, there are parties which can, together, decipher
the actual data itself, and break the privacy of it. Let us refer to the set of all
combinations of parties able to decipher the data as T. While not strictly nec-
essary, in general it is reasonable to assume that the owners are also the users
able to break privacy, that is T ⊆ 2O . While clearly there are many possible
combinations here, a few stand out as interesting, and we observe that they all
relate to some interpretation of privacy-preserving smart contracts:

– O = P, T = 2P : This is the setting of Ethereum, and of the σ used in this


work. Data is public, but can be interacted with by all.
– O = {p}, T = {p}: This is the setting of ρ used in this work. Data is private,
but cannot be interacted with by anyone else.
– O = P, T is all subsets of P with a resource majority (regardless of work,
stake, or what other honest majority assumption is being made): This setting
is feasible by running MPC across the honest majority of the underlying
consensus protocol.
– O is a fixed-size set, T = {m}: This is the setting of Hawk [22], in which a
single party is trusted with privacy.
– O is a fixed-size set, T = {O}: This is the setting of privacy-preserving
state-channels, in which parties run MPC out-of-band to agree on updates.
– O is a fixed-size set, T = 2O : This is the setting of public state-channels, in
which parties run Arbitrum-like protocols out-of-band to agree on updates.

In particular, this work only directly concerns itself with the first two of
these. It is clear, however that different problems call for different solutions, and
ideally a smart contract system would encode all of these trust systems, not just
one, or a few. Part of the reason for the choice of the first two is that they are
sufficient for constructing the rest, being the exteremes of the spectrum.
The case of Hawk, for instance, was already described above in Appendix H.
We will sketch how state channels might be modelled on top of Kachina, al-
though we stress that a full formal treatment of this, and other settings, will be
left for future work.
A state channel between two users can be interpreted as the two users con-
stituting a “metaparty” – a single entity consisting of multiple parties. This is
subject to some access control for when the constituent parties can act on behalf
of both – commonly requiring agreement from all constituent parties. If Alice

66
and Bob open a new state channel, this can be seen as creating a new combined
party of (Alice, Bob).
In Kachina, this party again has its own private state, and for state chan-
nels, this can track the most recent update of the channel. Updates are now
operations that only affect the private state of this combined party, and as ar-
gued in Appendix H can be left off the ledger entirely. Interestingly, the access
structure for closing channels, and reading the current state is more permissive
in most state or payment channels – requiring only one user to initiate it.
Given a state channel system, most of it can be implemented in a Kachina
smart contract. It is not new for state or payment channels to use smart con-
tracts, however this is typically only for the opening and closing of the channel.
We observe that in Kachina the update of the channel can also be modelled.
This approach of metaparties is useful, but not optimal. For instance, a con-
tract cannot interact with both Alice’s private state, and the state channel be-
tween Alice and Bob at the same time, as presented here. Further, how the
constituents of a metaparty reach consensus on whether an action is permitted
or not is unclear, and varies from case to case. We leave as future work giving
first-class treatment to data owned by multiple parties.

J Smart Contract Systems

To construct complex systems of multiple smart contracts, not much additional


machinery is required. In this section, we incrementally construct a complex
system with similar functionality to Ethereum [31]. We begin by multiplexing
between a fixed set of transition functions, and expand this with the ability to
allow new transition functions to be registered, transition functions to call each
other, registered contracts to hold and transfer funds, and combine in a setting
where computation has an associated cost, which must be paid by the caller. We
finally show how access to the underlying ledger may be modelled.
It is worth noting that we only concern ourselves with the “real world” of
Kachina contracts. A reasonable question is how to transfer a proof such as the
one we presented in Section 5 into this setting. While we don’t go into the details
here, we observe that (with one exception for the specific token contract used),
only the smart contract’s own transition function affects its state. Running a
multiplexed smart contract is equivalent to running many small smart contracts
independently – only interpreting the ledger differently. This is no longer true
once contracts may call each other – in which case it is sufficient to reason about
the closure of contracts able to call each other instead.

J.1 Multiplexing Contracts

The basic multiplexing contract takes n different sub-contracts as inputs. Each


party supplies not only the input, but the index i of the contract they wish
to call. The public and private states of the multiplexer consist of the product
of the corresponding sub-contract states, and oracle queries are re-written to

67
address the correct part of the state. To do some, new oracles Oσ0 and Oρ0 are
constructed, which rewrite queries made to them. Then, the requested transition
function is run with these oracles, instead of the original ones.

Transition Function Γmux

The multiplexing transition function Γmux is parameterised by n transition func-


tions Γ1 , . . . , Γn , and allows a users to address any one of them.

Public state variables and initialisation values:

Variable Description
∀i ∈ Zn : σi := ∅ Public states for each sub-contract

Private state variables and initialisation values:

Variable Description
∀i ∈ Zn : ρi := ∅ Private states for each sub-contract

When receiving an input (i, w):


assert i ∈ Zn
let Oσ0 ← λq : Oσ (muxPubOracle(i, q))
let Oρ0 ← λq : Oρ (muxPrivOracle(i, q))
return Γi,Oσ0 ,Oρ0 (w)

Helper procedures:
function muxPubOracle(i, q, σ, ∅)
let σ 0 ← σ.σi
let (σ 0 , y) ← q(σ 0 , ∅)
if σ 0 = ⊥ then return (⊥, y)
else
let σ.σi ← σ 0
return (σ, y)
function muxPrivOracle(i, q, ρ, (σ o , ρo , σ π , ρπ , η))
let ρ0 ← ρ.ρi
let z 0 ← (σ o .σi , ρo .ρi , σ π .σi , ρπ .ρi , η)
let (ρ0 , y) ← q(ρ0 , z 0 )
if ρ0 = ⊥ then return (⊥, y)
else
let ρ.ρi ← ρ0
return (ρ, y)

We assume the existence of unmuxPubOracle and unmuxPrivOracle, which


take an oracle transcript to an Oracle produced by a multiplexed oracle, and
return the pair (i, T 0 ), where i is the address used in the original multiplexing,
and T 0 is the equivalent un-multiplexed transcript.
function unmuxZmux ((σ o , ρo , σ π , ρπ , η), i)

68
return (σ o .σi , ρo .ρi , σ π .σi , ρπ .ρi , η)
function unmuxXmux (X, i)
let X 0 ← 
for (u, T , z, D) ∈ X do
if ∃T 0 : unmuxPrivOracle(T ) = (i, T 0 ) then
let X 0 ← X 0 k (u, T 0 , unmuxZmux (z, i), D)
return X 0
function descmux (t, X, Tσ , Tρ , (i, w), z)
let (·, Tσ0 ) ← unmuxPubOracle(Tσ ); (·, Tρ0 ) ← unmuxPrivOracle(Tρ )
let X 0 ← unmuxXmux (X, i); z 0 ← unmuxZmux (z, i)
return “Calling sub-contract i: ”+desci (t, X 0 , Tσ0 , Tρ0 , w, z 0 )
function depmux (X, Tρ , z)
if Tρ =  then return ∅
else
let (i, Tρ0 ) ← unmuxPrivOracle(Tρ )
let X 0 ← unmuxXmux (X, i); z 0 ← unmuxZmux (z, i)
return depi (X 0 , Tρ0 , z 0 )

J.2 Multiplexing With Registration


To allow registering new contracts in the multiplexer, it is possible to include
the full contract’s description as part of its address A. In practice it may make
more sense to maintain a mapping from addresses to contract code, however we
observe that this is not required. The only other large changes is that, since
contracts are created on the fly, we cannot rely on their states to have been
initialised at any point. Therefore, this initialisation takes place at any point
where the multiplexed state is accessed.
function forceInitMaps(((M1 , . . . , Mn ), k, v))
for i ∈ {1, . . . , n} do
if k ∈/ Mi then let Mi (k) ← v
return (M1 , . . . , Mn )

Transition Function Γregmux

The multiplexing with registration transition function Γregmux allows addressing


any pair of address and sub-transition function (A, Γ). It uses the specified tran-
sition function on whatever state is associated with this pair, or a new, empty
state for the first use.

Public state variables and initialisation values:

Variable Description
Σ := ∅ Mapping from address pairs to public states

Private state variables and initialisation values:

69
Variable Description
P := ∅ Mapping from address pairs to private states

When receiving an input (A = (i, Γ, desc, dep), w):


let Oσ0 ← λq : Oσ (muxPubOracle(A, q))
let Oρ0 ← λq : Oρ (muxPrivOracle(A, q))
return ΓOσ0 ,Oρ0 (w)

Helper procedures:
function muxPubOracle(A, q, σ, ∅)
if A ∈ / σ.Σ then let σ.Σ(A) ← ∅
let σ 0 ← σ.Σ(A)
let (σ 0 , y) ← q(σ 0 , ∅)
if σ 0 = ⊥ then return (⊥, y)
else
let σ.Σ(A) ← σ 0
return (σ, y)
function muxPrivOracle(A, q, ρ, (σ o , ρo , σ π , ρπ , η))
let (ρ.P, σ o .Σ.ρo .P, σ π .Σ, ρπ .P ) ←
forceInitMaps((ρ.P, σ o .Σ, ρo .P, σ π .Σ, ρπ .P ), A, ∅)
let ρ0 ← ρ.P (A)
let z 0 ← (σ o .σi , ρo .ρi , σ π .σi , ρπ .ρi , η)
let (ρ0 , y) ← q(ρ0 , z 0 )
if ρ0 = ⊥ then return (⊥, y)
else
let ρ.P (A) ← ρ0
return (ρ, y)

We assume the existence of unmuxPubOracle and unmuxPrivOracle, which


take an oracle transcript to an Oracle produced by a multiplexed oracle, and
return the pair (A, T 0 ), where A = (i, Γ, desc, dep) is the address used in the
original multiplexing, and T 0 is the equivalent un-multiplexed transcript.
function unmuxZregmux ((σ o , ρo , σ π , ρπ , η), A)
let (σ o .Σ, ρo .P, σ π .Σ, ρπ .P ) ← forceInitMaps((σ o .Σ, ρo .P, σ π .Σ, ρπ .P ), A, ∅)
return (σ o .Σ(A), ρo .P (A), σ π .Σ(A), ρπ .P (A), η)
function unmuxXregmux (X, A)
let X 0 ← 
for (u, T , z, D) ∈ X do
if ∃T 0 : unmuxPrivOracle(T ) = (A, T 0 ) then
let X 0 ← X 0 k (u, T 0 , unmuxZregmux (z, A), D)
return X 0
function descregmux (t, X, Tσ , Tρ , (A = (·, ·, desc, ·), w), z)
let (·, Tσ0 ) ← unmuxPubOracle(Tσ ); (·, Tρ0 ) ← unmuxPrivOracle(Tρ )
let X 0 ← unmuxXregmux (X, A); z 0 ← unmuxZregmux (z, A)
return “Calling sub-contract A: ”+desc(t, X 0 , Tσ0 , Tρ0 , w, z 0 )
function depregmux (X, Tρ , (σ o , ρo , σ π , ρπ , η))
if Tρ =  then return ∅

70
else
let (A = (. . . , dep), Tρ0 ) ← unmuxPrivOracle(Tρ )
let (σ o .Σ.ρo .P, σ π .Σ, ρπ .P ) ←
forceInitMaps((σ o .Σ, ρo .P, σ π .Σ, ρπ .P ), A, ∅)
let z 0 ← (σ o .Σ(A), ρo .P (A), σ π .Σ(A), ρπ .P (A), η)
let X 0 ← 
for (u, Tρ , (σ o , ρo , σ π , ρπ , η), D) ∈ X do
if ∃Tρ0 : unmuxPrivOracle(Tρ ) = (A, Tρ0 ) then
let (σ o .Σ.ρo .P, σ π .Σ, ρπ .P ) ←
forceInitMaps((σ o .Σ, ρo .P, σ π .Σ, ρπ .P ), A, ∅)
let X 0 ← X 0 k (u, Tρ0 , (σ o .σi , ρo .ρi , σ π .σi , ρπ .ρi , η), D)
return dep(X 0 , Tρ0 , z 0 )

J.3 Loopback Multiplexing

Smart contract systems truly become interesting when contracts are allowed to
call each other. This is not a technically difficult operation: Contracts simply
need to have an additional exit and entry point to allow new queries to other
contracts to be made, and these queries to be responded to. Specifically, we
require contracts to either return (return, y), or (call, A, M ), with the latter
invoking a separate contract. we associate a special return value structure with
indicating a new contract address and input to call, and require contracts to
process a specific resume message.
As for the first time, it is possible for multiple separate contracts to get called,
we domain-separate the randomness source η.
function unxmuZloopmux ((σ o , ρo , σ π , ρπ , η), A)
let (σ o .Σ, ρo .P, σ π .Σ, ρπ .P ) ← forceInitMaps((σ o .Σ, ρo .P, σ π .Σ, ρπ .P ), A, ∅)
Let η 0 be a randomness source determinstically and collision-resistantally derived
from the pair (η, A).
return (σ o .Σ(A), ρo .P (A), σ π .Σ(A), ρπ .P (A), η 0 )

Transition Function Γloopmux

The multiplexing with registration and loopback transition function Γloopmux al-
lows addressing any pair of address and sub-transition function (A, Γ). These
sub-transition functions may, return values of either (call, A, M ), or (return, y).
In the former case, a different sub-transition function is invoked, and the value
it eventually returns is fed back into the original one, by re-invoking it with
(resume, y).

Public state variables and initialisation values:

Variable Description
Σ := ∅ Mapping from address pairs to public states

Private state variables and initialisation values:

71
Variable Description
P := ∅ Mapping from address pairs to private states

When receiving an input (A = (i, Γ, desc, dep), w):


let Oσ0 ← λq : Oσ (muxPubOracle(A, q))
let Oρ0 ← λq : Oρ (muxPrivOracle(A, q))
repeat
let y ← ΓOσ0 ,Oρ0 (w)
if ∃A0 , M : y = (call, A0 , M ) then
let w ← resume, Γloopmux,Oσ ,Oρ ((A0 , M ))


until ∃y 0 : y = (return, y 0 )
return y 0

Helper procedures:
function muxPubOracle(A, q, σ, ∅)
if A ∈ / σ.Σ then let σ.Σ(A) ← ∅
let σ 0 ← σ.Σ(A)
let (σ 0 , y) ← q(σ 0 , ∅)
if σ 0 = ⊥ then return (⊥, y)
else
let σ.Σ(A) ← σ 0
return (σ, y)
function muxPrivOracle(A, q, ρ, z)
let z 0 ← unmuxZloopmux (z, A)
if A ∈ / ρ.P then let ρ.P (A) ← ∅
let ρ0 ← ρ.P (A)
let (ρ0 , y) ← q(ρ0 , z 0 )
if ρ0 = ⊥ then return (⊥, y)
else
let ρ.P (A) ← ρ0
return (ρ, y)

Unlike before, we cannot invert the multiplexing on an entire transcript, as


the transcript may consist of multiple, separate, sub-contract calls. Instead, we
can invert multiplexing each query/response pair in the transcript itself. We
assume the existence of unmuxOracle, which take a query-response pair (q, r),
where the query is muxPubOracle(A, q 0 ) or muxPrivOracle(A, q 0 ), and maps it to
(A, (q 0 , r)).
As far as descriptions go, it is crucial to note that the leakage description
of a contract is no longer in isolation: what the contract may leak, depends on
what this contract calls. We will assume instead that each sub-contracts leakage
descriptor is aware that it is being run in a loopback system – and therefore we
give it the full transcripts, even of sub-contracts being called. The assumption
here is that the contract directly called by the user is also trusted by this user –
the descriptor it gives should be trusted, not necessarily that of any further con-
tracts it invoked. It is worth noting that this change of setting for the descriptor
function does not preclude using contracts designed without loopback systems

72
in mind: As this cannot invoke other contracts, their old descriptor function can
be easily lifted to this setting, as seen in Subsection J.2 (a slight caveat is that
either the old descriptor needs to be capable of tolerating unconfirmed transac-
tion transcripts over multiple calls to the underlying function, or there should
exist a function which splits transcripts into these individual calls).
function liftDesc(A, desc)(t, X, Tσ , Tρ , w, z)
let Tσ0 ← map(proj2 ◦ unmuxOracle, Tσ )
let Tρ0 ← map(proj2 ◦ unmuxOracle, Tρ )
let X 0 ← unmuxXregmux (X, A); z 0 ← unmuxZregmux (z, A)
return desc(t, X 0 , Tσ0 , Tρ0 , w, z 0 )
function unmuxT(T , A)
return map(proj2 , filter(λ(A0 , ·) : A = A0 , map(unmuxOracle, T )))
function unmuxXloopmux (X, A)
let X 0 ← 
for (u, T , z, D) ∈ X do
let T 0 ← unmuxT(T , A); z 0 ← unmuxZloopmux (z, A)
let X 0 ← X 0 k (u, T 0 , z 0 , D0 )
return X 0
function descloopmux (t, X, Tσ , Tρ , (A = (·, ·, desc, ·), w), z)
return “Calling sub-contract A: ”+desc(t, X, Tσ , Tρ , w, z)
function deploopmux (X, Tρ , z)
let S ← ∅
for (q, r) ∈ Tρ do
let (A, ·) ← unmuxOracle((q, r))
let S ← S ∪ {A}
let D ← ∅
for A = (·, ·, ·, dep) ∈ S do
let Tρ0 ← unmuxT(Tρ , A)
let z 0 ← unmuxZloopmux (z, A)
let X 0 ← unmuxXloopmux (X, A)
let D ← D ∪ dep(X 0 , Tρ0 , z 0 )
return map(proj1 , X) ∩ D

J.4 Integrated Payments Systems


Smart contract systems typically have an associated, native “asset”, which can be
traded not only by users, but by contracts as well. This asset is further typically
tied to a public key, which can be used as an identity of end users, providing a
means to authenticate to contracts. We demonstrate a simple means of achieving
this: We construct a “simple payments” contract, which allows payments by end
users through demonstrating knowledge of secret keys, and arbitrary payments
which will be restricted to system usage. It is worth noting that this could be done
in a privacy-preserving means, as presented in Section 5, although significant
changes would have to be made, as there would be situations where a contract
should publicly own funds, and be able to transfer them, and the simplified
single-denomination design is not ideal.

73
Transition Function Γsp

The state transition function for a simple payments system. Parties have associ-
ated public/private keys, and balances. The payments system allows for parties
without a key pair to generate one, and for parties to transfer and mint coins, as
well as query their own balance.

Public state variables and initialisation values:

Variable Description
B := λpk : 0 Mapping of public keys to their spendable coins

Private state variables and initialisation values:

Variable Description
sk := ∅ The party’s secret key

When receiving an input init:


send init to Oρ and receive the reply sk
let pk ← prf pk
sk (1)
return pk
When receiving an input (send, recv, v):
send secretKey to Oρ and receive the reply sk
let pk ← prf pk
sk (1)
send (send, pk, recv, v) to Oσ
return pk
When receiving an input (system-send, snd, recv, v):
send (send, snd, recv, v) to Oσ
When receiving an input (mint, v):
send secretKey to Oρ and receive the reply sk
let pk ← prf pk
sk (1)
send (mint, pk, v) to Oσ
When receiving an input balance:
send balance to Oρ

When receiving an private oracle query init:


assert ρπ .sk = ∅
R
− {0, 1}κ
let ρ.sk ←
return ρ.sk
When receiving an private oracle query secretKey:
return ρ.sk
When receiving an private oracle query balance:
return σ π .B(prf pk
ρπ .sk (1))

74
When receiving an public oracle query (send, pk, recv, v):
assert σ.B(pk) ≥ v
let σ.B(pk) ← σ.B(pk) − v
let σ.B(recv) ← σ.B(recv) + v
When receiving an public oracle query (mint, pk, v):
let σ.B(pk) ← σ.B(pk) + v

function descsp (t, X, Tσ , Tρ , w, z)


if Tσ = (init, pk) then return (init, pk)
else if Tσ = ((send, snd, recv, v) , ·) then return (send, snd, recv, v)
else if Tσ = ((mint, pk, v) , ·) then return (mint, pk, v)
else return ⊥
function depsp (X, T , z)
return 
Once given such a payments system, the multiplexing system can ensure that
for each call, a transfer to the called contract is initiated first, with the value of
the transfer, and the source address being passed into the contract being called.
Likewise, if this calls another contract, this call may transfer funds from one
contract to another.

Transition Function Γpaymux

The multiplexing with registration, loopback, and payments transition func-


tion Γpaymux allows addressing any pair of address and sub-transition function
(a, Γ). These sub-transition functions may, return values of either (call, A, M ),
or (return, y). In the former case, a different sub-transition function is invoked,
and the value it eventually returns is fed back into the original one, by re-invoking
it with (resume, y).

Public state variables and initialisation values:

Variable Description
Σ := ∅ Mapping from address pairs to public states

Private state variables and initialisation values:

Variable Description
P := ∅ Mapping from address pairs to private states

When receiving an input (token, w):


assert w 6= (system-send, . . .)
let Oσ0 ← λq : Oσ (muxPubOracle(token, q))
let Oρ0 ← λq : Oρ (muxPrivOracle(token, q))
return Γsp,Oσ0 ,Oρ0 (w)
When receiving an input (call, v, A = (i, Γ, desc, dep), w):

75
let pk ← Γpaymux,Oσ ,Oρ (token, (send, A, v))
return callOσ ,Oρ (v, pk, A, w)

Helper procedures:
function subCallOσ ,Oρ (v, A, A0 = (i, Γ, desc, dep), w)
assert A0 6= token
let Oσ0 ← λq : Oσ (muxPubOracle(token, q))
let Oρ0 ← λq : Oρ (muxPrivOracle(token, q))
run Γsp,Oσ0 ,Oρ0 (system-send, A, A0 , v)
return callOσ ,Oρ (v, A, A0 , w)
function callOσ ,Oρ (v, A, A0 = (·, Γ, ·, ·), w)
let Oσ0 ← λq : Oσ (muxPubOracle(A0 , q))
let Oρ0 ← λq : Oρ (muxPrivOracle(A0 , q))
repeat
let y ← ΓOσ0 ,Oρ0 (call, A, v, w)
if ∃v 0 , A00 , w0 : y = (call, v 0 , A00 , w0 ) then
let w ← resume, subCallOσ ,Oρ (v 0 , A0 , A00 , w0 )


until ∃y 0 : y = (return, y 0 )
return y 0
function muxPubOracle(A, q, σ, ∅)
if A ∈ / σ.Σ then let σ.Σ(A) ← ∅
let σ 0 ← σ.Σ(A)
let (σ 0 , y) ← q(σ 0 , ∅)
if σ 0 = ⊥ then return (⊥, y)
else
let σ.Σ(A) ← σ 0
return (σ, y)
function muxPrivOracle(A, q, ρ, (σ o , ρo , σ π , ρπ , η))
let (ρ.P, σ o .Σ.ρo .P, σ π .Σ, ρπ .P ) ←
forceInitMaps((ρ.P, σ o .Σ, ρo .P, σ π .Σ, ρπ .P ), A, ∅)
let ρ0 ← ρ.P (A)
let z 0 ← (σ o .σi , ρo .ρi , σ π .σi , ρπ .ρi , η)
let (ρ0 , y) ← q(ρ0 , z 0 )
if ρ0 = ⊥ then return (⊥, y)
else
let ρ.P (A) ← ρ0
return (ρ, y)

function descpaymux (t, X, Tσ , Tρ , M, z)


if ∃w : M = (token, w) then
return “Calling token contract:”+descsp (t, X, map(proj2 ◦ unmuxOracle, Tσ ),
map(proj2 ◦ unmuxOracle, Tρ ), w, z)
else if ∃v, A = (·, ·, desc, ·), w : M = (call, v, A, w) then
return “Calling sub-contract A with pay-in v: ”+desc(t, X, Tσ , Tρ , (⊥, v, w), z)
else return ⊥
deppaymux = deploopmux

76
J.5 Fees and Cost Models

In order to prevent denial-of-service attacks, the computations performed by


the network in verifying a transaction must be paid for in some way. In public
currencies, there is typically a cost model, which maps each step of computation
to a cost, often referred to as gas. Each transaction declares a limit on how much
gas it is willing to pay, and what each unit’s value should be. It then pays the
corresponding amount into a fees pool, and while executing the transaction, the
gas usage is counted. If the limit is reached, the transaction is rejected, otherwise
any spare gas is refunded.
We assume the existence of three cost models, $zk , $std , and Estd , calculating
the cost of a transition function execution, a calculating the cost of a public
state oracle execution, and estimating the cost of a public state oracle execution
respectively.
The oracle cost model $std takes a state σ, a gas budget gas, and an oracle
query q. It returns the amount of spare gas spare, and the query results σ 0 , and r,
ensuring the computation does not exceed the allotted gas limit: (spare, σ 0 , r) ←
$std (σ, gas, q). If this limit is reached, it returns (0, ⊥, ⊥), otherwise, (σ 0 , r) =
q(σ, ∅).
The cost oracle cost estimator Estd takes a state σ, and an oracle query q as
inputs, and returns an estimate e for the gas $std will require: e ← Estd (σ, q).
This is used to allocate the gas budget of each given query.
The transition function cost model $zk is parameterised with oracle access to
Oσ and Oρ , and given a transition function Γ and input w as inputs. It returns
afixed cost c, and a result y: (c, y) ← $zk (Oσ , Oρ , Γ, w), where y = ΓOσ ,Oρ (w).
It further guarantees that for each oracle query q made in Γ, the following code
is executed instead:
let e ← Oρ (λ(ρ, ·) : let (ρ.σ E , ·) ← q(ρ.σ E , ∅) in (ρ, Estd (ρ.σ E , q)))
let r ← Oσ (λ(σ, ·) : let (sp, σ 0 , r) ← $std (σ, e, q); σ 0 .spare ← σ 0 .spare + sp in (σ 0 , r))
The cost c returned must be at least the sum of all values e for each above
queries.
This directly has the effect that a) the estimate e is not exceeded by any
query, and b) that σ 0 .spare is precisely the difference between estimates and
actual costs. We assume here that σ.spare, and ρ.σ E are not touched by Γ, and
are initialised to 0 and σ π respectively. As a result, the smart contract system
using this cost model can ensure that spare funds are refunded, and that the
user pays the necessary fees.
It is worth noting that this is not entirely on par with existing fee models in
smart contract systems, due to one key issue: A failed transaction in Kachina
has no effect by definition. This also means that no miner can be awarded gas fees
for a failed transaction, as the fee payment is itself an effect of the transaction.
There are a few ways this could be solved – for instance introducing multiple fail-
ure states with different effects, or splitting transactions into linked fee-payment
and contract call sub-transactions. For instance, each transaction could consist
of both a contract call transaction as listed below, and a fee-payment transac-
tion of the same value, with the consensus rules ensuring the former is placed

77
in the ledger iff the gas cost is sufficient, and the latter otherwise. We do not
construct these here, but observe that in a practical system the payment of fees
will require a special status to combat denial of service attacks.

Transition Function Γscs

The multiplexing with registration, loopback, payments, and fees transition


function Γscs allows addressing any pair of address and sub-transition function
(a, Γ). These sub-transition functions may, return values of either (call, A, M ),
or (return, y). In the former case, a different sub-transition function is invoked,
and the value it eventually returns is fed back into the original one, by re-invoking
it with (resume, y). The transition function tabulates the cost of the call, and
ensures the caller sends this at the end of a valid transition.

Public state variables and initialisation values:

Variable Description
Σ := ∅ Mapping from address pairs to public states
spare := 0 Temporary book-keeping of the value to return

Private state variables and initialisation values:

Variable Description
P := ∅ Mapping from address pairs to private states
σ E := ∅ Temporary projected state for estimating gas costs

When receiving an input (token, w):


assert w 6= (system-send, . . .)
let Oσ0 ← λq : Oσ (muxPubOracle(token, q))
let Oρ0 ← λq : Oρ (muxPrivOracle(token, q))
return Γsp,Oσ0 ,Oρ0 (w)
When receiving an input (call, gasPrice, v, A = (i, Γ, desc, dep), w):
send init-spare to Oσ
send init-state to Oρ
let c ← 0
let pk ← Γscs,Oσ ,Oρ (token, (send, A, v))
let c ← c + csend
let (c0 , y) ← callOσ ,Oρ (v, pk, A, w)
let c ← c + c0
let pk ← Γscs,Oσ ,Oρ (token, (send, fee-pot, c × gasPrice))
send (deinit, pk, gasPrice) to Oσ
send deinit to Oρ
return y

When receiving an public oracle query init-spare:


let σ.spare ← 0
When receiving an public oracle query (deinit, pk, gasPrice):

78
run Γsp (fee-pot, pk, σ.spare × gasPrice)
let σ.spare ← 0

When receiving an public oracle query init-state:


let ρ.σ E ← σ π
When receiving an public oracle query deinit:
let ρ.σ E ← ∅

Helper procedures:
function subCallOσ ,Oρ (v, A, A0 = (i, Γ, desc, dep), w)
assert A0 6= token
let Oσ0 ← λq : Oσ (muxPubOracle(token, q))
let Oρ0 ← λq : Oρ (muxPrivOracle(token, q))
run Γsp,Oσ0 ,Oρ0 (system-send, A, A0 , v)
let (c, y) ← callOσ ,Oρ (v, A, A0 , w)
return (c + csend , y)
function callOσ ,Oρ (v, A, A0 = (·, Γ, ·, ·), w)
let Oσ0 ← λq : Oσ (muxPubOracle(A0 , q))
let Oρ0 ← λq : Oρ (muxPrivOracle(A0 , q))
let c ← 0; e ← 0
repeat
let (c0 , y) ← $zk (Oσ0 , Oρ0 , Γ, (call, A, v, w))
let c ← c + c0
if ∃v 0 , A00 , w0 : y = (call, v 0 , A00 , w0 ) then
let (c0 , y) ← subCallOσ ,Oρ (v 0 , A0 , A00 , w0 )
let c ← c + c0 ; w ← (resume, y)
until ∃y 0 : y = (return, y 0 )
return (c, y 0 )
function muxPubOracle(A, q, σ, ∅)
if A ∈ / σ.Σ then let σ.Σ(A) ← ∅
let σ 0 ← σ.Σ(A)
let (σ 0 , y) ← q(σ 0 , ∅)
if σ 0 = ⊥ then return (⊥, y)
else
let σ.Σ(A) ← σ 0
return (σ, y)
function muxPrivOracle(A, q, ρ, (σ o , ρo , σ π , ρπ , η))
let (ρ.P, σ o .Σ.ρo .P, σ π .Σ, ρπ .P ) ←
forceInitMaps((ρ.P, σ o .Σ, ρo .P, σ π .Σ, ρπ .P ), A, ∅)
let ρ0 ← ρ.P (A)
let z 0 ← (σ o .σi , ρo .ρi , σ π .σi , ρπ .ρi , η)
let (ρ0 , y) ← q(ρ0 , z 0 )
if ρ0 = ⊥ then return (⊥, y)
else
let ρ.P (A) ← ρ0
return (ρ, y)

79
descscs = descpaymux
depscs = deppaymux

J.6 Exporting Ledger Data


Real-world smart contract systems often have some means to extract limited
information about the underlying consensus protocol, such as the hash of the
most recent block, the address of the block’s miner, or the length of the current
chain. These can be useful in applications – in particular the latter, as it gives
an provides an imprecise clock for use in contracts.
Clearly, these rely on tighter integration with the underlying consensus mech-
anism than Kachina provides. We can still capture the core idea, by having a
sub-contract which manages such chain data, and allows this to be read and
set arbitrarily6 . We can then assume that the correct usage of this sub-contract
is enforced by the validation of the underlying consensus mechanism – transac-
tions which attempt to “incorrectly” set the chain data – for any definition of
“correct” will never reach the ledger.
Transition Function Γchaindata

The chain data transition function Γchaindata allow arbitrary setting and reading
of state. An external assumption is that the setting of state is both enforced and
restricted by the underlying ledger protocol, to give it meaning – for instance
each block may induce a phantom “chain-data” transaction which appears on the
ledger, and sets the most recent block hash in the chain-data contracts state.

When receiving an input (set, σ 0 ):


run Oσ (λ(·, ·) : (σ 0 , >))
When receiving an input get:
return Oσ (λ(σ, ·) : (σ, σ))

The contract we present here does have a further issue: Since the loopback
in our multiplexers occurs only in the main transition function, the transcripts
it generates will commit to specific values for the ledger data upon transaction
creation – something which is likely not reasonable. A more complex loopback
design, which we do not present here, would solve this: If calling into public
or private parts of other contracts were permitted from within the public and
private state oracles respectively.
For both leakage descriptors and dependencies, we make use of our assump-
tion that users cannot directly call set.
function descchaindata (t, X, Tσ , Tρ , w, z)
return “Reading the chain data”
function depchaindata (X, Tρ , (σ o , ρo , σ π , ρπ , η))
return 
6
This could be expanded to allow only certain types of setting – such as advancing
the time, but not rewinding it.

80

You might also like