You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: dart-bp/docs/1.md
+24Lines changed: 24 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -316,4 +316,28 @@ The chain allows 1 public key to have only 1 account per asset-id. This is done
316
316
This is to ensure that a public key can do an accurate proof-of-balance for that asset without hiding any amount of that asset. In the future, we might support asset-id privacy during registration by the chain keeping a commitment of the assets per public key
317
317
and during registration, a proof of uniqueness of the new asset-id against the committed set is provided (likely using a linear cost non-membership proof).
318
318
319
+
320
+
### Workflows
321
+
The system supports 3 workflows for producing the proofs described in the rest of this document. The protocols are largely the
322
+
same across them; the only thing that changes is how secret keys are handled (and consequently how the proving/verification work is split between 2 parties).
323
+
The idea is to use homomorphism of Pedersen commitments, which account commitments are, and split the commitment into two parts - one part containing the secret keys
324
+
and other part without them. Each party does its proof over its corresponding part and the verifier "combines" these 2 parts appropriately. Sometimes the parts can
325
+
just be added by the verifier to form the final commitment. However, sometimes revealing the parts can leak information so both parties blind their commitment with cancelling
326
+
randomness, i.e. $r$ and $-r$ which hides each commitment but during "combining", it cancels out.
327
+
328
+
1.**W1 (Solo)**: A single prover holds all witnesses, including the secret keys $sk$ and $ek$, and produces the whole proof on its own. The protocols in the remaining sections are written assuming W1.
329
+
330
+
2.**W2 (Parallel)**: Two provers — a device (e.g. Ledger) which holds the secret keys, and a host (the user's computer) which does not. How the commitment gets split depends on whether $AK$ and $EK$ are revealed for the transaction:
331
+
332
+
-**When $AK$ and $EK$ are revealed** (account registration, minting): they become public to the verifier, so the device just proves knowledge of $sk, ek$ in $AK = sk.G_{Aff}$ and $EK = ek.G_{Enc}$, and the host's part can have these subtracted out.
333
+
-**When $AK$ and $EK$ stay hidden inside the account commitment** (fee payment, transparent deposit/withdraw, affirmations): the device's part carries the secret-key terms together with a share of the commitment randomness, and the host's part carries
334
+
everything else with the complementary share. Leg ciphertexts in affirmations are split the same way - the device contributes the $ek^{-1}$ and its proof and the host contributes the plaintext component ($amount$, $asset\_id$), its proofs, range proofs,
335
+
curve tree membership proofs and other relations which use Bulletproofs. Thus all heavy lifting is done by the host.
336
+
337
+
The two proofs run independently and in parallel, bound together by feeding the same nonce/context and the same public inputs (account commitments, nullifier, re-randomized leaf, leg ciphertexts, etc.) into both transcripts. The exact split is described in each protocol's section.
338
+
339
+
3.**W3 (Sequential)**: Same split of work as W2 between device and host, but ordered. The host runs its pre-challenge phase first: it commits to its randomness, writes its instance to the transcript and derives its challenge $c_H$. It then sends $c_H$ to the device. The device sets its $nonce$ to $c_H \| nonce$ (concatenation of the byte serialization of $c_H$ and the original $nonce$), runs its proof against that combined nonce and sends the proof back. The host appends the device's proof bytes to its transcript, derives a fresh challenge $c_H'$ and generates its responses against $c_H'$. The verifier mirrors the same ordering.
340
+
341
+
There is no technical reason to use W3 over W2, but still ....
Copy file name to clipboardExpand all lines: dart-bp/docs/2.md
+51-1Lines changed: 51 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -55,6 +55,9 @@ A successful completion of registration results in the following:
55
55
56
56
57
57
### Protocol
58
+
59
+
_The following description is for W1 (solo) where a single prover knows both secret keys $sk$ and $ek$ along with all other witnesses. The split-prover variant used in W2/W3 is described after the Verifier section below._
60
+
58
61
Here the prover (investor) wants to prove following relations:
59
62
60
63
1. $State_0 = sk.G_{Aff} + at.G_3 + \rho.G_4 + \rho^2.G_5 + s.G_6 + s^2.G_7 + id.G_8 + ek.G_{Enc}$. This is equivalent to proving $State_0 = AK + EK + at.G_3 + id.G_8 + \rho.G_4 + \rho^2.G_5 + s.G_6 + s^2.G_7$ since public key $AK$, encryption key $EK$, asset-id $at$ and identity $id$ are revealed to the verifier. So only $\rho, \rho^2, s, s^2$ need to be proved.
@@ -196,7 +199,54 @@ Above are the high level instance and witness values known before the protocol s
196
199
14. Verifier finally checks the Bulletproofs proof that verifies all constraints, i.e for Poseidon2, multiplications and range proofs
197
200
198
201
199
-
## Encrytion key distribution
202
+
### Split prover variant (W2/W3)
203
+
204
+
In W2/W3 the work is split between a host (which does not know $sk, ek$) and a device (which holds $sk, ek$). The host runs essentially the same protocol as above except its statement excludes the secret-key components: since $AK$ and $EK$ are public, the verifier can subtract them out, so the host only proves knowledge of the remaining witnesses in
i.e. $State_0$ minus $AK$ and $EK$. Everything else the host does (nullifier proof, encryption-of-$s$ and $\rho$ to $pk_T$, range proofs, Poseidon2 constraint, etc.) is unchanged. The verifier reconstructs $State_0 = State_{0_H} + AK + EK$ and uses it in the original checks.
209
+
210
+
The device produces a standalone Sigma proof of knowledge of $sk$ in $AK = sk.G_{Aff}$ and $ek$ in $EK = ek.G_{Enc}$. Both relations share the same challenge (single transcript).
211
+
212
+
**Instance**: $AK, EK, G_{Aff}, G_{Enc}$
213
+
214
+
**Witness**: $sk, ek$
215
+
216
+
#### Device prover
217
+
1. Pick random $sk_r, ek_r \in \mathbb{Z}_p$ and compute
**W2 (parallel).** The device's $nonce$ is the same $nonce$ the host uses, so both proofs end up bound to the same context. The two proofs are produced independently and verified independently; nothing flows from one prover to the other during proving.
239
+
240
+
**W3 (sequential).** The host first runs its pre-challenge phase of the Prover above — picking all blindings and computing all $T$ values on the host side, but dropping the parts that involve $sk$ or $ek$ (so $T_{pk}$ and $T_{EK}$ are not computed and not added to its transcript). It then derives its challenge from that transcript exactly as the W1 challenge $c$ is derived, but with $T_{pk}$ and $T_{EK}$ omitted from the hash; call this challenge $c_H$. The host sends $c_H$ to the device. The device sets its $nonce$ to
241
+
$$nonce' = c_H \| nonce$$
242
+
(concatenation of the byte serialization of $c_H$ and the original $nonce$), runs the Device prover above against $nonce'$ — so its challenge becomes
— and sends $(T_{AK}, T_{EK}, s_{sk}, s_{ek})$ back to the host. The host appends the device proof bytes to its transcript and derives a fresh challenge
which it uses for its own response generation. The verifier mirrors the same ordering: derives $c_H$, reconstructs $nonce' = c_H \| nonce$, verifies the device proof against $nonce'$, then derives $c_H'$ from the device proof bytes and verifies the host's responses against $c_H'$.
247
+
248
+
249
+
## Encryption key distribution
200
250
When an asset has a shared encryption key, the asset issuer distributes the corresponding secret key $ek$ to the relevant auditors/mediators using Twisted Elgamal and a key-distribution proof which proves to the chain that issuer has indeed encrypted the secret key for the intended recipients and they can decrypt to get it. The issuer splits $ek$ into chunks $ek_i$ and for each chunk produces:
201
251
- A shared ciphertext: $C_i = G_{Enc}.r_i + H.ek_i$
202
252
- A per-recipient ciphertext: $E_{ji} = EK_j.r_i$ for each recipient $j$ with encryption public key $EK_j$
0 commit comments