Skip to content

Commit 0174102

Browse files
authored
Protocol 3.5 implementation (#36)
* Changes for mcl support * Extra info printing * Added server mode + misc optimizations * Changes for optimizations * Reserve the necessary number of sha256 hashers for deposits/withdrawals * Multi-threading fix for gcc * Fixed problem with swapping between different sized buffers * Fixed cli docs for pk_alt2mcl * Initial commit protocol 3.5 * Remove label functionality * Increased max number of tokens to 1024 * Re-enable parallel witness calculation of transfers in circuits * Removed debug prints
1 parent a388bea commit 0174102

22 files changed

+806
-1311
lines changed

Circuits/DepositCircuit.h

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ class DepositGadget : public GadgetT
1919
{
2020
public:
2121

22+
const Constants& constants;
23+
2224
// User state
2325
BalanceGadget balanceBefore;
2426
AccountGadget accountBefore;
@@ -40,12 +42,14 @@ class DepositGadget : public GadgetT
4042

4143
DepositGadget(
4244
ProtoboardT& pb,
43-
const Constants& constants,
45+
const Constants& _constants,
4446
const VariableT& root,
4547
const std::string& prefix
4648
) :
4749
GadgetT(pb, prefix),
4850

51+
constants(_constants),
52+
4953
// User state
5054
balanceBefore(pb, FMT(prefix, ".balanceBefore")),
5155
accountBefore(pb, FMT(prefix, ".accountBefore")),
@@ -117,11 +121,11 @@ class DepositGadget : public GadgetT
117121
updateAccount.generate_r1cs_constraints();
118122
}
119123

120-
const std::vector<VariableArrayT> getOnchainData(const Constants& constants) const
124+
const std::vector<VariableArrayT> getOnchainData() const
121125
{
122-
return {constants.padding_0000, accountID.bits,
126+
return {accountID.bits,
123127
publicKeyX.bits, publicKeyY.bits,
124-
tokenID.bits,
128+
VariableArrayT(6, constants.zero), tokenID.bits,
125129
amount.bits};
126130
}
127131

@@ -197,7 +201,7 @@ class DepositCircuit : public Circuit
197201
deposits.back().generate_r1cs_constraints();
198202

199203
// Hash data from deposit
200-
std::vector<VariableArrayT> depositData = deposits.back().getOnchainData(constants);
204+
std::vector<VariableArrayT> depositData = deposits.back().getOnchainData();
201205
std::vector<VariableArrayT> hashBits;
202206
hashBits.push_back(reverse((j == 0) ? depositBlockHashStart.bits : hashers.back().result().bits));
203207
hashBits.insert(hashBits.end(), depositData.begin(), depositData.end());

Circuits/InternalTransferCircuit.h

Lines changed: 68 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ class InternalTransferGadget : public GadgetT
1919
{
2020
public:
2121

22+
const Constants& constants;
23+
2224
// User From state
2325
BalanceGadget balanceFBefore_From;
2426
BalanceGadget balanceTBefore_From;
@@ -36,7 +38,16 @@ class InternalTransferGadget : public GadgetT
3638
DualVariableGadget amount;
3739
DualVariableGadget feeTokenID;
3840
DualVariableGadget fee;
39-
VariableT label;
41+
DualVariableGadget type;
42+
43+
// Signature
44+
Poseidon_gadget_T<9, 1, 6, 53, 8, 1> hash;
45+
SignatureVerifier signatureVerifier;
46+
47+
// Type
48+
NotGadget signatureInvalid;
49+
UnsafeAddGadget numConditionalTransfersAfter;
50+
RequireEqualGadget type_eq_signatureInvalid;
4051

4152
// User To account check
4253
RequireNotZeroGadget publicKeyX_notZero;
@@ -68,21 +79,20 @@ class InternalTransferGadget : public GadgetT
6879
// Update Operator
6980
UpdateBalanceGadget updateBalanceF_O;
7081

71-
// Signature
72-
Poseidon_gadget_T<10, 1, 6, 53, 9, 1> hash;
73-
SignatureVerifier signatureVerifier;
74-
7582
InternalTransferGadget(
7683
ProtoboardT &pb,
7784
const jubjub::Params& params,
78-
const Constants& constants,
85+
const Constants& _constants,
7986
const VariableT& accountsMerkleRoot,
8087
const VariableT& operatorBalancesRoot,
8188
const VariableT& blockExchangeID,
89+
const VariableT& numConditionalTransfersBefore,
8290
const std::string &prefix
8391
) :
8492
GadgetT(pb, prefix),
8593

94+
constants(_constants),
95+
8696
// User From state
8797
balanceFBefore_From(pb, FMT(prefix, "balanceFBefore_From")),
8898
balanceTBefore_From(pb, FMT(prefix, "balanceTBefore_From")),
@@ -100,7 +110,16 @@ class InternalTransferGadget : public GadgetT
100110
amount(pb, NUM_BITS_AMOUNT, FMT(prefix, ".amount")),
101111
feeTokenID(pb, NUM_BITS_TOKEN, FMT(prefix, ".feeTokenID")),
102112
fee(pb, NUM_BITS_AMOUNT, FMT(prefix, ".fee")),
103-
label(make_variable(pb, FMT(prefix, ".label"))),
113+
type(pb, NUM_BITS_TYPE, FMT(prefix, ".type")),
114+
115+
// Signature
116+
hash(pb, var_array({blockExchangeID, accountID_From.packed, accountID_To.packed, tokenID.packed, amount.packed, feeTokenID.packed, fee.packed, accountBefore_From.nonce}), FMT(this->annotation_prefix, ".hash")),
117+
signatureVerifier(pb, params, constants, accountBefore_From.publicKey, hash.result(), FMT(prefix, ".signatureVerifier"), false),
118+
119+
// Type
120+
signatureInvalid(pb, signatureVerifier.result(), ".signatureInvalid"),
121+
numConditionalTransfersAfter(pb, numConditionalTransfersBefore, signatureInvalid.result(), ".numConditionalTransfersAfter"),
122+
type_eq_signatureInvalid(pb, type.packed, signatureInvalid.result(), ".type_eq_signatureInvalid"),
104123

105124
// User To account check
106125
publicKeyX_notZero(pb, accountBefore_To.publicKey.x, FMT(prefix, ".publicKeyX_notZero")),
@@ -117,8 +136,8 @@ class InternalTransferGadget : public GadgetT
117136
// Transfer from From to To
118137
transferPayment(pb, NUM_BITS_AMOUNT, balanceTBefore_From.balance, balanceTBefore_To.balance, fAmount.value(), FMT(prefix, ".transferPayment")),
119138

120-
// Increase the nonce of From by 1
121-
nonce_From_after(pb, accountBefore_From.nonce, constants.one, NUM_BITS_NONCE, FMT(prefix, ".nonce_From_after")),
139+
// Increase the nonce of From by 1 (unless it's a conditional transfer)
140+
nonce_From_after(pb, accountBefore_From.nonce, signatureVerifier.result(), NUM_BITS_NONCE, FMT(prefix, ".nonce_From_after")),
122141

123142
// Update User From
124143
updateBalanceF_From(pb, accountBefore_From.balancesRoot, feeTokenID.bits,
@@ -148,11 +167,7 @@ class InternalTransferGadget : public GadgetT
148167
updateBalanceF_O(pb, operatorBalancesRoot, feeTokenID.bits,
149168
{balanceBefore_O.balance, balanceBefore_O.tradingHistory},
150169
{feePayment.Y, balanceBefore_O.tradingHistory},
151-
FMT(prefix, ".updateBalanceF_O")),
152-
153-
// Signature
154-
hash(pb, var_array({blockExchangeID, accountID_From.packed, accountID_To.packed, tokenID.packed, amount.packed, feeTokenID.packed, fee.packed, label, accountBefore_From.nonce}), FMT(this->annotation_prefix, ".hash")),
155-
signatureVerifier(pb, params, accountBefore_From.publicKey, hash.result(), FMT(prefix, ".signatureVerifier"))
170+
FMT(prefix, ".updateBalanceF_O"))
156171
{
157172

158173
}
@@ -176,7 +191,16 @@ class InternalTransferGadget : public GadgetT
176191
amount.generate_r1cs_witness(pb, transfer.amount);
177192
feeTokenID.generate_r1cs_witness(pb, transfer.balanceUpdateF_From.tokenID);
178193
fee.generate_r1cs_witness(pb, transfer.fee);
179-
pb.val(label) = transfer.label;
194+
type.generate_r1cs_witness(pb, transfer.type);
195+
196+
// Signature
197+
hash.generate_r1cs_witness();
198+
signatureVerifier.generate_r1cs_witness(transfer.signature);
199+
200+
// Type
201+
signatureInvalid.generate_r1cs_witness();
202+
pb.val(numConditionalTransfersAfter.sum) = transfer.numConditionalTransfersAfter;
203+
type_eq_signatureInvalid.generate_r1cs_witness();
180204

181205
// User To account check
182206
publicKeyX_notZero.generate_r1cs_witness();
@@ -207,10 +231,6 @@ class InternalTransferGadget : public GadgetT
207231

208232
// Update Operator
209233
updateBalanceF_O.generate_r1cs_witness(transfer.balanceUpdateF_O.proof);
210-
211-
// Signature
212-
hash.generate_r1cs_witness();
213-
signatureVerifier.generate_r1cs_witness(transfer.signature);
214234
}
215235

216236
void generate_r1cs_constraints()
@@ -222,7 +242,16 @@ class InternalTransferGadget : public GadgetT
222242
amount.generate_r1cs_constraints(true);
223243
feeTokenID.generate_r1cs_constraints(true);
224244
fee.generate_r1cs_constraints(true);
225-
// label has no limit
245+
type.generate_r1cs_constraints(true);
246+
247+
// Signature
248+
hash.generate_r1cs_constraints();
249+
signatureVerifier.generate_r1cs_constraints();
250+
251+
// Type
252+
signatureInvalid.generate_r1cs_constraints();
253+
numConditionalTransfersAfter.generate_r1cs_constraints();
254+
type_eq_signatureInvalid.generate_r1cs_constraints();
226255

227256
// User To account check
228257
publicKeyX_notZero.generate_r1cs_constraints();
@@ -254,19 +283,16 @@ class InternalTransferGadget : public GadgetT
254283

255284
// Update Operator
256285
updateBalanceF_O.generate_r1cs_constraints();
257-
258-
// Signature
259-
hash.generate_r1cs_constraints();
260-
signatureVerifier.generate_r1cs_constraints();
261286
}
262287

263288
const std::vector<VariableArrayT> getPublicData() const
264289
{
265-
return {accountID_From.bits,
290+
return {type.bits,
291+
accountID_From.bits,
266292
accountID_To.bits,
267-
tokenID.bits,
293+
VariableArrayT(2, constants.zero), tokenID.bits,
294+
VariableArrayT(2, constants.zero), feeTokenID.bits,
268295
fAmount.bits(),
269-
feeTokenID.bits,
270296
fFee.bits()};
271297
}
272298

@@ -279,6 +305,11 @@ class InternalTransferGadget : public GadgetT
279305
{
280306
return updateBalanceF_O.result();
281307
}
308+
309+
const VariableT& getNewNumConditionalTransfers() const
310+
{
311+
return numConditionalTransfersAfter.result();
312+
}
282313
};
283314

284315
class InternalTransferCircuit : public Circuit
@@ -295,6 +326,7 @@ class InternalTransferCircuit : public Circuit
295326
DualVariableGadget exchangeID;
296327
DualVariableGadget merkleRootBefore;
297328
DualVariableGadget merkleRootAfter;
329+
std::unique_ptr<libsnark::dual_variable_gadget<FieldT>> numConditionalTransfers;
298330
DualVariableGadget operatorAccountID;
299331

300332
// Operator account check
@@ -308,10 +340,6 @@ class InternalTransferCircuit : public Circuit
308340
// Update Operator
309341
std::unique_ptr<UpdateAccountGadget> updateAccount_O;
310342

311-
// Labels
312-
std::vector<VariableT> labels;
313-
std::unique_ptr<LabelHasher> labelHasher;
314-
315343
InternalTransferCircuit(ProtoboardT &pb, const std::string &prefix)
316344
: Circuit(pb, prefix),
317345

@@ -362,9 +390,9 @@ class InternalTransferCircuit : public Circuit
362390
transAccountsRoot,
363391
transOperatorBalancesRoot,
364392
exchangeID.packed,
393+
(j == 0) ? constants.zero : transfers.back().getNewNumConditionalTransfers(),
365394
std::string("transfer_") + std::to_string(j));
366395
transfers.back().generate_r1cs_constraints();
367-
labels.push_back(transfers.back().label);
368396
}
369397

370398
// Update Operator
@@ -374,18 +402,19 @@ class InternalTransferCircuit : public Circuit
374402
FMT(annotation_prefix, ".updateAccount_O")));
375403
updateAccount_O->generate_r1cs_constraints();
376404

377-
// Labels
378-
labelHasher.reset(new LabelHasher(pb, constants, labels, FMT(annotation_prefix, ".labelHash")));
379-
labelHasher->generate_r1cs_constraints();
405+
// Num conditional transfers
406+
numConditionalTransfers.reset(new libsnark::dual_variable_gadget<FieldT>(
407+
pb, transfers.back().getNewNumConditionalTransfers(), 32, ".numConditionalTransfers")
408+
);
409+
numConditionalTransfers->generate_r1cs_constraints(true);
380410

381411
// Public data
382412
publicData.add(exchangeID.bits);
383413
publicData.add(merkleRootBefore.bits);
384414
publicData.add(merkleRootAfter.bits);
385-
publicData.add(labelHasher->result()->bits);
415+
publicData.add(numConditionalTransfers->bits);
386416
if (onchainDataAvailability)
387417
{
388-
publicData.add(constants.padding_0000);
389418
publicData.add(operatorAccountID.bits);
390419
for (const InternalTransferGadget& transfer : transfers)
391420
{
@@ -426,8 +455,8 @@ class InternalTransferCircuit : public Circuit
426455
// Update operator
427456
updateAccount_O->generate_r1cs_witness(block.accountUpdate_O.proof);
428457

429-
// Labels
430-
labelHasher->generate_r1cs_witness();
458+
// Num conditional transfers
459+
numConditionalTransfers->generate_r1cs_witness_from_packed();
431460

432461
// Public data
433462
publicData.generate_r1cs_witness();

0 commit comments

Comments
 (0)