-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathprivacypool.go
168 lines (145 loc) · 5.61 KB
/
privacypool.go
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
package privacypool
import (
_ "embed"
"github.com/0xBow-io/privacy-pool-veritas/core"
. "github.com/0xBow-io/veritas"
)
// PrivacyPoolCircuitPkg is the package containg all core circuit
// blocks required to build a complete PrivacyPool circuit
//
// You will still need to import the following circuit pkgs
// to meet dependencies:
// - BinSumCircuitPkg && BitifyCircuitPkg
// - CircuitUtilsPkg
// - ComparatorsCircuitPkg & SafeComparatorsCircuitPkg
// - PoseidonCircuitPkg with PoseidonDecrypt
// - MerkleTreeCircuitPkg
// - MultiplexerCircuitPkg
// - GatesCircuitPkg
// - BabyJubCircuitPkg
// - MontGomeryCircuitPkg
// - EcdhCircuitPkg
// - EscalarMulCircuitPkg
var PrivacyPoolCircuitPkg = CircuitPkg{
TargetVersion: "2.2.0",
Field: "bn128",
Programs: []Program{
PrivacyPool,
// Core Circuit Blocks
core.RecoverCommitmentKeys,
core.DecryptCommitment,
core.CommitmentOwnershipProof,
core.CommitmentMembershipProof,
core.HandleExistingCommitment,
core.HandleNewCommitment,
core.PoseidonDecryptWithoutCheck,
core.PoseidonDecryptIterations,
},
}
// TODO:
// - Add Documentation
// - Fragment template into smaller components
// - Utilise Buses to tidy up signals
var (
PrivacyPool = Program{
Identity: "PrivacyPool",
Src: `
template PrivacyPool(maxTreeDepth, cipherLen, tupleLen, nExisting, nNew) {
/// **** Public Signals ****
// Scope is the domain identifier
// i.e. Keccak256(chainID, contractAddress)
input signal scope;
// The depth of the State Tree
// at which the merkleproofs
// were generated
input signal actualTreeDepth;
input signal context;
// external input values to existing commitments
// external output values from new commitments
input signal externIO[2];
input signal existingStateRoot;
input signal newSaltPublicKey[nNew][2];
input signal newCiphertext[nNew][cipherLen];
/// **** End Of Public Signals ****
/// **** Private Signals ****
input signal privateKey[nExisting+nNew];
input signal nonce[nExisting+nNew];
input signal exSaltPublicKey[nExisting][2];
input signal exCiphertext[nExisting][cipherLen];
input signal exIndex[nExisting];
input signal exSiblings[nExisting][maxTreeDepth];
/// **** End Of Private Signals ****
output signal newNullRoot[nExisting+nNew];
output signal newCommitmentRoot[nExisting+nNew];
output signal newCommitmentHash[nExisting+nNew];
// ensure that External Input & Output
// fits within the 252 bits
var n2bIO[2][252];
n2bIO[0] = Num2Bits(252)(externIO[0]);
n2bIO[1] = Num2Bits(252)(externIO[1]);
signal _newNullRootOut[nNew+nExisting];
signal _newCommitmentRootOut[nNew+nExisting];
signal _newCommitmentHashOut[nNew+nExisting];
// get ownership & membership proofs for existing commitments
// and compute total sum
signal totalEx[nExisting+1];
totalEx[0] <== externIO[0];
for (var i = 0; i < nExisting; i++) {
var out[4] = HandleExistingCommitment(
maxTreeDepth,
cipherLen,
tupleLen
)(
scope,
existingStateRoot,
actualTreeDepth,
privateKey[i],
nonce[i],
exSaltPublicKey[i],
exCiphertext[i],
exIndex[i],
exSiblings[i]
);
_newNullRootOut[i] <== out[0];
_newCommitmentRootOut[i] <== out[1];
_newCommitmentHashOut[i] <== out[2];
totalEx[i+1] <== totalEx[i] + out[3];
}
// get ownership for new commitments
// and compute total sum
signal totalNew[nNew+1];
totalNew[0] <== externIO[1];
var k = nExisting; // offset for new commitments
for (var i = 0; i < nNew; i++) {
var out[4] = HandleNewCommitment(
cipherLen,
tupleLen
)(
scope,
privateKey[k],
nonce[k],
newSaltPublicKey[i],
newCiphertext[i]
);
_newNullRootOut[k] <== out[0];
_newCommitmentRootOut[k] <== out[1];
_newCommitmentHashOut[k] <== out[2];
totalNew[i+1] <== totalNew[i] + out[3];
k++;
}
// lastly ensure that all total sums are equal
signal sumEqCheck <== IsEqual()(
[
totalEx[nExisting],
totalNew[nNew]
]
);
sumEqCheck === 1;
newNullRoot <== _newNullRootOut;
newCommitmentRoot <== _newCommitmentRootOut;
newCommitmentHash <== _newCommitmentHashOut;
// constraint on context
signal contextSqrd <== context * context;
}
`}
)