Skip to content
This repository was archived by the owner on Nov 20, 2024. It is now read-only.

Commit ca6226c

Browse files
authored
Merge pull request #29 from jbaylina/master
float16 to float40
2 parents 16f791e + 3bad82a commit ca6226c

17 files changed

+5560
-150
lines changed

package-lock.json

Lines changed: 5420 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
"author": "HermezDAO",
2222
"license": "AGPL-3.0",
2323
"dependencies": {
24-
"@hermeznetwork/commonjs": "0.0.5",
24+
"@hermeznetwork/commonjs": "0.1.0",
2525
"circom": "^0.5.35",
2626
"circom_runtime": "^0.1.9",
2727
"circomlib": "^0.3.0",

src/compute-fee.circom

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ include "./lib/mux256.circom";
1010
* @output feeOut - {Uint128} - amount*feeFactor
1111
*/
1212
template ComputeFee() {
13-
signal input feeSel;
14-
signal input amount;
15-
signal input applyFee;
13+
signal input feeSel;
14+
signal input amount;
15+
signal input applyFee;
1616

1717
signal output feeOut;
1818

@@ -36,12 +36,12 @@ template ComputeFee() {
3636
// feeFactor is the output of the mux256
3737
// feeFactor could be shifted or not
3838
// overflow could not be achieved since:
39-
// - maxTransferAmount is '10235000000000000000000000000000000' since amountF max value is 0xFFFF
40-
// - maxAmountTransfer bits length is 113
39+
// - maxTransferAmount is '343597383670000000000000000000000000000000' since amountF max value is 0xFFFFFFFFFF
40+
// - maxAmountTransfer bits length is 138
4141
// - maxShiftedFeeValue = feeShiftTable(191) with bit length 60
4242
// - maxNonShiftedFeeValue = feeShiftTable(255) with bit length 63
43-
// - bitLength(maxTransferAmount) + bitLength(maxShiftedFeeValue) = 173 < 253
44-
// - bitLength(maxTransferAmount) + bitLength(maxNonShiftedFeeValue) = 176 < 253
43+
// - bitLength(maxTransferAmount) + bitLength(maxShiftedFeeValue) = 198 < 253
44+
// - bitLength(maxTransferAmount) + bitLength(maxNonShiftedFeeValue) = 201 < 253
4545
signal feeOutNotShifted;
4646
feeOutNotShifted <== mux256.out*amount;
4747

@@ -59,10 +59,10 @@ template ComputeFee() {
5959
var lcIn = 0; // linear combination value stored on 'bitsFeeOut'
6060
var lcNotShifted = 0; // feeOut if feeSel >= 192. Took from 'bitsFeeOut[0]...bitsFeeOut[127]'
6161
var lcShifted = 0; // feeOut if feeSel < 192. Took from 'bitsFeeOut[bitsShiftPrecision]...bitsFeeOut[bitsShiftPrecision + 127]'
62-
var lcOverflowNotShifted = 0; // check overflow if feeSel >= 192. Took from 'bitsFeeOut[128]...bitsFeeOut[252]'
62+
var lcOverflowNotShifted = 0; // check overflow if feeSel >= 192. Took from 'bitsFeeOut[128]...bitsFeeOut[252]'
6363
var lcOverflowShifted = 0; // check overflow if feeSel < 192. Took from 'bitsFeeOut[bitsShiftPrecision + 128]...bitsFeeOut[252]'
6464

65-
// computes:
65+
// computes:
6666
// - amount * feeFactor
6767
// - amount * (feeFactor << bitsShiftPrecision)
6868
for (var i = 0; i < 253; i++) {
@@ -83,14 +83,10 @@ template ComputeFee() {
8383
}
8484
}
8585

86-
// check binary representeation of 'feeOutNotShifted' matches its value
86+
// check binary representeation of 'feeOutNotShifted' matches its value
8787
lcIn === feeOutNotShifted;
8888

8989
// checks overflow of 128 bits
90-
// it is performed a sanity check for shifted 'feeFactor'
91-
// - max shifted 'feeFactor' is 'feeShiftTable(191)'
92-
// - (feeShiftTable(191) >> bitsShiftPrecision) = 2**(-0.05) < 1
93-
// - max computed fee would not overflow since 'maxTransferAmount' < 2**128
9490
applyShift * lcOverflowShifted === 0;
9591
(1 - applyShift) * lcOverflowNotShifted === 0;
9692

@@ -99,7 +95,7 @@ template ComputeFee() {
9995

10096
/**
10197
* Fee table hardcoded values
102-
* Table:
98+
* Table:
10399
* - (fee2Apply) * 2**bitsShift for i < 192
104100
* - (fee2Apply) for i < 192
105101
* Chosen bitShift = 60, which is the minimum value to have precision for each fee applied (if fee selected < 192)

src/decode-tx.circom

Lines changed: 54 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -12,22 +12,23 @@ include "./lib/decode-float.circom";
1212
* @input previousOnChain - {Bool} - determines if previous transaction is L1
1313
* @input txCompressedData - {Uint241} - encode transaction fields
1414
* @input maxNumBatch - {Uint32} - maximum allowed batch number when the transaction can be processed
15+
* @input amountF - {Uint40} - amount
1516
* @input toEthAddr - {Uint160} - ethereum address receiver
1617
* @input toBjjAy - {Field} - babyjubjub Y coordinate receiver
1718
* @input rqTxCompressedDataV2 - {Uint193} -requested encode transaction fields version2
1819
* @input rqToEthAddr - {Uint160} - requested ethereum address receiver
1920
* @input rqToBjjAy - {Field} - requested babyjubjub Y coordinate
2021
* @input fromEthAddr - {Uint160} - ethereum address sender
2122
* @input fromBjjCompressed[256] - {Array[Bool]} - babyjubjub compressed sender
22-
* @input loadAmountF - {Uint16} - amount to deposit from L1 to L2 encoded as float16
23+
* @input loadAmountF - {Uint40} - amount to deposit from L1 to L2 encoded as float40
2324
* @input globalChainID - {Uint16} - global chain identifier
2425
* @input currentNumBatch - {Uint32} - current batch number
2526
* @input onChain - {Bool} - determines if the transaction is L1 or L2
2627
* @input newAccount - {Bool} - determines if transaction creates a new account
2728
* @input auxFromIdx - {Uint48} - auxiliary index to create accounts
2829
* @input auxToIdx - {Uint48} - auxiliary index when signed index receiver is set to null
2930
* @input inIdx - {Uint48} - old last index assigned
30-
* @output L1L2TxData[nLevels*2 + 16 + 8] - {Array[Bool]} - L1-L2 data availability
31+
* @output L1L2TxData[nLevels*2 + 40 + 8] - {Array[Bool]} - L1-L2 data availability
3132
* @output txCompressedDataV2 - {Uint193} - encode transaction fields together version 2
3233
* @output L1TxFullData - {Array[Bool]} - L1 full data
3334
* @output outIdx - {Uint48} - new last index assigned
@@ -45,14 +46,15 @@ template DecodeTx(nLevels) {
4546
signal input previousOnChain;
4647
signal input txCompressedData; // data shared with L1 tx
4748
signal input maxNumBatch;
49+
signal input amountF;
4850
signal input toEthAddr;
4951
signal input toBjjAy;
5052
signal input rqTxCompressedDataV2;
5153
signal input rqToEthAddr;
5254
signal input rqToBjjAy;
5355

5456
// fromIdx | toIdx | amountF | userFee
55-
signal output L1L2TxData[nLevels*2 + 16 + 8];
57+
signal output L1L2TxData[nLevels*2 + 40 + 8];
5658
signal output txCompressedDataV2;
5759

5860
// tx L1 fields
@@ -68,7 +70,7 @@ template DecodeTx(nLevels) {
6870
signal input auxToIdx;
6971

7072
// fromEthAddr | fromBjjCompressed | fromIdx | loadAmountF | amountF | tokenID | toIdx
71-
signal output L1TxFullData[160 + 256 + 48 + 16 + 16 + 32 + 48];
73+
signal output L1TxFullData[160 + 256 + 48 + 40 + 40 + 32 + 48];
7274

7375
signal input inIdx;
7476
signal output outIdx;
@@ -78,19 +80,20 @@ template DecodeTx(nLevels) {
7880
signal chainID; // 16 32..47
7981
signal output fromIdx; // 48 48..95
8082
signal output toIdx; // 48 96..143
81-
signal output amount; // 16 144..159
82-
signal output tokenID; // 32 160..191
83-
signal output nonce; // 40 192..231
84-
signal output userFee; // 8 232..239
85-
signal output toBjjSign; // 1 240
83+
signal output tokenID; // 32 144..175
84+
signal output nonce; // 40 176..215
85+
signal output userFee; // 8 216..223
86+
signal output toBjjSign; // 1 224
87+
88+
signal output amount;
8689

8790
signal output sigL2Hash; // For the L2 signature
8891

8992
var i;
9093

9194
// Parse txCompressedData
9295
////////
93-
component n2bData = Num2Bits(241);
96+
component n2bData = Num2Bits(225);
9497
n2bData.in <== txCompressedData;
9598

9699
// constant signature
@@ -133,43 +136,48 @@ template DecodeTx(nLevels) {
133136
}
134137
paddingTo === 0;
135138

136-
// amountF
137-
component dfAmount = DecodeFloatBin();
138-
for (i = 0; i < 16; i++) {
139-
dfAmount.in[i] <== n2bData.out[144 + i];
140-
}
141-
dfAmount.out ==> amount;
142139

143140
// tokenID
144141
component b2ntokenID = Bits2Num(32);
145142
for (i = 0; i < 32; i++) {
146-
b2ntokenID.in[i] <== n2bData.out[160 + i];
143+
b2ntokenID.in[i] <== n2bData.out[144 + i];
147144
}
148145
b2ntokenID.out ==> tokenID;
149146

150147
// nonce
151148
component b2nNonce = Bits2Num(40);
152149
for (i = 0; i < 40; i++) {
153-
b2nNonce.in[i] <== n2bData.out[192 + i];
150+
b2nNonce.in[i] <== n2bData.out[176 + i];
154151
}
155152
b2nNonce.out ==> nonce;
156153

157154
// userFee
158155
component b2nUserFee = Bits2Num(8);
159156
for (i = 0; i < 8; i++) {
160-
b2nUserFee.in[i] <== n2bData.out[232 + i];
157+
b2nUserFee.in[i] <== n2bData.out[216 + i];
161158
}
162159
b2nUserFee.out ==> userFee;
163160

164161
// toBjjSign
165-
toBjjSign <== n2bData.out[240];
162+
toBjjSign <== n2bData.out[224];
163+
164+
// Parse amount
165+
////////
166+
167+
component n2bAmount = Num2Bits(40);
168+
n2bAmount.in <== amountF;
169+
component dfAmount = DecodeFloatBin();
170+
for (i = 0; i < 40; i++) {
171+
dfAmount.in[i] <== n2bAmount.out[i];
172+
}
173+
dfAmount.out ==> amount;
166174

167175
// Build txCompressedDataV2
168176
////////
169177
// fromIdx | toIdx | amountF | tokenID | nonce | userFee | toBjjSign
170178

171179
// add fromIdx
172-
component b2nTxCompressedDataV2 = Bits2Num(48*2 + 16 + 32 + 40 + 8 + 1);
180+
component b2nTxCompressedDataV2 = Bits2Num(48*2 + 40 + 32 + 40 + 8 + 1);
173181
for (i = 0; i < 48; i++) {
174182
b2nTxCompressedDataV2.in[i] <== n2bData.out[48 + i]*(1-onChain);
175183
}
@@ -180,27 +188,27 @@ template DecodeTx(nLevels) {
180188
}
181189

182190
// add amountF
183-
for (i = 0; i < 16; i++) {
184-
b2nTxCompressedDataV2.in[48 + 48 + i] <== n2bData.out[144 + i]*(1-onChain);
191+
for (i = 0; i < 40; i++) {
192+
b2nTxCompressedDataV2.in[48 + 48 + i] <== n2bAmount.out[i]*(1-onChain);
185193
}
186194

187195
// add tokenID
188196
for (i = 0; i < 32; i++) {
189-
b2nTxCompressedDataV2.in[48 + 48 + 16 + i] <== n2bData.out[160 + i]*(1-onChain);
197+
b2nTxCompressedDataV2.in[48 + 48 + 40 + i] <== n2bData.out[144 + i]*(1-onChain);
190198
}
191199

192200
// add nonce
193201
for (i = 0; i < 40; i++) {
194-
b2nTxCompressedDataV2.in[48 + 48 + 16 + 32 + i] <== n2bData.out[192 + i]*(1-onChain);
202+
b2nTxCompressedDataV2.in[48 + 48 + 40 + 32 + i] <== n2bData.out[176 + i]*(1-onChain);
195203
}
196204

197205
// add userFee
198206
for (i = 0; i < 8; i++) {
199-
b2nTxCompressedDataV2.in[48 + 48 + 16 + 32 + 40 + i] <== n2bData.out[232 + i]*(1-onChain);
207+
b2nTxCompressedDataV2.in[48 + 48 + 40 + 32 + 40 + i] <== n2bData.out[216 + i]*(1-onChain);
200208
}
201209

202210
// add toSignBjj
203-
b2nTxCompressedDataV2.in[192] <== n2bData.out[240];
211+
b2nTxCompressedDataV2.in[48 + 48 + 40 + 32 + 40 + 8] <== n2bData.out[224];
204212

205213
b2nTxCompressedDataV2.out ==> txCompressedDataV2;
206214

@@ -231,19 +239,20 @@ template DecodeTx(nLevels) {
231239
L1L2TxData[nLevels*2 - 1 - i] <== n2bFinalToIdx.out[i];
232240
}
233241
// Add amountF
234-
for (i = 0; i < 16; i++) {
235-
L1L2TxData[nLevels*2 + 16 - 1 - i] <== n2bData.out[144 + i];
242+
for (i = 0; i < 40; i++) {
243+
L1L2TxData[nLevels*2 + 40 - 1 - i] <== n2bAmount.out[i];
236244
}
237245
// Add fee
238246
for (i = 0; i < 8; i++) {
239-
L1L2TxData[nLevels*2 + 16 + 8 - 1 - i] <== n2bData.out[232 + i]*(1-onChain);
247+
L1L2TxData[nLevels*2 + 40 + 8 - 1 - i] <== n2bData.out[216 + i]*(1-onChain);
240248
}
241249

242250
// Build sigL2Hash
243251
////////
244252
// build e_1: toEthAddr 160 bits 0..159
245-
// maxNumBatch 32 bits 160..192
246-
component b2nElement1 = Bits2Num(160 + 32);
253+
// amountF 40 bits 160..199
254+
// maxNumBatch 32 bits 200..232
255+
component b2nElement1 = Bits2Num(160 + 32 + 40);
247256

248257
// add toEthAddr
249258
component n2bToEthAddr = Num2Bits(160);
@@ -252,11 +261,16 @@ template DecodeTx(nLevels) {
252261
b2nElement1.in[i] <== n2bToEthAddr.out[i];
253262
}
254263

264+
// amountF
265+
for (i = 0; i < 40; i++) {
266+
b2nElement1.in[160 + i] <== n2bAmount.out[i];
267+
}
268+
255269
// add maxNumBatch
256270
component n2bMaxNumBatch = Num2Bits(32);
257271
n2bMaxNumBatch.in <== maxNumBatch;
258272
for (i = 0; i < 32; i++) {
259-
b2nElement1.in[160 + i] <== n2bMaxNumBatch.out[i];
273+
b2nElement1.in[200 + i] <== n2bMaxNumBatch.out[i];
260274
}
261275

262276
component hashSig = Poseidon(6);
@@ -289,25 +303,25 @@ template DecodeTx(nLevels) {
289303
}
290304

291305
// Add loadAmountF
292-
component n2bLoadAmountF = Num2Bits(16);
306+
component n2bLoadAmountF = Num2Bits(40);
293307
n2bLoadAmountF.in <== loadAmountF;
294-
for (i = 0; i < 16; i++) {
295-
L1TxFullData[160 + 256 + 48 + 16 - 1 - i] <== n2bLoadAmountF.out[i]*(onChain);
308+
for (i = 0; i < 40; i++) {
309+
L1TxFullData[160 + 256 + 48 + 40 - 1 - i] <== n2bLoadAmountF.out[i]*(onChain);
296310
}
297311

298312
// Add amountF
299-
for (i = 0; i < 16; i++) {
300-
L1TxFullData[160 + 256 + 48 + 16 + 16 - 1 - i] <== n2bData.out[144 + i]*(onChain);
313+
for (i = 0; i < 40; i++) {
314+
L1TxFullData[160 + 256 + 48 + 40 + 40 - 1 - i] <== n2bAmount.out[i]*(onChain);
301315
}
302316

303317
// Add tokenID
304318
for (i = 0; i < 32; i++) {
305-
L1TxFullData[160 + 256 + 48 + 16 + 16 + 32 - 1 - i] <== n2bData.out[160 + i]*(onChain);
319+
L1TxFullData[160 + 256 + 48 + 40 + 40 + 32 - 1 - i] <== n2bData.out[144 + i]*(onChain);
306320
}
307321

308322
// Add toIdx
309323
for (i = 0; i < 48; i++) {
310-
L1TxFullData[160 + 256 + 48 + 16 + 16 + 32 + 48 - 1 - i] <== n2bData.out[96 + i]*(onChain);
324+
L1TxFullData[160 + 256 + 48 + 40 + 40 + 32 + 48 - 1 - i] <== n2bData.out[96 + i]*(onChain);
311325
}
312326

313327
// Perform checks on transaction fields

src/hash-inputs.circom

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ template HashInputs(nLevels, nTx, maxL1Tx, maxFeeTx) {
2727
var bitsRoots = 256;
2828
var bitsChainID = 16;
2929
var bitsCurrentNumBatch = 32;
30-
var bitsL1TxsFullData = maxL1Tx * (2*bitsIndexMax + 32 + 16 + 16 + 256 + 160);
31-
var bitsL1L2TxsData = nTx * (2*nLevels + 16 + 8);
30+
var bitsL1TxsFullData = maxL1Tx * (2*bitsIndexMax + 32 + 40 + 40 + 256 + 160);
31+
var bitsL1L2TxsData = nTx * (2*nLevels + 40 + 8);
3232
var bitsFeeTxsData = maxFeeTx * bitsIndex;
3333

3434
// inputs

0 commit comments

Comments
 (0)