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:
Values become "stateful" — their variables for qty/flavor have to keep commitments inside the VM to make them "replaceable" (re-blindeable).
This makes the runtime state more complicated and requires tracking whether the variable is "attached" or "detached".
We cannot use PortableItem and Value types in the Output: instead we have another set of types FrozenItem and FrozenValue.
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.
// 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>
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:
PortableItem
andValue
types in theOutput
: instead we have another set of typesFrozenItem
andFrozenValue
.blind
instruction, the user is supposed to copy-paste a part of the proof into thereblind
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 theEncryptedPayload
type.Second, define the
encrypt:n
instruction to taken
items that must be eitherValue
orData
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
Decrypt
EncryptedPayload format
E.g.
<C><Q><P><tag=scalar><point><tag=value><point><point>