-
Notifications
You must be signed in to change notification settings - Fork 128
/
Copy pathencrypt.zk
65 lines (50 loc) · 1.79 KB
/
encrypt.zk
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# Verifiable encryption inside ZK
# Normally this algo will be hardened due to malleability attacks
# on the ciphertext, but the ZK proof ensures that the ciphertext
# cannot be modified.
#
# This is basically the el gamal scheme in ZK
k = 13;
field = "pallas";
constant "Encrypt" {}
witness "Encrypt" {
# We are encrypting values to this public key
EcNiPoint pubkey,
# Emphemeral secret value
Base ephem_secret,
# Values we are encrypting
Base value_1,
Base value_2,
Base value_3,
}
circuit "Encrypt" {
################################################
# 1. Derive shared secret using DH
################################################
ephem_pub = ec_mul_var_base(ephem_secret, pubkey);
ephem_pub_x = ec_get_x(ephem_pub);
ephem_pub_y = ec_get_y(ephem_pub);
# Used by the receiver to also derive the same shared secret
constrain_instance(ephem_pub_x);
constrain_instance(ephem_pub_y);
shared_secret = poseidon_hash(ephem_pub_x, ephem_pub_y);
################################################
# 2. Derive blinding factors for witness values
################################################
N1 = witness_base(1);
N2 = witness_base(2);
N3 = witness_base(3);
blind_1 = poseidon_hash(shared_secret, N1);
blind_2 = poseidon_hash(shared_secret, N2);
blind_3 = poseidon_hash(shared_secret, N3);
################################################
# 3. Encrypt the values by applying blinds
################################################
# This could be add or mul
enc_value_1 = base_mul(value_1, blind_1);
enc_value_2 = base_mul(value_2, blind_2);
enc_value_3 = base_mul(value_3, blind_3);
constrain_instance(enc_value_1);
constrain_instance(enc_value_2);
constrain_instance(enc_value_3);
}