foreign
[Music]
so looking forward to the next talk uh
who is who is here for for zkps
who thinks who thinks
zkps are the greatest things that
blockchains uh ever enabled in the space
in terms of getting it funded
all right all right that's just my
personal opinion though but I think zkps
are actually the the nice thing that
nobody expected coming from
cryptocurrencies but they still happened
uh so next up uh we have Henry de
valence uh the founder of penumbra and
he's going to uh to be talking about
um their experience of building uh a
privacy oh they just disappeared in
front of my eyes because the talk is
starting now but uh Henry's building uh
privacy preserving decks uh using zkp so
please put chance together for Henry all
right
um yeah well uh great to see everyone
um so I'm gonna be giving a talk about
how to build a private decks however
just as a kind of a pre-warning
um if you're really interested in all of
the sort of details of ZK proofs that
actually won't be covered in the talk
and the reason is that I think part of
the problem with deploying zkps for uh
privacy rather than just for scalability
is that there's some interesting and
fundamental challenges in the state
model so that's actually sort of the
whole summary of the talk so to get
started
for context so I'm working on a project
called penumbra what that is is a
private proof of stake L1 inside of that
L1 we have an interchange shielded pool
so you can take any IBC compatible asset
moving into this chain and that's the
Privacy boundary so as it moves in it's
recorded in this shielded pool
and the cool feature that we have is
this private Dax that's integrated with
that shielded pool on top of that
privacy preserving base layer
however
um I'm not sort of here to just you know
chill the project I'm here to talk about
the kind of technical aspects and
specifically what are the challenges to
actually building this system
so the first challenge is oh sorry uh so
just as as a bit of motivation right
like why do we actually care about
having
um a private decks in the first place
um the the thought is that every Market
is also a marketing information when we
talk about price Discovery for instance
you can think of that as being a kind of
decentralized computational process that
as a side effect produces some
information about prices
but that means that information leaks
are value leaks when people talk about
Mev and have these you know dashboards
of here's how much value is extracted
from people who are trying to do trading
really that's just the sort of first
order symptom of this problem it's not
even if you fixed Mev in some way
um
you still have the problem that you're
you're leaking information about what
trades are doing what trades your
account has done your entire history of
your whole trading strategy all of that
information is valuable too it's just
harder to make a dashboard of it
so the the thought here is that privacy
is a really interesting thing for uh
trading because trading is a context
where having privacy allows you to
unlock greater Capital efficiency and as
somebody who's really interested in
privacy you know for its own sake as a
value as a human right Etc
um this is a really interesting and
exciting uh
opportunity because it means that
there's the potential to build a private
product that can actually out compete
the non-private ones because it's
private so we we get out of this mode of
like oh well we'll you know have people
accept all these trade-offs to use the
private thing no we're going to build
something that's that's better because
it's private so right I said I was going
to talk about the challenges and the
first challenge which is the most
fundamental is actually the state model
so if we consider a transparent chain
like ethereum the the Paradigm of that
state is global mutable State there's
like one big ethereum state and every
transaction is applied sequentially and
it can do whatever mutation to that
state and as it's doing that mutation
effectively it's taking like a global
lock over the whole state
doing some changes then you do the next
transaction and so on
but in order to have a shielded chain
where the user state is not public
information we have to change the state
model to a model of immutable composable
State this is actually kind of like
historically speaking this is sort of
rewinding to a Bitcoin style sort of
utxo model but I think utxo is a little
bit of a loaded like baggage Laden term
so I prefer just having this idea of a
state fragment and instead of having one
big Global State we're going to have a
tree of State fragments which are
immutable and each transaction is going
to consume some State fragments produce
some new ones and put those you know
append those into this tree
the reason that we want to do this is
that that way we can make the state
transitions private and the move to do
that is you replace all of those State
fragments with cryptographic commitments
to States and then in your transaction
rather than explicitly declaring the
plaintext values of those State
fragments you can just have a ZK proof
that the state transition was valid and
here are the commitments to the new
states that I produced okay so this is
all cool and that's why everybody's like
using like private blockchains all the
time no why is that because that diagram
isn't quite right in fact what you're
submitting to the chain is this ZK proof
pi that represents the state transition
but what we've actually done is we've
moved all of the execution off chain
along with moving all the user data off
chain right but now we don't really have
any way to access any shared State
because when somebody's submitting their
transaction effectively every
transaction is is its own little micro
Roll-Up
and what I would claim is that the key
problem here is is one of early versus
late binding so what we have in this
sort of ZK model is early binding every
transaction has to have this fully
sealed complete State transition but
that's not actually what we generally
want right if you make a trade on
uniswap you're not going to sign over
here's the exact State of the Union
reserves of this contract here's the
exact outputs that I'll get because
the only way that you could do that is
by sort of having the entire world stop
while you you know submit your
transaction right what we want is the
ability to have a partially filled
transaction where we can have some
placeholder values where when the
transaction is executed the the shared
state is going to go in that spot and
then it'll determine some outputs
um so
in order to make this work with the sort
of ZK model where we're keeping all of
the user data off chain we need to have
some better concurrency model for shared
state right fundamentally the problem is
that if you're doing this off chain
execution you need to have some kind of
like exclusive control over the the data
that you're executing on and you can
start with the kind of oh well we'll
take a big Global lock and you can make
the locks you know smaller but
the the more interesting idea I think is
what if we try to model concurrency with
message passing rather than locking if
you look outside of blockchains that
just kind of like normal you know high
performance High concurrency software
systems
um
you can do better by having finer
locking but a cleaner and more scalable
approach is to have different parts of
the system executing independently with
their own State and passing messages
back and forth to each other so what
would that look like in the context of
trying to build a privacy preserving
chain well we could try to think of this
kind of actor model for chains where a
transaction rather than synchronously
doing a contract call where it locks
some state does some execution and then
finishes and releases the look we could
say that the transaction is going to
pass a message to a contract
and now we're going to have each
contract execute once per block but as
it executes it's going to receive the
set of all of the messages that any
transaction passed to it and it can
process those all in a batch and
depending on you know the specifics of
that contract logic in some cases you
know you could combine all of those
messages into one right like you could
do a batch swap which I'll get to later
on in the talk but also you could
imagine say like an auction protocol
that orders these messages by the the
bid amount
um and the key thing is that you're not
doing any execution at a higher time
resolution than is actually provided by
the underlying consensus right when
people talk about transaction ordering a
lot of the problems arise from this
mismatch between the economic mechanism
and the contract which is trying to
execute at this sort of faster than
consensus speed and the actual you know
consensus ordering guarantees that are
provided by the blockchain which happen
block by block right like if you're
agreeing on transactions in in batches
like maybe you should also be executing
them in batches
um and on the other hand our our per
user State we can still have this sort
of off-chain uh execution but now the
execution is going to be asynchronous
right when I consume my state and I pass
a message to a contract I can't compute
my outputs yet because I haven't got a
message back so I need to somehow record
this sort of intermediate future
that represents the eventual result of
the computation that I'm going to be
doing but I can do all of the uh all of
the computation that is only touching a
particular user State can happen off
chain uh privately in ZK so the really
interesting thing about this model is
that it actually simultaneously unlocks
both scalability and privacy because all
of the data that doesn't need to be
having any shared execution is happening
that execution is is happening on each
individual user's client
and the on-chain data is limited to the
minimum uh shared computation and it's
executing in a batch so you can
potentially have a much more efficient
implementation so to see kind of how
this works in a in a diagram uh which I
think it might be a little bit more
clear we're going to start off with our
first uh you know somebody's preparing a
transaction they're going to perform a
state transition and produce a ZK proof
of it with their private inputs
and that transaction is going to send a
message out to this contract
what it's going to record as the output
of that initial transaction is actually
a privately minted state nft
which commits to the Future that this
computation is supposed to be uh
representing so now this user has this
in this diagram this is the the Diamond
is this nft that records the kind of
intermediate state of their per user
computation
after they send that all out to the
chain it's included in a block
the chain is going to send a message
back by publishing data to the the chain
or the contract's going to send a
message back by publishing the data to
the chain and
we take that message from the contract
combine it with our intermediate
execution state we're going to burn that
state and inside of this ZK proof we can
now prove that we've you know modeled
the correct future with the correct uh
you know same input values that we had
committed to in the first transaction
and now we can privately mint some
outputs
so this is this sort of big picture
diagram of how this sort of async ZK
execution can work
um in principle
um and we'll get to a concrete example
of how that works out for the case of
doing batch swaps but before that I just
want to get into this second challenge
which is
um once you have an idea of okay we have
maybe a workable State model but what is
the Privacy model right
and
the the claim here is that basically
every useful blockchain revolves around
public shared State that's why you know
for instance ethereum is valuable
because it has everybody's state in it
and it's all there
um so the idea of like oh well we're
gonna just like make everything private
and like everything will be completely
private doesn't actually work because in
fact like the reason that we're we're
using the coordination tool is so that
we can coordinate nobody wants to use a
market where they have no idea what the
liquidity is or what prices they might
get or you know what the volume is
um
and all of the
the sort of big breakout successes uh
of of useful contracts have the
contracts uh public shared State acting
as this kind of universal counterparty
so you don't need to go and find some
some person to interact with you can
just interact with the chain so we need
to have public shared state but you know
maybe we want it to be private so what
what does that mean exactly right this
question the question is like how do you
allow private interaction with public
shared State
um we want to have uh some kind of
notion where the individual users
transactions have privacy but all of the
aggregate state of the chain like you
know all of the aggregate Market data is
public but the individual users trades
are not so here's two basic strategies
of how you could have a private
interaction with public State one is
splitting flows and the other is
batching flows when I say flow the
reason I use that word is that I think
of
um you know value being in in different
sort of pieces of the chain State and as
people do things you're going to have
flows of value between different
portions of the chain State and we want
to have some kind of system where people
can have privacy about what their
contribution to that specific flow is
but still have a sort of overall
um
a transparent aggregate
so looking at these two in turn
for splitting flows the idea is that
we're going to start off with some users
value that you know this maybe this is
an amount that they want to trade they
can split that into randomized sub
amounts and then reveal each of those
sub amounts in distinct transactions and
then
reunify them later so this method only
works if you have a shielded base layer
if you have a transparent based layer
then this like is trivially broken
because you just like look at what the
account was and then you can see what it
did but if everything else is private
and you're only revealing like here is a
specific amount that I'm sending to this
part of the system like this is a a
public delegation amount to some
validator this is like an amount in in
one sort of randomized sub trade this
might be okay and it's a it's a fairly
practical and simple thing however it's
it's not really ideal so the other
strategy which is more interesting and
more cool is this idea of batching flows
so if we know that we're already going
to be processing uh uh the contract
state in batches it would be nice to
have a way to batch up flows
um we do this using a construction that
we we're calling flow encryption which
is effectively
additively homomorphic threshold
encryption uh with sort of end-to-end
verifiability once you've tacked on you
know six different properties you might
as well give it a distinct name
but the idea is that each individual
user with their you know distinct
contribution to this flow can encrypt an
integer amount
uh include that in their transaction and
then the validators can sum up those
encryptions and decrypt only a batch
total
um so that there's the batch total and
the idea is that now you can use that as
the input to some public on-chain
computation but still have long-term
privacy for individual transactions you
know as long as the the batch size is is
big enough as an example if you're
trying to have
um you know a a delegated proof of stake
system you could make it so that oh the
validator weights will change you know
in each Epoch and we'll just sum up all
of the the delegations or undelegations
in each Epoch and only reveal the net
change
um so these are sort of the the two
pieces let's see how this kind of works
out uh as a as a concrete worked example
um which is doing sealed input batch
swaps on penumbra
um so looking first at the private State
part right remember that we have this
model where we explicitly segment away
the per user private state from the
shared public state
we're going to start off with okay
here's the the private input for this
trade that a user wants to make they're
going to encrypt that input include that
in their transaction the rest of the
transaction right is is totally shielded
because we have this shielded base layer
so there's no Public Accounts or any
other metadata in the the transaction
and what though meant in that swap
transaction is a swap nft where the the
asset ID of that uh nft is a snark
friendly hash of their input trade
amounts the trading pair their you know
the address that they're going to Mint
the funds to some prepaid fees uh and as
this transaction that they submitted is
included in a block it gets batched
together with the others
decrypted you send that into the Dex
engine which resolves all of the trade
intent and publishes the output data
into the chain State and now that user
can consume their swap nft which
remember is modeling this sort of future
that resolves eventually to their swap
outputs
and produce a proof that uses these uh
public back swap data as a public input
and their swap nft is a private input to
privately mint their correct prorata
share of the batch Swap and so
that that means that that individual
user's output can be minted completely
privately and as long as you have
sufficient uh
uh sufficient volume in in the batch
um you can get long-term privacy for
individual users trade amounts now if
you're on say like a thinly traded uh
pair maybe you end up in a badge size of
one but in that case you can use this uh
sort of randomized splitting technique
that I mentioned earlier to make
effectively a kind of like randomized
t-wop of your trade
so zooming out of the the private State
part to how this works on the public
State Side
um we have all of these uh
uh all of these swap transactions that
have been included in the the block we
have the Dex engine group all of those
inputs by pair we do this batching and
decryption but now at this point we we
don't just have you know a single
swap we don't just have a single Swap
transaction on a single pair we have a
complete picture of here's all the
trading intent
uh for the entire chain in this block
and we also know that we only have to
run the Dex engine once per block
because we're in this batched
computation model so that means that we
can actually be you know considerably
more sophisticated in how we resolve
these trades we can load up the entire
liquidity graph of all of the assets on
the Chain sort of put the trade intent
into the correct spots on that graph and
then compute uh some optimal resolution
of all of these trades simultaneously so
you can do some kind of global
resolution of the trading intent do
optimal Arbitrage and this is
computationally tractable to do just
like in consensus because you know that
you're only doing this once per block so
you you end up in a model where rather
than sort of having to call each
contract you know potentially like
thousands of times a block you just know
that the chain is going to step in
discrete time from one set of consistent
prices to a new set of consistent prices
you can handle all of the uh newly added
or removed liquidity also in a batched
way right so you first add all of the
newly created liquidity then you resolve
all of the trading tent then you are up
all the prices to be consistent with
each other then you close all the you
know closed positions and this also lets
you as a side effect have like single
block uh
jit liquidity uh with the kind of like
batch semantics so there's a lot of
really interesting pieces of Market
design that get unlocked by this model
um so that's basically the content of
the talk if you want to play with this
we have some weekly test Nets that you
can you know play around with here's a
bunch of links
um
so far uh the the big last sort of piece
to build is the the actual Dex engine
but we have a toy uh amm that you can do
these shielded swaps against uh on our
test net so that's a talk if anybody has
any questions
happy to get into it
[Applause]
uh just wait for the mic please I'll run
to you with the mic
thanks for the talk uh just curious so
have you found a tight Bound for how
much of a loss you have when you provide
batching because if it's the content
function Market maker there's a loss in
what sense uh so you're going to get an
average you're smoothing it out in that
sense of speaking so you can actually
have a spike in a block you're just
averaging
so have you done an announcements I did
some analysis so I'm curious if you have
done that so I guess the question that I
have is like a loss relative to what
right assuming no private so two volts
same block private versus non-private
uh
uh I'm no okay
do we have more questions yeah they're
not sure who was first sorry
just a quick one thanks very much for
the talk this is fantastic to hear and
to get uh this content and this
all right quick question on reverts the
whole batch reverts all right so I
missed that on revert the whole batch
reverts
if a transaction reverts oh objection is
not valid yeah so
um it's possible for instance that
someone could submit a transaction that
say you know they submit a trade for a
trading pair that doesn't have any
um liquidity on it right so one of the
outcomes of the the batch swap is that
the the trade can fail and in that case
rather than having people privately
meant their Pro rata share of the
outputs they privately meant their Pro
rata share of the inputs they get their
their funds back
uh yeah so the whole batch goes goes at
once so like technically I guess you
could have some kind of griefing attack
where someone is like continually
locking up capital in trying to like dot
prevent other people from Trading by
submitting a giant whale trade but like
they can't actually do that without
running the risk that like someone will
provide liquidity at a bad price so I
think it's probably not a big deal
right the time is off well
one more round of applause forehand
really please
thank you Henry