Registration/Deregistration: Intially, as in Ouroboros-Genesis, then call Initialization-Crypsinous(Up,sid, R), returning the result.
Interacting with the Ledger (cf. Section 6.4):
Upon receiving a ledger-specific input I ∈ {(submit, . . .),(read, . . .),(maintain-ledger, . . .)}
verify first that all resources are available. Ifnot all resources are available,then ignore the input;else execute one of the following steps depending on the inputI:
IfI = (submit,sid,(public,transfer)ktx) thenset invoke the protocol
SubmitXfer(tx,Cloc,log).
Else ifI = (submit,sid,tx) thenset invoke the protocolSubmitGeneric(sid).
IfI = (maintain-ledger,sid)then invoke protocol
LedgerMaintenance(Cloc,C, Up,sid, k, s, R, f,log); ifLedgerMaintenance haltsthenhalt the protocol execution (all future input is ignored).
IfI = (generate,sid,tag) then
• If tag=coin, queryGclock for the current timeτ. Then, sample skcoinτ ← {$ 0,1}`PRF,
and let skcoini+1 ←PRFevlski(1), fori∈ {τ+ 1, . . . , τ+R}. Letrootcoinsk be the root of the Merkle tree over skcoinτ , . . . ,skcoinτ+R, and pkcoin←PRFpkrootcoin
sk
(τ). Insert the Merkle tree
into Cfree, and return pkcoin.
• If tag=id, and this is the first query for id, send(KeyGen,sid) toFFwEnc. Denote the
response by pkenc. Recordpkenc, then return it.
• Otherwise, return a uniformly sampled value from{0,1}κ.
IfI = (read,sid)then invoke protocolReadState(k,Cloc, Up,sid, R, f,log).
Handling external (protocol-unrelated) calls: as in Ouroboros-Genesis.
Protocol Ouroboros-Crypsinousk(Up,sid)
The following steps are executed in an (maintain-ledger,sid)-interruptible manner:
1: Use the clock to updateτ, ep← dτ /Re,and sl←τ.
2: ifτ = 0 thenexecute the following steps in an (maintain-ledger,sid)-interruptible
manner:
3: Send(claim, sid, Up)toFINITto claim stake from the genesis block, receiving the response
(pkcoin, ρc, rc, vc), andskcoin.
4: Let C← {(pkcoinc , ρc, rc, vc)}, and Cfree← {skcoin}
5: Send(clock-update,sidC) toGclock.
6: Use the clock to updateτ, ep← dτ /Re,and sl←τ, and give up the activation.
7: while τ = 0 do
Use the clock to updateτ, ep,and sland give up the activation.
end while
8: else
Send (genblock_req, sid, Up) to FINIT. If FINIT signals an error then halt. Otherwise,
receive from FINIT the response(genblock, sid,G= (C1, η1)). 9: Set Cloc ←(G).
10: Send(new-party,sid, Up)toFnew N-MC.
11: Returnpkcoinc .
end if
12: Setton ←τ. 13: Return ∅.
Global variables: The protocol stores the list of variables pkenc, τ, ep, sl,Cloc,C,Cfree,ton to make each of them accessible by all protocol parts.
Protocol Initialization-Crypsinous(Up,sid, R)
C.2 The Staking Procedure
The following steps are executed in an (maintain-ledger,sid)-interruptible manner:
1: for(pkcoinc , ρc, rc, vc)∈C do
2: if c is not eligible for leadershipthen continue
3: Send(eval,sidRO,noncekηepksl))toGRO, and denote the response µρ. 4: Send(eval,sidRO,leadkηepksl))toGRO, and denote the response µy. 5: Lookup skcoinc,τ ,rootc, and τcin Cfreecorresponding topkcoinc .
6: Let ρ←µrootskcoinc kρc
ρ ;y←µ rootskcoin c kρc y 7: if y <ord(G)φf(vc) then 8: repeat
9: Parsebuffer0 as sequence
(tx1, . . . ,txn)
10: fori= 1 tondo
11: if ValidTxOP(txi, ~st||st) = 1 then
12: N~ ←N~||txi
13: Removetx from buffer0
14: Setst←blockifyOP(N~)
end if end for
until N~ does not increase anymore 15: Setptr←H(head(Cloc)); h←H(st)
16: Setρc0 ←PRFevlroot
skcoinc (ρc);snc←PRF sn rootskcoin
c
(ρc) 17: Set(cmc0, rc0) =Comm(pkcoinkvckρc0).
18: Let stx~ref be, in order, the list of leadership transactions made by Up not in Cloc.
19: Letroot be the root of the Merkle treeClead inCloc, after applying all transactions in
~
stxref. Letpathbe the path to cmcin the same Merkle tree.
20: Let pathc be the Merkle path toskcoinc,τ in the secret-key Merkle tree.
21: Let x= (cmc0,snc, ηep, sl, ρ, h, ptr, µρ, µy,root). 22: Let w= (path,rootskcoin,pathc, τc, ρc, rc, vc, rc0).
23: Send(prove,sid,x,w) toFNIZKLlead, and denote the response π.
24: Let txlead = (lead,stx~ref,(cmc0,snc, ep, sl, ρ, h, ptr, π)). 25: SetB ←(txlead,st);Cloc← ClockB.
26: Updatec: C←(C\ {(pkcoinc , ρc, rc, vc)})∪ {(pkcoinc , ρc0, rc0, vc)} 27: Send (multicast,sid,txlead) to Ftx
N-MC and proceed from here upon next activation
of this procedure.
28: Send(multicast,sid,Cloc) toFbc
N-MC and proceed from here upon next activation of
this procedure.
29: break
end if end for
30: while A(clock-update,sidC) has not been received during the current rounddo
Give up activation. Upon next activation of this procedure, proceed from here.
end while
C.3 The Ledger Maintenance Procedure
The following steps are executed in an (maintain-ledger,sid)-interruptible manner:
1: ExecuteFetchInformation to receive the newest messages for this round; denote the output by(C1, . . . ,CM),(tx1, . . . ,txk), and read the flagwelcome.
2: ifwelcome= 1then
3: Send(multicast,sid,Cloc) toFbc N-MC.
4: for each tx∈buffer do
Send(multicast,sid,tx) toFtx N-MC. end for
end if
5: fortransaction tx∈(tx1, . . . ,txk) do
6: if tx is a transfer transactionthen Protocol LedgerMaintenance(. . .)
7: Attempt to decrypt each new ciphertext c by sending (Decrypt,sid, c) to FFwEnc.
Receive the response m.
8: ifm= (pkcoin, τ, ρc, rc, vc)∧cmc∈tx then 9: if@skcoinτ ∈Cfree corresponding topkcoin
10: then continue
11: LetCcnd←Ccnd∪ {(pkcoin, ρc, rc, vc)}. 12: Letlog←logk(tx,receive,(pkcoin, vc)).
13: end if
14: else if txis a generic transaction then
15: Attempt to decrypt each subtransaction ciphertext c by sending (Decrypt,sid, c) to
FFwEnc. Receive the responsem.
16: if m6=⊥thenlog←logk(plaintext, c, m)
17: end if
18: end for
19: for coin(skcoinc , τc)∈Cfree do
20: if∃ a coin forpkcoininCcndwhose transaction ∈ C dk
loc then
21: Move such candidates to C.
22: end if
23: Erase skcoinc,τ (and for any time before τ) from Cfree.
24: end for
25: Use the clock to updateτ, ep← dτ /Re,and sl←τ.
26: Setbuffer←buffer||(tx1, . . . ,txk),ton ←τ,N ← {C1, . . ., and CM} 27: Invoke ProtocolSelectChain(Cloc,N, k, s, R, f).
28: UpdateFFwEnc as many times as necessary for its time to be a leastτ −k.
29: if twork< τ then
30: Invoke protocol StakingProcedure(k, Up, ep, sl,buffer,Cloc,C) (in a (maintain-ledger,
sid)-interruptible manner).
31: Settwork←τ and send (clock-update,sidC) toGclock.
end if
C.4 Submitting Transfer Transactions 1: Let((pkencr ,(pkcoinc4 , v4)),(pkencs ,(pkcoinc1 , v1),(pk
coin
c2 , v2),(pk
coin
c3 , v3)))←txxfer. 2: ifpkencs 6=pkenc orv1+v2 =6 v3+v4 orpkcoinc3 ∈/Cfree then return
3: CheckCfor the first coin received at ID pkcoinc1 ,pkcoinc2 . Ensure they have valuev1 andv2 respectively, and denote their (potentially evolved) variant as c1 and c2. Ensure these are inClocdk.
4: As a special case, allowpkcoinc2 =⊥, and v2= 0.
5: ifthese do not exist, or are not in Cthen return 6: Retrieve the corresponding(pkcoinci , ρci, rci, vci) from C. 7: Lookupskcoinci inCfree fori∈ {1,2}, corresponding topkcoinci . 8: ifpkcoinc2 =⊥, and v2= 0 then snc2 ←PRF
zdrv
rootskcoinc1 (ρc1) and all other values forc2 are zeroed.
9: Sampleρc3, ρc4 $
← {0,1}`PRF.
10: Commit (cmci, rci)←Comm(pk coin ci kvikρci), fori∈ {3,4}. 11: Letsnc1 ←PRF sn rootskcoin c1 (ρc1);snc2 ←PRF sn rootskcoin c2 (ρc2) 12: Extract the statest~ fromCloc.
13: Letroot be the transfer Merkle tree root in Clocdk.
14: Letpath1 and path2 be paths tocmc1, and cmc2 in the same Merkle tree, respectively, or, if
pkcoinc2 =⊥, and v2 = 0, let path2 be empty.
15: ifeither are not found in the Merkle tree then return 16: Letx←({cmc3,cmc4},{snc1,snc2}, τ,root).
17: Let w ← (rootskcoin
c1 ,pathskcoinτ,c1,rootskcoinc2 ,pathskcoinτ,c2,pk
coin
c3 ,pk
coin
c4 ,(ρc1, rc1, v1,path1),
(ρc2, rc2, v2,path2),(ρc3, rc3, v3),(ρc4, rc4, v4)). 18: Send(prove,sid,x,w)toFLxfer
NIZK, and receiveπ.
19: Send(encrypt,sid, τ,pkencr ,(pkcoinc4 , τ, ρc4, rc4, vc4)) toFFwEnc, and receivecrcpt. 20: Letstxproof ←({cmc3,cmc4},{snc1,snc2},root, π).
21: Lettxreal
xfer←(transfer,stxproof, crcpt).
22: Letlog←log\
(pkcoinc1 , vc1),(pk coin c2 , vc2) . 23: Erase c1,2: C←C\ {(pkcoinci , ρci, rci, vci)|i∈ {1,2}}. 24: Record c3: Ccnd←Ccnd∪ (pkcoinc3 , ρc3, rc3, vc3) 25: Send(multicast,sid,txrealxfer) toFtx
N-MC.
C.5 Submitting Generic Transactions 1: Lettxreal=generic.
2: foreach stx∈tx in order do
3: if stx= (>, M) then
4: Lettxreal←txrealkstx.
5: else if stx= (pkencr , M)then
6: Send(Encrypt,sid, τ,pkencr , M) toFFwEnc, and denote the response c.
7: Lettxreal←txrealk(⊥, c). end if
end for
8: Send (multicast,sid,txreal) toFtx N-MC. Protocol SubmitGeneric(tx)
C.6 Reading the Ledger State
1: ExecuteFetchInformation to receive the newest messages for this round; denote the output chains by(C1, . . . ,CM) (the list of transactions (tx1, . . . ,txk) and the flag welcome
can be ignored).
2: Invoke protocolUpdateTime(k, Up, R, f) and denote the output as τ, ep, sl,Sep, αepp , Tpep, and ηep.
3: Use the clock to updateτ, ep← dτ /Re,and sl←τ. 4: Setton ←τ,N ← {C1, . . . ,CM}.
5: Invoke ProtocolSelectChain(Cloc,N, k, s, R, f).
6: Extract the statest~ from the current local chainCloc.
7: Letst~ideal =.
8: foreach tx∈~stdk in order do
9: if tx= (transfer,stxproof,stxrcpt) then
10: Letstxchng←stxrcpt ← ⊥.
11: if∃v: (tx,receive, v)∈log then 12: Letstxrcpt←(Up, v).
13: end if
14: Letst~ideal←st~idealk((>,transfer),stxrcpt,stxchng).
15: else if tx= (generic,stx1, . . . ,stxn) then
16: Lettxideal←.
17: foreach subtransactions stx∈txin order do
18: ifstx= (>, m) then
19: Lettxideal ←txidealk(>, m)
20: else ifstx= (⊥, c) then
21: if ∃m: (plaintext, c, m)∈log then
22: Lettxideal ←txidealk(Up, m)
23: else
24: Lettxideal ←txidealk ⊥
25: end if
26: end if
27: end for
28: end if
29: Let st~ideal ←~stidealk(txideal).
30: end for
31: Output(read,sid, ~stideal).