@@ -10,14 +10,21 @@ import { Example } from "./../mocks/Example.sol";
10
10
import { MockDelta } from "./../mocks/MockDelta.sol " ;
11
11
12
12
contract DeltaProofTest is Test {
13
+ // The parameters required to generate a delta instance
13
14
struct DeltaInstanceInputs {
15
+ // The identifier of the asset
14
16
uint128 kind;
17
+ // The quantity of the asset
15
18
int128 quantity;
19
+ // Value commitment randomness
16
20
uint256 rcv;
17
21
}
18
22
23
+ // The parameters required to generate a delta proof
19
24
struct DeltaProofInputs {
25
+ // Value commitment randomness
20
26
uint256 rcv;
27
+ // The hash being signed over
21
28
bytes32 verifyingKey;
22
29
}
23
30
@@ -27,8 +34,8 @@ contract DeltaProofTest is Test {
27
34
deltaInputs.rcv = deltaInputs.rcv % SECP256K1_ORDER;
28
35
vm.assume (deltaInputs.rcv != 0 );
29
36
vm.assume (deltaInputs.kind != 0 );
30
- int256 prod_aux = (int256 (uint256 (deltaInputs.kind)) * int256 (deltaInputs.quantity));
31
- uint256 prod = prod_aux >= 0 ? uint256 (prod_aux ) : SECP256K1_ORDER - (uint256 (- prod_aux ) % SECP256K1_ORDER);
37
+ int256 prodAux = (int256 (uint256 (deltaInputs.kind)) * int256 (deltaInputs.quantity));
38
+ uint256 prod = prodAux >= 0 ? uint256 (prodAux ) : SECP256K1_ORDER - (uint256 (- prodAux ) % SECP256K1_ORDER);
32
39
uint256 preDelta = addmod (prod, deltaInputs.rcv, SECP256K1_ORDER);
33
40
vm.assume (preDelta != 0 );
34
41
// Derive address and public key from transaction delta
@@ -124,59 +131,19 @@ contract DeltaProofTest is Test {
124
131
Delta.verify ({proof: proof1, instance: instance2, verifyingKey: verifyingKey});
125
132
}
126
133
127
- /// @notice Wrap the delta inputs in such a way that they can be balanced
128
- /// and also return the total quantity and value commitment randomness
129
- function wrapDeltaInputs (DeltaInstanceInputs[] memory deltaInputs ) public pure returns (DeltaInstanceInputs[] memory wrappedDeltaInputs , int128 quantity_acc , uint256 rcv_acc ) {
130
- // Grab the kind to use for all deltas
131
- uint128 kind = deltaInputs.length > 0 ? deltaInputs[0 ].kind : 0 ;
132
- // Compute the window into which the deltas should sum
133
- int128 half_max = type (int128 ).max >> 1 ;
134
- int128 half_min = type (int128 ).min >> 1 ;
135
- // Track the current quantity and value commitment randomness
136
- quantity_acc = 0 ;
137
- rcv_acc = 0 ;
138
- // Wrap the deltas
139
- for (uint i = 0 ; i < deltaInputs.length ; i++ ) {
140
- // Ensure that all the deltas have the same kind
141
- deltaInputs[i].kind = kind;
142
- // Accumulate the randomness commitments modulo SECP256K1_ORDER
143
- rcv_acc = addmod (rcv_acc, deltaInputs[i].rcv, SECP256K1_ORDER);
144
- // Adjust the delta inputs so that the sum remains in a specific range
145
- if (deltaInputs[i].quantity >= 0 && quantity_acc > half_max - deltaInputs[i].quantity) {
146
- int128 overflow = quantity_acc - (half_max - deltaInputs[i].quantity);
147
- deltaInputs[i].quantity = half_min + overflow - 1 - quantity_acc;
148
- } else if (deltaInputs[i].quantity < 0 && quantity_acc < half_min - deltaInputs[i].quantity) {
149
- int128 underflow = (half_min - deltaInputs[i].quantity) - quantity_acc;
150
- deltaInputs[i].quantity = half_max + 1 - underflow - quantity_acc;
151
- }
152
- // Finally, accumulate the adjusted quantity
153
- quantity_acc += deltaInputs[i].quantity;
154
- }
155
- // Finally, return tbe wrapped deltas
156
- wrappedDeltaInputs = deltaInputs;
157
- }
158
-
159
- /// @notice Grab the first length elements from deltaInputs
160
- function truncateDeltaInputs (DeltaInstanceInputs[] memory deltaInputs , uint length ) public pure returns (DeltaInstanceInputs[] memory truncatedDeltaInputs ) {
161
- truncatedDeltaInputs = new DeltaInstanceInputs [](length);
162
- for (uint i = 0 ; i < length; i++ ) {
163
- truncatedDeltaInputs[i] = deltaInputs[i];
164
- }
165
- }
166
-
167
134
/// @notice Check that a balanced transaction does pass verification
168
135
function test_verify_balanced_delta_succeeds (DeltaInstanceInputs[] memory deltaInputs , bytes32 verifyingKey ) public {
169
136
uint256 [2 ] memory deltaAcc = [uint256 (0 ), uint256 (0 )];
170
137
// Truncate the delta inputs to improve test performance
171
- uint MAX_DELTA_LEN = 10 ;
172
- deltaInputs = truncateDeltaInputs (deltaInputs, deltaInputs.length % MAX_DELTA_LEN );
138
+ uint256 maxDeltaLen = 10 ;
139
+ deltaInputs = truncateDeltaInputs (deltaInputs, deltaInputs.length % maxDeltaLen );
173
140
// Make sure that the delta quantities balance out
174
141
(DeltaInstanceInputs[] memory wrappedDeltaInputs , int128 quantity , uint256 rcv ) = wrapDeltaInputs (deltaInputs);
175
142
// Adjust the last delta so that the full sum is zero
176
143
if (quantity != 0 ) {
177
144
wrappedDeltaInputs[wrappedDeltaInputs.length - 1 ].quantity -= quantity;
178
145
}
179
- for (uint i = 0 ; i < wrappedDeltaInputs.length ; i++ ) {
146
+ for (uint256 i = 0 ; i < wrappedDeltaInputs.length ; i++ ) {
180
147
// Compute the delta instance and accumulate it
181
148
uint256 [2 ] memory instance = generateDeltaInstance (wrappedDeltaInputs[i]);
182
149
deltaAcc = Delta.add (deltaAcc, instance);
@@ -195,13 +162,13 @@ contract DeltaProofTest is Test {
195
162
function test_verify_imbalanced_delta_fails (DeltaInstanceInputs[] memory deltaInputs , bytes32 verifyingKey ) public {
196
163
uint256 [2 ] memory deltaAcc = [uint256 (0 ), uint256 (0 )];
197
164
// Truncate the delta inputs to improve test performance
198
- uint MAX_DELTA_LEN = 10 ;
199
- deltaInputs = truncateDeltaInputs (deltaInputs, deltaInputs.length % MAX_DELTA_LEN );
165
+ uint256 maxDeltaLen = 10 ;
166
+ deltaInputs = truncateDeltaInputs (deltaInputs, deltaInputs.length % maxDeltaLen );
200
167
// Accumulate the total quantity and randomness commitment
201
168
(DeltaInstanceInputs[] memory wrappedDeltaInputs , int128 quantity , uint256 rcv ) = wrapDeltaInputs (deltaInputs);
202
169
// Assume that the deltas are imbalanced
203
170
vm.assume (quantity != 0 );
204
- for (uint i = 0 ; i < wrappedDeltaInputs.length ; i++ ) {
171
+ for (uint256 i = 0 ; i < wrappedDeltaInputs.length ; i++ ) {
205
172
// Compute the delta instance and accumulate it
206
173
uint256 [2 ] memory instance = generateDeltaInstance (wrappedDeltaInputs[i]);
207
174
deltaAcc = Delta.add (deltaAcc, instance);
@@ -217,6 +184,46 @@ contract DeltaProofTest is Test {
217
184
Delta.verify ({proof: proof, instance: deltaAcc, verifyingKey: verifyingKey});
218
185
}
219
186
187
+ /// @notice Wrap the delta inputs in such a way that they can be balanced
188
+ /// and also return the total quantity and value commitment randomness
189
+ function wrapDeltaInputs (DeltaInstanceInputs[] memory deltaInputs ) public pure returns (DeltaInstanceInputs[] memory wrappedDeltaInputs , int128 quantityAcc , uint256 rcvAcc ) {
190
+ // Grab the kind to use for all deltas
191
+ uint128 kind = deltaInputs.length > 0 ? deltaInputs[0 ].kind : 0 ;
192
+ // Compute the window into which the deltas should sum
193
+ int128 halfMax = type (int128 ).max >> 1 ;
194
+ int128 halfMin = type (int128 ).min >> 1 ;
195
+ // Track the current quantity and value commitment randomness
196
+ quantityAcc = 0 ;
197
+ rcvAcc = 0 ;
198
+ // Wrap the deltas
199
+ for (uint256 i = 0 ; i < deltaInputs.length ; i++ ) {
200
+ // Ensure that all the deltas have the same kind
201
+ deltaInputs[i].kind = kind;
202
+ // Accumulate the randomness commitments modulo SECP256K1_ORDER
203
+ rcvAcc = addmod (rcvAcc, deltaInputs[i].rcv, SECP256K1_ORDER);
204
+ // Adjust the delta inputs so that the sum remains in a specific range
205
+ if (deltaInputs[i].quantity >= 0 && quantityAcc > halfMax - deltaInputs[i].quantity) {
206
+ int128 overflow = quantityAcc - (halfMax - deltaInputs[i].quantity);
207
+ deltaInputs[i].quantity = halfMin + overflow - 1 - quantityAcc;
208
+ } else if (deltaInputs[i].quantity < 0 && quantityAcc < halfMin - deltaInputs[i].quantity) {
209
+ int128 underflow = (halfMin - deltaInputs[i].quantity) - quantityAcc;
210
+ deltaInputs[i].quantity = halfMax + 1 - underflow - quantityAcc;
211
+ }
212
+ // Finally, accumulate the adjusted quantity
213
+ quantityAcc += deltaInputs[i].quantity;
214
+ }
215
+ // Finally, return tbe wrapped deltas
216
+ wrappedDeltaInputs = deltaInputs;
217
+ }
218
+
219
+ /// @notice Grab the first length elements from deltaInputs
220
+ function truncateDeltaInputs (DeltaInstanceInputs[] memory deltaInputs , uint256 length ) public pure returns (DeltaInstanceInputs[] memory truncatedDeltaInputs ) {
221
+ truncatedDeltaInputs = new DeltaInstanceInputs [](length);
222
+ for (uint256 i = 0 ; i < length; i++ ) {
223
+ truncatedDeltaInputs[i] = deltaInputs[i];
224
+ }
225
+ }
226
+
220
227
function test_signatureIntegrity () public pure {
221
228
(uint8 v , bytes32 r , bytes32 s ) = vm.sign (MockDelta.SIGNER_PRIVATE_KEY, MockDelta.MESSAGE_HASH);
222
229
assertEq (r, MockDelta.R);
0 commit comments