foreign
[Music]
welcome back
um our next speaker is Chance Hudson and
he'll be talking about how to build an
identity ecosystem on unirp and unirp
itself is an anonymous reputation system
so chance
thank you
all right so thank you all for being
here
um oops I'm excited to talk to you guys
today about a protocol I work on called
unirp
so before we get into it this is a quick
road map of how this presentation is
going to go first I'm going to give a
semi-technical overview of what unit
protocol is then I'll talk a little bit
about improving the user experience of
ZK and blockchain applications in
general and then I'll talk a little bit
about how we can scale ZK on the
blockchain and sort of where we're at
with the capacity right now
right so let's dive into it uh unirp is
short for Universal reputation and you
can think of it as two different things
first it's an identity system that gives
you anonymity and it does this by
creating public keys that change over
time the second component is this
attestation system uh within the system
we have a testers which you can also
think of as applications or just smart
contracts and these are testers give
reputation to users and you can think of
an attest or to reputation like erc20
contracts to tokens they create the
system to find how the reputation is
distributed and spent and destroyed and
everything like that
and so we Define reputation as two
different integers uh positive and
negative reputation and we do this so we
can represent negative reputation like
net negative reputation in CK proofs and
in smart contracts without having to
deal with assigned integers or wrapping
around unsigned integers or anything
like that
so that's one component of the user
State the other is this graffiti value
which the uh the a tester can use for uh
anything in anything they want to within
the application and this is just 32
bytes uh and yeah the assessor can use
it as they like and so one example use
case of this is and a tester can allow
users to register a username and so the
user requests a username and then the
tester attests giving the hash of the
username as graffiti to the user now
when the user takes an action or makes a
proof they can prove the pre-image of
the graffiti and move from anonymity to
pseudonymity so that's one example use
case that's relatively simple a more
complex example would be storing the
state route of a Merkle tree inside of
this graffiti and then the attester can
extend the ZK proof system to prove
things about the contents of that tree
that's in the graffiti so for example
they could use an incremental Merkle
tree to give achievements to the user or
to track actions the user has taken
anything like that so very extensible
system
so the two main properties of unirp are
anonymity and non-confidentiality that
means we can see everything that's
happening inside of the system how much
reputation is being transferred and
whatnot but we don't know who's doing
what
so let's talk a little bit about the
unirap identity system we build on top
of a system called semaphore which is
also developed by the privacy and
scalability team
uh and with some before we have this
public private Key System that's the
most simple explanation it has two
Secrets a chapter and a nullifier and we
defined a public key as the hash of the
hash of those two secrets we also call
this an identity commitment in semaphore
talk and we use the Poseidon hash
function to calculate these values which
makes it a ZK friendly protocol and that
means that you can extend it to do
arbitrary things so so in this example
we have just a public private key system
which isn't particularly useful but
using a ZK proof you could extend it to
do signatures for example by writing a
proof that proves the secret values as
well as the hash of some data that you
want to assign uh yes you can extend ZK
proofs in our in arbitrary ways like
this
another way you can extend it is by
building something like unirap so we
have these public keys that change over
time and we call these epoc keys because
they are valid for the length of one
Epoch uh and this is some amount of time
that is set by the tester in question
and so the epoch key is the hash of the
nullifier the tester ID Epoch and Knots
and so as you can see because the epoch
is part of the hash it changes uh every
epoch we also have this nonce value
which is a value between like one and or
zero and two by default and it allows us
to give the user multiple Epoch keys for
a single Epoch so if your user wants to
commit an action and then wants to give
it another action but doesn't want to
link their identity between uh the two
keys they can use different epochies uh
and still be able to prove the same
amount of reputation and whatnot and
just like some of our this system is ZK
friendly and therefore extensible so if
you want to make a signature system
using these epochies you would use the
exact same approach where you prove the
proof control of the nullifier and the
public signals and then you pass in
whatever you want to hash and it all
gets output
yeah so now I want to talk a little bit
about data structures that we use in
unit so we have like this identity
system but how do we assign reputation
and graffiti to users in the system and
then like continue to prove it
so we really have two structures
um we have this state tree first which
controls uh or measures whether or not a
user is a member of the current Epoch
and as you can see it's an incremental
Merkel tree that we store completely on
chain and the the leaves themselves are
the hash of this private identity
nullifier the tester in the epoch and
then the reputation the user has at the
start of the epoch so this tree control
or this tree has leaves that a user
inserts into when they join the current
Epoch so for example when a user signs
up we insert a leaf or the the user
makes a ZK proof and then creates a leaf
with zero positive and negative
reputation because they're just joining
the system so they start with zero
the other structure we have is what we
call an epoxy so the state tree tracks
the starting ballots for the epoch and
the epoch tree uh tracks the amount of
reputation that was received during the
epoch and as you can see it's a sparse
Miracle tree and we store only the root
of this tree on chain and we use ZK
proof's off chain to insert and update
leaves in the street and then we just
post the new route along with the ZK
proof to the chain
and you can see that the leaf values in
this tree are the hash of the total
reputation owned by this Epoch key
and so we determined the index of the
user's Leaf in the tree in the tree
using the epoch key so in the previous
slide you saw that the epoch key is just
smash of some arbitrary data and we're
able to uh apply or were able to
determine a leaf in the tree by taking
the modulus of that hash uh across the
the number of leaves in the tree so if
we use this exact tree we would take the
hash modulus two to the third because
it's only three levels deep but of
course if we did that we would have lots
of collisions so when we operate this
tree in production we use a depth of 128
so we take the hash modulus 2 to the
128th and now everyone gets a unique
Epoch key and we have 128 bits of
collision resistance
so the whole idea behind unirp is users
have these identities
um for that are valid for an Epoch and
then at the end of that Epoch they pack
up their reputation and they move to a
new identity and the next Epoch by
inserting a leaf into the new state tree
uh I didn't say this before but we have
a copy of these trees every Epoch that
we that we use
right so let's change gears a little bit
and talk about the user experience for
uh zero knowledge applications so we
have these proofs with unrap and we want
the users to be able to uh make these
proofs inside of like their browser for
example on a computer
so here we have a graph of the proving
time for proofs of various sizes on a
few different devices and yeah you can
read it pretty well uh so you can see
that there's a sweet spot below 30 000
constraints where any proof you make is
going to take less than five seconds on
most modern devices that purple line at
the top is uh an iPhone from like 2016.
so like older mobile devices can still
do that in less than 10 seconds which is
pretty acceptable performance
so where's unirup where where are our
proofs on this graph
the first proof we have is a sign up
proof it's very small it's 700
constraints and all it does is output a
hash value so less than one second
a little bit bigger we have an Epoch
keep proof this proves control of an
Epoch key and also proves a leaf in the
state tree so it's a little bit bigger
3000 constraints still less than one
second on most devices and way over here
we have this user State transition proof
and in this proof we add up the value in
the state tree leaf as well as the
values in all of the epoch tree leaves
and output a new state tree leaf with
the sum of the reputation the user owns
so we have to do multiple inclusion
inclusion proofs over trees that are
quite large but we still end up with
about 29 000 constraints so less than
five seconds on Modern devices and we
can also execute this proof in the
background so the user doesn't have to
know about it and doesn't have to wait
right so I think a good goal for zika
applications and for blockchain in
general is users not being aware that
they're using the blockchain while
they're using the blockchain so a lot of
you probably use websites or
applications like Spotify or Twitter or
Reddit or stack Overflow uh just raise
your hand if you know what kind of
database those applications are using
right no one raised okay one person
raised their hand we have at least one
nerd in the crowd but for the most part
users don't really care about the data
structures that are backing the
applications they're using and
blockchains are really the same they're
just databases with different properties
and so the user shouldn't have to be
aware that they're using the blockchain
so this is the the architecture of a
traditional dap and as an engineer I
really like this architecture because
it's simple and it's sort of
unprecedented before blockchain but for
the reasons that I like it I think that
users kind of hate it because they have
to learn about the blockchain and then
they have to learn about wallets like
metamask and transactions and gas and
gas prices and way and ether and they
have to get ether and it's a whole thing
and it's it's a lot for them to learn
just to use a single dab
so luckily if we use ZK identities
instead of wallets we can build this
more traditional three-tier architecture
where we introduce a relay uh that that
bundles the transaction and sends it so
the flow would be the web app generates
a ZK proof gives it to the relay the
relay creates a transaction and then
post it to the blockchain and the
economics of why the relay would do this
are sort of there are a lot of different
schemes you could build like
subscription models or just like free
trial models uh all sorts of different
things you could do and so one one note
about like this architecture the relay
is not a trusted entity uh the Relay can
censor transactions that can go offline
it doesn't matter uh the web applicant
or the user can only send their ZK proof
with a different relay or broadcast it
to the blockchain themselves uh the
relay also can't compromise the ZK proof
itself because if they change anything
about it the proof itself will be
invalid and the proof determines what
the user wants to do on chain
so I think a good goal for this would be
uh from a user experience perspective a
user clicks a button and then in less
than five seconds we show a loading
animation and we generate a ZK proof
give it to the relayer the relay then
packages it into a transaction and gives
it to an L2 node who then returns an
instant finality guarantee and at that
point we can stop the loading animation
on the front end and say okay your
action is complete and even if we get a
weak economic guarantee from this L2
node we can still do this on the front
end and then have an alternate code path
where if the sequencer doesn't include
the transaction we show a notification
saying oh this action failed or do you
want to try again or not and hopefully
that code path is relatively cold and
sequencers include transactions as they
say they're going to
right so how can we build an ecosystem
using like ZK proofs in this sort of
abstracted architecture
uh one approach I think is sort of
detailed in this diagram you can see
there are three different attestra
applications and a user's browser and
each tester application is managing a
unique identity for the user inside of
the browser local storage and the
advantage to this is we can treat these
identities more like web 2
authentication tokens and less like
Bitcoin or ethereum private keys so
instead of prompting the user for
permission to do a signature or make a
transaction we just in the background
make these ZK proofs and give them to
the relayers and at the same time when
we use different identities for each of
these websites if one of the identities
is compromised because the website
injects some malicious JavaScript or
does something like this the damage is
contained to that single a tester
but at the same time we want a testers
to be interoperable so if for example
this to review a tester wanted to get a
proof of from the Cyber resistance
tester how could we do that and the
answer is basically oauth for ZK so for
so in this example flow I'm trying to
sign up for this review a tester and the
reviewer tester wants a proof that I am
a human being in the form of a
reputation proof from this cyber
resistance attester and so in this flow
I create the sine of proof from the
reviewer tester and then I get
redirected to the Cyber resistance to
tester and I get prompted to make a
proof from this identity and in this
case we shouldn't operate silently we
should definitely request that the user
Make This proof because we're going to
hand it to a different third party and
so if the user says yes then we prove
that we have like the reputation and we
sign the hash of the sign up proof to
prove that we're the same person and
then we get redirected back to the the
original application and we can continue
sign up so using this flow we can get ZK
proofs from different applications into
different sort of Origins
okay so this is part three of the
presentation
um how can we scale ZK so first I want
to talk about uh like where we're at
right now and the limitations of our
current infrastructure so when we talk
about scaling ZK there's two limitations
one is the the call data itself and two
is actually executing the verification
on chain so let's talk about call data
first so for graph 16 we have about 130
bytes per proof and for plonk we have
about half a kilobyte per proof so
assume that we're talking about EIP like
a post eip4844 world and we have two
megabytes per block that we can use for
blob data so at that point we're able to
do 1300 across 16 fruits per second and
330 plonkers per second
uh it's not not terrible so let's open
door number two and look at the
verification costs
so across 16 of Planck both cost about
250 000 gas to verify
this isn't totally true cross 16 is a
little bit cheaper and they both scale
up with the number of public signals in
the proof but for this example we're
just going to say they both cost 250
000.
so the ethereum maina is doing two and a
half million gas per second right now
they're doing uh 30 million gas every 12
seconds which comes down to this so it
gets to verify 10 proofs per second on
ethereum Main net
so on arbitrum and L2 for example
they're doing 7 million gas per second
so that number is bumped to 24 proofs
per second
so we see an obvious bottleneck here
it's the verification cost on chain uh
and these numbers are also extreme upper
bounds this assumes that we're filling
entire uh The Blob blocks with two
megabytes of ZK proofs and we're filling
entire blocks with verification of ZK
proofs and not even factoring call data
all right so how can we scale unit up
and how can we scale ZK proofs in
general given those bottlenecks
so this is a proof from the U interrupt
system where we're generating a user
State transition and as you can see
there's I think seven public signals and
for every user that wants to join a new
Epoch we make one of these and put it on
the blockchain and verify it so how can
we make this a little bit more efficient
we can do recursive proofs so we have
the users make a proof and then it gets
sent to an aggregator and then the
aggregator proves that four proofs are
valid and outputs one proof and so we're
able to reduce it by in this case a
factor of four
there are other things we can do like to
reduce the public signals as well like
cue the ZK proofs on chain and then form
a hash chain of the public signals and
the proof stuff uh to reduce it so that
we don't have to Output all these public
signals at once
which will also reduce the verification
cost
and so recursive proving is really
important because it changes the
approach from scaling the throughput of
decentralized network to instead scaling
off-chain computational power which
we're much more able to do like Intel
and AMD do this every year we can also
build Asics to make proof of it make
proofs very quickly and then we're able
to see the sort of uh improvements that
we want to see like if we're able to
bundle 10 proofs at a time we get a 10x
Improvement 100x
Etc
and and this does introduce a little bit
of complexity because we have to deal
with approved aggregator and now the
user potentially has to like wait on
that or potentially optimistically
evaluate the aggregator but this is a
decent approach to scaling
right so now um that's most of the
presentation I'm just going to talk
about like some of my tester ideas that
I think are kind of cool that we can
build with unirp or the other Universe
protocol
so the first is just like ZK Dows we can
keep the balance uh hidden or the
balance controlled by a user hidden
within the Dow we could also do things
like vote for proposals anonymously
um a lot of interesting ideas a lot of
interesting things that can be done with
this
the next is anticipal reputation I use
this as an example in one of the
previous slides but what you could do is
basically take like proofs that you have
a web 2 identity and give reputation for
that or potentially use like bright ID
or or approve that you have like poapps
for example and just get reputation and
then use that to sign up for other
testers
the third is like really simple and
generic which is a recommendation system
as a web app everyone has things that
they use or that they would want to
recommend to other people you having
like reputation for good recommendations
seems like a good use of the system
and then the final one is one that I
thought of when I was given the Devcon
poapp I I really hate claiming co-ops on
chain because I'm just giving people a
history of like the places I've been in
the real world which I think is kind of
weird uh so we can use unirp to like
claim pull-ups anonymously and then we
could make a proof that you have like a
co-op and a set like for example I could
prove that I have two apps from the set
of all Defcon pop-ups something like
that
uh and then just some nice to have
things for sort of the ecosystem like
infrastructure wise the first is like a
ZK directory this just a directory of
the hashes of proofs and human readable
descriptions of what the proofs do and
this would be really important if we're
going to oauth between different
applications and request ZK proofs
because they're potentially requests
just random proofs that are specific to
their application and so applications
should have a place where they can
request information about a proof and
then return it to the user
the next thing is planck we already have
this but I just want to talk about it a
little bit more
um the most important part of Planck to
me at least is we don't have the space
to use trusted setup that is circuit
specific so with unirp we want people to
extend the proofs that we've written and
write their own to build their own
functionality and with Ross 16 that's
very difficult to do because they have
to run a trusted setup ceremony for the
circuits that they build and this is a
huge amount of coordination and effort
can't really expect most developers to
reasonably do so with Planck we cut all
the head out we get to just use some
phase one trusted setup made by some
trusted density or some trusted entities
and then you have secure proofs
and the last thing is easier browser
proofs so we have proofs in the browser
using snark.js but you have to like
configure webpack really specifically
and it also uses like Z key and
webassembly file and a second
webassembly file for a curve and it'd be
much easier if we had a tool that just
sort of bundles all of that into a
single web assembly that we can run in
the browser just pass in signals and get
the proof back this will give us like
three asynchronous operation as well
um yeah it would just be a nice thing to
have
uh yeah that's pretty much the end of
the talk we have a few events happening
related to unirap so first we have a
unwrap workshop on Friday at 10 30 a.m
that's going to be on the first floor at
the ZK Community Hub we also have a demo
at Thursday at three o'clock in the same
place a big thank you to Xerox park for
putting on those events and inviting us
to participate
uh and then if you want more information
about unirp you can go to github.com
unit or you can scan this QR and it'll
take you to our organization homepage
where you can find documentation links
uh links to our Discord and a link to a
demo application that we have running on
this protocol
uh yeah that's it uh any questions
[Applause]
um first of all cool cool presentation
thank you for all the information uh I
was wondering from a product standpoint
or maybe from the user perspective how
do you explain
um the need to sequentially create new
identities
in order to remain anonymous and also if
there's a way to apps like that maybe
save it in the session in the browser
you know appstock the user away from
such a involved mechanism of creating
like a sudden anonymous
name every every Epoch sure
yeah so well the reason we do this is
because they need to have uh they need
to be able to prove a leaf in the epoch
tree to claim reputation uh but I would
say it's not as involved as it might
seem we can do this silently in the
background in the browser so like the
user enters the the web page and then
the web page checks if they need to
generate a new identity and if they do
they generate a ZK proof in the
background and submit it to a relayer
and it's done
um
yeah there's not a way to make that less
manual without changing the architecture
of the system like pretty substantially
though
hello so
how often do you see the state
transition happen is it going to be
peripoc or maybe there can be some
um
tricky there to maybe avoid this
Kevin load in the computation
uh yeah so the state transition happens
anytime you want to move to a new Epoch
so if you are participating consistently
then yeah it's every Epoch we can adjust
or testers can set the epoch length
themselves though so this could be like
pretty short maybe one hour or it could
be like a week or it could be a month or
anything like that and we're also
planning to make it so a testers can set
the max knots value to change like the
number of keys the user has for Epoch so
that would sort of make it so that the
power key proof is longer but you also
have like longer epochs so there's sort
of a lot of tuning we can do with that
okay
any thoughts about using dids and VCC
standards in this implementation uh any
thoughts about using what decentralized
identifiers and verifiable credentials
from the w3c
no um no I have to look into that I'm
not aware of actually that but thank you
thank you
uh quick question you talked about
growth 16 verification after eip4844
um I would be curious to understand if
you have like more detailed thoughts in
particular two questions I was thinking
of those like one uh if you don't have
your uh I guess proof in call data
instead it's in the blob you would have
to verify there's some batch proof right
opening your Kate polynomial inside this
narc and then doing recursive rules or I
guess what is the exact setup you're
thinking of uh do you mean gross16 or do
you mean Planck either one I guess right
so sorry that makes a little bit hard to
hear but it's just like a question about
how do we aggregate these proofs or how
do we sequence them for aggregation
in a post eip44 world right yeah yeah so
I sort of touched on it a little bit but
I didn't talk about it much but one
approach is users can't send the public
signals of the proof and then the hash
of the proof onto the blockchain and
then we form a hash chain on chain and
then the aggregator is able to make a
recursive proof using that data and only
put a hash chain on chain
um but this still involves like the
aggregator receiving the full proof and
then like calculating the hash
um
we honestly we haven't gotten
uh we're not really close to doing that
yet like we're proving especially for
like solidity approvers are a little bit
far out
um but yeah it's probably going to be
some sort of optimistic system so the
user experience is pretty good
thank you thank you all