stellar / slingshot

A new blockchain architecture under active development, with a strong focus on scalability, privacy and safety
Apache License 2.0
415 stars 61 forks source link

zkvm: encrypt/decrypt protocol #259

Open oleganza opened 5 years ago

oleganza commented 5 years ago

Based on previous discussion: #177.

Problem

Blinding/Reblinding protocol in ZkVM solves the problem of (roughly speaking) "communicating the blinding factor to a counter-party". The problem is still relevant, but the solution is sub-optimal:

  1. Values become "stateful" — their variables for qty/flavor have to keep commitments inside the VM to make them "replaceable" (re-blindeable).
  2. This makes the runtime state more complicated and requires tracking whether the variable is "attached" or "detached".
  3. We cannot use PortableItem and Value types in the Output: instead we have another set of types FrozenItem and FrozenValue.
  4. When the commitment is blinded with blind instruction, the user is supposed to copy-paste a part of the proof into the reblind instruction to "remind the VM" that a certain commitment has a required shape. This is an unnecessary overhead that may be eliminated if the VM encodes the valid transformation in the type system.

Suggestion

First, define a protocol for converting n Pedersen commitments into a single ElGamal encryption over a vector of the secret values. Encryption and decryption will prove the correspondence between the secrets in commitments and encryption. Decryption is a bit cheaper as proof about two auxiliary points will be preserved in the EncryptedPayload type.

Second, define the encrypt:n instruction to take n items that must be either Value or Data convertible to a point (Pedersen commitment). Values are mapped to a pair of commitments (qty, flv), but Data items are mapped to a single commitment. These are type-annotated and wrapped in an EncryptedPayload object.

decrypt instruction pops EncryptedPayload object and maps commitments back to Values and Data, and checks the associated proof.

Commitment-Encryption Protocol

TBD: ∑-protocol for mapping N pedersen commitments to a vector ElGamal encryption.

TBD: use Henry's ZKP crate https://github.com/dalek-cryptography/zkp/tree/develop

Encrypt

// Encrypt {v_i} to pubkey P with nonce q:
{V_i = v_i * B + f_i * B2} for i=0 to n-1
Q = q*B
P = p*B
C = ∑(v_i*G_i) + q*P
return (C,Q,P)

proof size: n+3 commitments, 2n+2 secrets, total (3n+5)*32 bytes
352 bytes for a n=2 (single Value)

Decrypt

// Decrypt C into {V_i}:
{V_i = v_i * B + f_i * B2} for i=0 to n-1
C = ∑(v_i*G_i) + p*Q
(no need to prove that Q=q*B since Q is remembered in EncryptedPayload)

proof size: n+1 commitments, 2n+1 secrets, total (3n+2)*32 bytes
256 bytes for a n=2 (single Value)

EncryptedPayload format

E.g. <C><Q><P><tag=scalar><point><tag=value><point><point>