@lfdecentralizedtrust/zeto-contracts 0.2.1 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (155) hide show
  1. package/README.md +70 -162
  2. package/contracts/factory.sol +30 -34
  3. package/contracts/factory_upgradeable.sol +160 -0
  4. package/contracts/lib/common/util.sol +40 -0
  5. package/contracts/lib/interfaces/ILockableCapability.sol +318 -0
  6. package/contracts/lib/interfaces/{izeto.sol → IZeto.sol} +13 -1
  7. package/contracts/lib/interfaces/{izeto_initializable.sol → IZetoInitializable.sol} +14 -12
  8. package/contracts/lib/interfaces/{izeto_kyc.sol → IZetoKyc.sol} +3 -3
  9. package/contracts/lib/interfaces/IZetoLockableCapability.sol +237 -0
  10. package/contracts/lib/interfaces/IZetoStorage.sol +106 -0
  11. package/contracts/lib/interfaces/{izeto_lockable.sol → IZetoVerifier.sol} +8 -21
  12. package/contracts/lib/registry.sol +77 -27
  13. package/contracts/lib/storage/base.sol +210 -0
  14. package/contracts/lib/storage/nullifier.sol +166 -0
  15. package/contracts/lib/zeto_common.sol +277 -28
  16. package/contracts/lib/zeto_fungible.sol +451 -33
  17. package/contracts/lib/zeto_fungible_base.sol +69 -0
  18. package/contracts/lib/zeto_fungible_burn.sol +83 -53
  19. package/contracts/lib/zeto_fungible_burn_nullifier.sol +115 -72
  20. package/contracts/lib/zeto_fungible_nullifier.sol +167 -0
  21. package/contracts/lib/zeto_lockable.sol +613 -0
  22. package/contracts/lib/zeto_non_fungible.sol +236 -0
  23. package/contracts/lib/zeto_non_fungible_base.sol +61 -0
  24. package/contracts/lib/zeto_non_fungible_nullifier.sol +61 -0
  25. package/contracts/test/escrow1.sol +90 -34
  26. package/contracts/test/escrow2.sol +64 -29
  27. package/contracts/test/qurrency.sol +10 -2
  28. package/contracts/test/smt.sol +8 -3
  29. package/contracts/test/tendecimals.sol +14 -12
  30. package/contracts/verifiers/impl/anon.sol +189 -0
  31. package/contracts/verifiers/impl/anon_batch.sol +301 -0
  32. package/contracts/verifiers/impl/anon_enc.sol +266 -0
  33. package/contracts/verifiers/impl/anon_enc_batch.sol +602 -0
  34. package/contracts/verifiers/impl/anon_enc_nullifier.sol +287 -0
  35. package/contracts/verifiers/impl/anon_enc_nullifier_batch.sol +679 -0
  36. package/contracts/verifiers/impl/anon_enc_nullifier_kyc.sol +294 -0
  37. package/contracts/verifiers/impl/anon_enc_nullifier_kyc_batch.sol +686 -0
  38. package/contracts/verifiers/impl/anon_enc_nullifier_non_repudiation.sol +413 -0
  39. package/contracts/verifiers/impl/anon_enc_nullifier_non_repudiation_batch.sol +1141 -0
  40. package/contracts/verifiers/impl/anon_nullifier_kyc_transfer.sol +217 -0
  41. package/contracts/verifiers/impl/anon_nullifier_kyc_transferLocked.sol +196 -0
  42. package/contracts/verifiers/impl/anon_nullifier_kyc_transferLocked_batch.sol +308 -0
  43. package/contracts/verifiers/impl/anon_nullifier_kyc_transfer_batch.sol +385 -0
  44. package/contracts/verifiers/impl/anon_nullifier_qurrency_transfer.sol +497 -0
  45. package/contracts/verifiers/impl/anon_nullifier_qurrency_transfer_batch.sol +1001 -0
  46. package/contracts/verifiers/{verifier_anon_nullifier_transferLocked.sol → impl/anon_nullifier_transfer.sol} +12 -19
  47. package/contracts/verifiers/{verifier_anon_nullifier_transferLocked_batch.sol → impl/anon_nullifier_transfer_batch.sol} +44 -51
  48. package/contracts/verifiers/impl/burn.sol +182 -0
  49. package/contracts/verifiers/impl/burn_batch.sol +238 -0
  50. package/contracts/verifiers/impl/burn_nullifier.sol +203 -0
  51. package/contracts/verifiers/impl/burn_nullifier_batch.sol +315 -0
  52. package/contracts/verifiers/impl/deposit.sol +182 -0
  53. package/contracts/verifiers/impl/deposit_kyc.sol +189 -0
  54. package/contracts/verifiers/impl/nf_anon.sol +175 -0
  55. package/contracts/verifiers/{verifier_nf_anon_nullifier_transferLocked.sol → impl/nf_anon_nullifier_transfer.sol} +6 -13
  56. package/contracts/verifiers/impl/withdraw.sol +189 -0
  57. package/contracts/verifiers/impl/withdraw_batch.sol +245 -0
  58. package/contracts/verifiers/impl/withdraw_nullifier.sol +210 -0
  59. package/contracts/verifiers/impl/withdraw_nullifier_batch.sol +322 -0
  60. package/contracts/verifiers/verifier_anon.sol +31 -186
  61. package/contracts/verifiers/verifier_anon_batch.sol +31 -298
  62. package/contracts/verifiers/verifier_anon_enc.sol +31 -263
  63. package/contracts/verifiers/verifier_anon_enc_batch.sol +31 -599
  64. package/contracts/verifiers/verifier_anon_enc_nullifier.sol +31 -284
  65. package/contracts/verifiers/verifier_anon_enc_nullifier_batch.sol +33 -676
  66. package/contracts/verifiers/verifier_anon_enc_nullifier_kyc.sol +31 -291
  67. package/contracts/verifiers/verifier_anon_enc_nullifier_kyc_batch.sol +33 -683
  68. package/contracts/verifiers/verifier_anon_enc_nullifier_non_repudiation.sol +33 -410
  69. package/contracts/verifiers/verifier_anon_enc_nullifier_non_repudiation_batch.sol +33 -1138
  70. package/contracts/verifiers/verifier_anon_nullifier_kyc_transfer.sol +33 -214
  71. package/contracts/verifiers/verifier_anon_nullifier_kyc_transferLocked.sol +33 -221
  72. package/contracts/verifiers/verifier_anon_nullifier_kyc_transferLocked_batch.sol +33 -389
  73. package/contracts/verifiers/verifier_anon_nullifier_kyc_transfer_batch.sol +33 -382
  74. package/contracts/verifiers/verifier_anon_nullifier_qurrency_transfer.sol +33 -221
  75. package/contracts/verifiers/verifier_anon_nullifier_qurrency_transfer_batch.sol +33 -389
  76. package/contracts/verifiers/verifier_anon_nullifier_transfer.sol +33 -207
  77. package/contracts/verifiers/verifier_anon_nullifier_transfer_batch.sol +33 -375
  78. package/contracts/verifiers/verifier_burn.sol +31 -179
  79. package/contracts/verifiers/verifier_burn_batch.sol +31 -235
  80. package/contracts/verifiers/verifier_burn_nullifier.sol +31 -200
  81. package/contracts/verifiers/verifier_burn_nullifier_batch.sol +31 -312
  82. package/contracts/verifiers/verifier_deposit.sol +31 -179
  83. package/contracts/verifiers/verifier_deposit_kyc.sol +34 -0
  84. package/contracts/verifiers/verifier_nf_anon.sol +31 -172
  85. package/contracts/verifiers/verifier_nf_anon_nullifier_transfer.sol +33 -179
  86. package/contracts/verifiers/verifier_withdraw.sol +31 -186
  87. package/contracts/verifiers/verifier_withdraw_batch.sol +31 -242
  88. package/contracts/verifiers/verifier_withdraw_nullifier.sol +31 -207
  89. package/contracts/verifiers/verifier_withdraw_nullifier_batch.sol +33 -319
  90. package/contracts/zeto_anon.sol +77 -231
  91. package/contracts/zeto_anon_burnable.sol +56 -12
  92. package/contracts/zeto_anon_enc.sol +93 -190
  93. package/contracts/zeto_anon_enc_nullifier.sol +249 -195
  94. package/contracts/zeto_anon_enc_nullifier_kyc.sol +51 -232
  95. package/contracts/zeto_anon_enc_nullifier_non_repudiation.sol +231 -238
  96. package/contracts/zeto_anon_nullifier.sol +164 -298
  97. package/contracts/zeto_anon_nullifier_burnable.sol +68 -18
  98. package/contracts/zeto_anon_nullifier_kyc.sol +40 -345
  99. package/contracts/zeto_anon_nullifier_qurrency.sol +218 -360
  100. package/contracts/zeto_nf_anon.sol +55 -130
  101. package/contracts/zeto_nf_anon_nullifier.sol +90 -152
  102. package/hardhat.config.ts +9 -3
  103. package/ignition/modules/lib/deps.ts +9 -6
  104. package/ignition/modules/zeto_anon_burnable.ts +8 -7
  105. package/ignition/modules/zeto_anon_enc_nullifier.ts +33 -1
  106. package/ignition/modules/zeto_anon_enc_nullifier_kyc.ts +2 -2
  107. package/ignition/modules/zeto_anon_enc_nullifier_non_repudiation.ts +2 -1
  108. package/ignition/modules/zeto_anon_nullifier.ts +30 -5
  109. package/ignition/modules/zeto_anon_nullifier_burnable.ts +52 -17
  110. package/ignition/modules/zeto_anon_nullifier_kyc.ts +27 -12
  111. package/ignition/modules/zeto_anon_nullifier_qurrency.ts +2 -1
  112. package/ignition/modules/zeto_nf_anon_nullifier.ts +16 -12
  113. package/package.json +4 -2
  114. package/scripts/deploy_cloneable.ts +19 -10
  115. package/scripts/deploy_upgradeable.ts +9 -5
  116. package/scripts/tokens/Zeto_Anon.ts +3 -3
  117. package/scripts/tokens/Zeto_AnonBurnable.ts +1 -1
  118. package/scripts/tokens/Zeto_AnonEnc.ts +12 -3
  119. package/scripts/tokens/Zeto_AnonEncNullifier.ts +7 -3
  120. package/scripts/tokens/Zeto_AnonEncNullifierKyc.ts +1 -1
  121. package/scripts/tokens/Zeto_AnonEncNullifierNonRepudiation.ts +3 -1
  122. package/scripts/tokens/Zeto_AnonNullifier.ts +3 -1
  123. package/scripts/tokens/Zeto_AnonNullifierBurnable.ts +3 -1
  124. package/scripts/tokens/Zeto_AnonNullifierKyc.ts +1 -1
  125. package/scripts/tokens/Zeto_AnonNullifierQurrency.ts +3 -1
  126. package/scripts/tokens/Zeto_NfAnon.ts +2 -2
  127. package/scripts/tokens/Zeto_NfAnonNullifier.ts +3 -2
  128. package/test/factory.ts +46 -73
  129. package/test/factory_upgradeable.ts +311 -0
  130. package/test/lib/anon_nullifier_helpers.ts +89 -0
  131. package/test/lib/anon_zeto_helpers.ts +76 -0
  132. package/test/lib/deploy.ts +3 -2
  133. package/test/lib/utils.ts +74 -35
  134. package/test/test/escrow1.ts +185 -58
  135. package/test/test/escrow2.ts +200 -107
  136. package/test/test/qurrency.ts +13 -33
  137. package/test/usdc-shielding.ts +39 -26
  138. package/test/utils.ts +144 -21
  139. package/test/zeto_anon.ts +956 -465
  140. package/test/zeto_anon_enc.ts +881 -142
  141. package/test/zeto_anon_enc_nullifier.ts +847 -38
  142. package/test/zeto_anon_enc_nullifier_kyc.ts +120 -181
  143. package/test/zeto_anon_enc_nullifier_non_repudiation.ts +77 -46
  144. package/test/zeto_anon_nullifier.ts +1212 -953
  145. package/test/zeto_anon_nullifier_kyc.ts +674 -655
  146. package/test/zeto_anon_nullifier_qurrency.ts +452 -306
  147. package/test/zeto_nf_anon.ts +737 -137
  148. package/test/zeto_nf_anon_nullifier.ts +876 -246
  149. package/contracts/lib/zeto_base.sol +0 -293
  150. package/contracts/lib/zeto_fungible_withdraw.sol +0 -132
  151. package/contracts/lib/zeto_fungible_withdraw_nullifier.sol +0 -144
  152. package/contracts/lib/zeto_nullifier.sol +0 -334
  153. package/contracts/zkDvP.sol_ +0 -273
  154. package/test/zkDvP.ts_ +0 -455
  155. /package/contracts/lib/{common.sol → common/common.sol} +0 -0
@@ -15,406 +15,264 @@
15
15
  // limitations under the License.
16
16
  pragma solidity ^0.8.27;
17
17
 
18
- import {PoseidonUnit5L} from "@iden3/contracts/lib/Poseidon.sol";
19
- import {IZeto} from "./lib/interfaces/izeto.sol";
20
- import {MAX_BATCH} from "./lib/interfaces/izeto.sol";
21
- import {Groth16Verifier_Deposit} from "./verifiers/verifier_deposit.sol";
22
- import {Groth16Verifier_WithdrawNullifier} from "./verifiers/verifier_withdraw_nullifier.sol";
23
- import {Groth16Verifier_WithdrawNullifierBatch} from "./verifiers/verifier_withdraw_nullifier_batch.sol";
24
- import {Groth16Verifier_AnonNullifierQurrencyTransfer} from "./verifiers/verifier_anon_nullifier_qurrency_transfer.sol";
25
- // import {Groth16Verifier_AnonNullifierTransferLocked} from "./verifiers/verifier_anon_nullifier_transferLocked.sol";
26
- import {Groth16Verifier_AnonNullifierQurrencyTransferBatch} from "./verifiers/verifier_anon_nullifier_qurrency_transfer_batch.sol";
27
- // import {Groth16Verifier_AnonNullifierTransferLockedBatch} from "./verifiers/verifier_anon_nullifier_transferLocked_batch.sol";
28
- import {ZetoNullifier} from "./lib/zeto_nullifier.sol";
29
- import {ZetoFungibleWithdrawWithNullifiers} from "./lib/zeto_fungible_withdraw_nullifier.sol";
30
- import {Commonlib} from "./lib/common.sol";
31
- import {IZetoInitializable} from "./lib/interfaces/izeto_initializable.sol";
32
- import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
33
- import {console} from "hardhat/console.sol";
18
+ import {Commonlib} from "./lib/common/common.sol";
19
+ import {IZetoInitializable} from "./lib/interfaces/IZetoInitializable.sol";
20
+ import {Zeto_AnonNullifier} from "./zeto_anon_nullifier.sol";
34
21
 
35
- uint256 constant INPUT_SIZE = 9;
36
- // uint256 constant INPUT_SIZE_LOCKED = 8;
37
- uint256 constant BATCH_INPUT_SIZE = 33;
38
- // uint256 constant BATCH_INPUT_SIZE_LOCKED = 32;
39
-
40
- /// @title A sample implementation of a Zeto based fungible token with anonymity and history masking
22
+ /// @title A sample implementation of a Zeto based fungible token with
23
+ /// anonymity, history masking via nullifiers, and post-quantum
24
+ /// ML-KEM encryption envelopes for transferred values.
41
25
  /// @author Kaleido, Inc.
42
- /// @dev The proof has the following statements:
43
- /// - each value in the output commitments must be a positive number in the range 0 ~ (2\*\*40 - 1)
44
- /// - the sum of the nullified values match the sum of output values
45
- /// - the hashes in the input and output match the hash(value, salt, owner public key) formula
46
- /// - the sender possesses the private BabyJubjub key, whose public key is part of the pre-image of the input commitment hashes, which match the corresponding nullifiers
47
- /// - the nullifiers represent input commitments that are included in a Sparse Merkle Tree represented by the root hash
48
- contract Zeto_AnonNullifierQurrency is
49
- IZeto,
50
- IZetoInitializable,
51
- ZetoNullifier,
52
- ZetoFungibleWithdrawWithNullifiers,
53
- UUPSUpgradeable
54
- {
55
- Groth16Verifier_AnonNullifierQurrencyTransfer internal _verifier;
56
- Groth16Verifier_AnonNullifierQurrencyTransferBatch internal _batchVerifier;
57
- // Groth16Verifier_AnonNullifierTransferLocked internal _lockVerifier;
58
- // Groth16Verifier_AnonNullifierTransferLockedBatch
59
- // internal _batchLockVerifier;
26
+ /// @notice Decimals: this token uses **4** decimals, inherited from
27
+ /// {ZetoCommon.decimals}. Indexers and UIs reading this contract
28
+ /// directly should treat balances accordingly.
29
+ /// @dev Replaces the BabyJubjub-based ECDH envelope used by
30
+ /// {Zeto_AnonEncNullifier} with an ML-KEM (post-quantum)
31
+ /// key-encapsulation envelope. The proof carries the
32
+ /// `encapsulatedSharedSecret` (25 field elements -- the encoded
33
+ /// KEM ciphertext) alongside the encrypted output values; the
34
+ /// circuit asserts that the encrypted values were produced under
35
+ /// the same shared secret derived from that ciphertext.
36
+ ///
37
+ /// Locked-input circuit binding: this contract intentionally does
38
+ /// NOT include `msg.sender` in the public-input vector for the
39
+ /// locked-input flavour, even though `main` did. Lock-spender
40
+ /// authorization is now enforced at the Zeto contract layer (via
41
+ /// `ZetoFungible._locks[lockId].spender == msg.sender`) rather than
42
+ /// inside the circuit. This matches how {Zeto_AnonNullifier}
43
+ /// organises its locked-input proof; deployments that still want a
44
+ /// circuit-level binding to the spender can override
45
+ /// {constructPublicInputs} and append it.
46
+ contract Zeto_AnonNullifierQurrency is Zeto_AnonNullifier {
47
+ /// @dev Proof decode + public-input assembly scratch lives in
48
+ /// {ZetoAnonNullifierQurrencyStorage} (ERC-7201).
49
+
50
+ /// @dev Lock the implementation contract on construction. Restated at
51
+ /// every leaf in the inheritance graph for H-2 robustness.
52
+ /// @custom:oz-upgrades-unsafe-allow constructor
53
+ constructor() {
54
+ _disableInitializers();
55
+ }
60
56
 
61
57
  function initialize(
62
- string memory name,
63
- string memory symbol,
58
+ string calldata name,
59
+ string calldata symbol,
64
60
  address initialOwner,
65
61
  IZetoInitializable.VerifiersInfo calldata verifiers
66
- ) public initializer {
67
- __ZetoNullifier_init(name, symbol, initialOwner);
68
- __ZetoFungibleWithdrawWithNullifiers_init(
69
- (Groth16Verifier_Deposit)(verifiers.depositVerifier),
70
- (Groth16Verifier_WithdrawNullifier)(verifiers.withdrawVerifier),
71
- (Groth16Verifier_WithdrawNullifierBatch)(
72
- verifiers.batchWithdrawVerifier
73
- )
74
- );
75
- _verifier = (Groth16Verifier_AnonNullifierQurrencyTransfer)(
76
- verifiers.verifier
77
- );
78
- // _lockVerifier = (Groth16Verifier_AnonNullifierTransferLocked)(
79
- // verifiers.lockVerifier
80
- // );
81
- _batchVerifier = (Groth16Verifier_AnonNullifierQurrencyTransferBatch)(
82
- verifiers.batchVerifier
83
- );
84
- // _batchLockVerifier = (Groth16Verifier_AnonNullifierTransferLockedBatch)(
85
- // verifiers.batchLockVerifier
86
- // );
62
+ ) public override initializer {
63
+ __ZetoAnonNullifier_init(name, symbol, initialOwner, verifiers);
87
64
  }
88
65
 
89
- function _authorizeUpgrade(address) internal override onlyOwner {}
90
-
91
- function constructPublicInputs(
92
- uint[2] memory computed_hashes,
66
+ function emitTransferEvent(
93
67
  uint256[] memory nullifiers,
94
68
  uint256[] memory outputs,
95
- uint256 root,
96
- uint256 size,
97
- bool locked
98
- ) internal view returns (uint256[] memory publicInputs) {
99
- publicInputs = new uint256[](size);
100
- // copy computed hashes
101
- publicInputs[0] = computed_hashes[0];
102
- publicInputs[1] = computed_hashes[1];
103
- uint256 piIndex = 2;
104
- // copy input commitments
105
- for (uint256 i = 0; i < nullifiers.length; i++) {
106
- publicInputs[piIndex++] = nullifiers[i];
107
- }
108
- // when verifying locked transfers, additional public input
109
- // for the lock delegate
110
- if (locked) {
111
- publicInputs[piIndex++] = uint256(uint160(msg.sender));
112
- }
113
- // copy root
114
- publicInputs[piIndex++] = root;
115
-
116
- // populate enables
117
- for (uint256 i = 0; i < nullifiers.length; i++) {
118
- publicInputs[piIndex++] = (nullifiers[i] == 0) ? 0 : 1;
119
- }
120
-
121
- // copy output commitments
122
- for (uint256 i = 0; i < outputs.length; i++) {
123
- publicInputs[piIndex++] = outputs[i];
124
- }
125
-
126
- return publicInputs;
69
+ bytes memory proof,
70
+ bytes memory data
71
+ ) internal override {
72
+ ZetoAnonNullifierQurrencyStorage.DecodedProofQurrency memory dp;
73
+ (dp, ) = decodeProof_Qurrency(proof);
74
+ emit UTXOTransferWithMlkemEncryptedValues(
75
+ nullifiers,
76
+ outputs,
77
+ dp.encryptionNonce,
78
+ dp.encapsulatedSharedSecret,
79
+ dp.encryptedValues,
80
+ msg.sender,
81
+ data
82
+ );
127
83
  }
128
84
 
129
85
  /**
130
- * @dev the main function of the contract.
86
+ * @dev Layout of `proof` (ABI-encoded tuple):
87
+ * (uint256 root,
88
+ * uint256 encryptionNonce,
89
+ * uint256[] encryptedValues,
90
+ * uint256[25] encapsulatedSharedSecret,
91
+ * Commonlib.Proof groth16Proof)
92
+ *
93
+ * Public-inputs layout (unlocked):
94
+ * encapsulatedSharedSecret[25]
95
+ * ++ encryptedValues
96
+ * ++ nullifiers
97
+ * ++ root
98
+ * ++ enabled-flags
99
+ * ++ outputs
131
100
  *
132
- * @param nullifiers Array of nullifiers that are secretly bound to UTXOs to be spent by the transaction.
133
- * @param outputs Array of new UTXOs to generate, for future transactions to spend.
134
- * @param root The root hash of the Sparse Merkle Tree that contains the nullifiers.
135
- * @param proof A zero knowledge proof that the submitter is authorized to spend the inputs, and
136
- * that the outputs are valid in terms of obeying mass conservation rules.
101
+ * Locked variant drops the `root`/`enabled-flags` block (locked
102
+ * inputs are raw UTXOs, not nullifiers, so the SMT-membership
103
+ * block is not part of the witness) but keeps the encryption
104
+ * commitments so the receiver can still decrypt the new outputs.
137
105
  *
138
- * Emits a {UTXOTransfer} event.
106
+ * Root validation is performed here for the unlocked path so the
107
+ * proof bytes are decoded exactly once per transition.
139
108
  */
140
- function transfer(
109
+ function constructPublicInputs(
141
110
  uint256[] memory nullifiers,
142
111
  uint256[] memory outputs,
143
- uint256 root,
144
- bytes memory ciphertext,
145
- Commonlib.Proof calldata proof,
146
- bytes calldata data
147
- ) public returns (bool) {
148
- nullifiers = checkAndPadCommitments(nullifiers);
149
- outputs = checkAndPadCommitments(outputs);
150
- validateTransactionProposal(nullifiers, outputs, root, false);
151
- uint[2] memory computed_pubSignals = calculateHash(ciphertext);
152
- verifyProof(computed_pubSignals, nullifiers, outputs, root, proof);
153
- uint256[] memory empty;
154
- processInputsAndOutputs(nullifiers, outputs, empty, address(0));
112
+ bytes memory proof,
113
+ bool inputsLocked
114
+ )
115
+ internal
116
+ virtual
117
+ override
118
+ returns (uint256[] memory, Commonlib.Proof memory)
119
+ {
120
+ (
121
+ ZetoAnonNullifierQurrencyStorage.DecodedProofQurrency memory dp,
122
+ Commonlib.Proof memory proofStruct
123
+ ) = decodeProof_Qurrency(proof);
155
124
 
156
- uint256[] memory nullifierArray = new uint256[](nullifiers.length);
157
- uint256[] memory outputArray = new uint256[](outputs.length);
158
- for (uint256 i = 0; i < nullifiers.length; ++i) {
159
- nullifierArray[i] = nullifiers[i];
160
- outputArray[i] = outputs[i];
125
+ if (!inputsLocked) {
126
+ validateRoot(dp.root);
161
127
  }
162
- emit UTXOTransfer(nullifierArray, outputArray, msg.sender, data);
163
- return true;
164
- }
165
128
 
166
- // function transferLocked(
167
- // uint256[] memory nullifiers,
168
- // uint256[] memory outputs,
169
- // uint256 root,
170
- // Commonlib.Proof calldata proof,
171
- // bytes calldata data
172
- // ) public returns (bool) {
173
- // nullifiers = checkAndPadCommitments(nullifiers);
174
- // outputs = checkAndPadCommitments(outputs);
175
- // validateTransactionProposal(nullifiers, outputs, root, true);
176
- // verifyProofLocked(nullifiers, outputs, root, proof);
177
- // uint256[] memory empty;
178
- // processInputsAndOutputs(nullifiers, outputs, empty, address(0));
129
+ ZetoAnonNullifierQurrencyStorage.layout().dpq = dp;
179
130
 
180
- // uint256[] memory nullifierArray = new uint256[](nullifiers.length);
181
- // uint256[] memory outputArray = new uint256[](outputs.length);
182
- // for (uint256 i = 0; i < nullifiers.length; ++i) {
183
- // nullifierArray[i] = nullifiers[i];
184
- // outputArray[i] = outputs[i];
185
- // }
186
- // emit UTXOTransfer(nullifierArray, outputArray, msg.sender, data);
187
- // return true;
188
- // }
131
+ uint256 size = _calcSize_Qurrency(nullifiers, outputs, inputsLocked);
132
+ _fillPublicInputs_Qurrency(size, nullifiers, outputs, inputsLocked);
189
133
 
190
- function deposit(
191
- uint256 amount,
192
- uint256[] memory outputs,
193
- Commonlib.Proof calldata proof,
194
- bytes calldata data
195
- ) public {
196
- _deposit(amount, outputs, proof);
197
- _mint(outputs, data);
134
+ ZetoAnonNullifierQurrencyStorage.Layout storage $ = ZetoAnonNullifierQurrencyStorage
135
+ .layout();
136
+ uint256[] memory out = new uint256[]($.publicInputsBuf.length);
137
+ for (uint256 i = 0; i < out.length; ++i) {
138
+ out[i] = $.publicInputsBuf[i];
139
+ }
140
+ return (out, proofStruct);
198
141
  }
199
142
 
200
- function withdraw(
201
- uint256 amount,
202
- uint256[] memory nullifiers,
203
- uint256 output,
204
- uint256 root,
205
- Commonlib.Proof calldata proof,
206
- bytes calldata data
207
- ) public {
208
- uint256[] memory outputs = new uint256[](nullifiers.length);
209
- outputs[0] = output;
210
- // Check and pad inputs and outputs based on the max size
211
- nullifiers = checkAndPadCommitments(nullifiers);
212
- outputs = checkAndPadCommitments(outputs);
213
- validateTransactionProposal(nullifiers, outputs, root, false);
214
- _withdrawWithNullifiers(amount, nullifiers, output, root, proof);
215
- uint256[] memory empty;
216
- processInputsAndOutputs(nullifiers, outputs, empty, address(0));
217
- emit UTXOWithdraw(amount, nullifiers, output, msg.sender, data);
143
+ function decodeProof_Qurrency(
144
+ bytes memory proof
145
+ )
146
+ internal
147
+ pure
148
+ returns (
149
+ ZetoAnonNullifierQurrencyStorage.DecodedProofQurrency memory dp,
150
+ Commonlib.Proof memory proofStruct
151
+ )
152
+ {
153
+ (
154
+ dp.root,
155
+ dp.encryptionNonce,
156
+ dp.encryptedValues,
157
+ dp.encapsulatedSharedSecret,
158
+ proofStruct
159
+ ) = abi.decode(
160
+ proof,
161
+ (uint256, uint256, uint256[], uint256[25], Commonlib.Proof)
162
+ );
163
+ return (dp, proofStruct);
218
164
  }
219
165
 
220
- function mint(
221
- uint256[] memory utxos,
222
- bytes calldata data
223
- ) public onlyOwner {
224
- _mint(utxos, data);
166
+ function _calcSize_Qurrency(
167
+ uint256[] memory nullifiers,
168
+ uint256[] memory outputs,
169
+ bool inputsLocked
170
+ ) internal view returns (uint256) {
171
+ ZetoAnonNullifierQurrencyStorage.DecodedProofQurrency storage dq = ZetoAnonNullifierQurrencyStorage
172
+ .layout()
173
+ .dpq;
174
+ if (inputsLocked) {
175
+ return
176
+ dq.encapsulatedSharedSecret.length +
177
+ dq.encryptedValues.length +
178
+ nullifiers.length +
179
+ outputs.length;
180
+ }
181
+ return
182
+ dq.encapsulatedSharedSecret.length +
183
+ dq.encryptedValues.length +
184
+ (nullifiers.length * 2) + // nullifiers + enabled flags
185
+ 1 + // root
186
+ outputs.length;
225
187
  }
226
188
 
227
- // function lock(
228
- // uint256[] memory nullifiers,
229
- // uint256[] memory outputs,
230
- // uint256[] memory lockedOutputs,
231
- // uint256 root,
232
- // Commonlib.Proof calldata proof,
233
- // address delegate,
234
- // bytes calldata data
235
- // ) public {
236
- // // merge the outputs and lockedOutputs and do a regular transfer
237
- // uint256[] memory allOutputs = new uint256[](
238
- // outputs.length + lockedOutputs.length
239
- // );
240
- // for (uint256 i = 0; i < outputs.length; i++) {
241
- // allOutputs[i] = outputs[i];
242
- // }
243
- // for (uint256 i = 0; i < lockedOutputs.length; i++) {
244
- // allOutputs[outputs.length + i] = lockedOutputs[i];
245
- // }
246
- // nullifiers = checkAndPadCommitments(nullifiers);
247
- // allOutputs = checkAndPadCommitments(allOutputs);
248
- // validateTransactionProposal(nullifiers, allOutputs, root, false);
249
- // verifyProof(nullifiers, allOutputs, root, proof);
250
-
251
- // spendNullifiers(nullifiers);
252
-
253
- // // lock the intended outputs
254
- // _lock(nullifiers, outputs, lockedOutputs, delegate, data);
255
- // }
256
-
257
- // function unlock(
258
- // uint256[] memory nullifiers,
259
- // uint256[] memory outputs,
260
- // uint256 root,
261
- // Commonlib.Proof calldata proof,
262
- // bytes calldata data
263
- // ) public {
264
- // transferLocked(nullifiers, outputs, root, proof, data);
265
- // }
266
-
267
- function verifyProof(
268
- uint[2] memory computed_hashes,
189
+ function _fillPublicInputs_Qurrency(
190
+ uint256 size,
269
191
  uint256[] memory nullifiers,
270
192
  uint256[] memory outputs,
271
- uint256 root,
272
- Commonlib.Proof calldata proof
273
- ) public view returns (bool) {
274
- if (nullifiers.length > 2 || outputs.length > 2) {
275
- uint256[] memory publicInputs = constructPublicInputs(
276
- computed_hashes,
277
- nullifiers,
278
- outputs,
279
- root,
280
- BATCH_INPUT_SIZE,
281
- false
282
- );
283
- // construct the public inputs for verifier
284
- uint256[BATCH_INPUT_SIZE] memory fixedSizeInputs;
285
- for (uint256 i = 0; i < fixedSizeInputs.length; i++) {
286
- fixedSizeInputs[i] = publicInputs[i];
287
- }
288
- // Check the proof using batchVerifier
289
- require(
290
- _batchVerifier.verifyProof(
291
- proof.pA,
292
- proof.pB,
293
- proof.pC,
294
- fixedSizeInputs
295
- ),
296
- "Invalid proof (batch)"
297
- );
298
- } else {
299
- uint256[] memory publicInputs = constructPublicInputs(
300
- computed_hashes,
301
- nullifiers,
302
- outputs,
303
- root,
304
- INPUT_SIZE,
305
- false
306
- );
307
- // construct the public inputs for verifier
308
- uint256[INPUT_SIZE] memory fixedSizeInputs;
309
- for (uint256 i = 0; i < fixedSizeInputs.length; i++) {
310
- fixedSizeInputs[i] = publicInputs[i];
311
- }
312
- // Check the proof
313
- require(
314
- _verifier.verifyProof(
315
- proof.pA,
316
- proof.pB,
317
- proof.pC,
318
- fixedSizeInputs
319
- ),
320
- "Invalid proof"
321
- );
193
+ bool inputsLocked
194
+ ) internal {
195
+ ZetoAnonNullifierQurrencyStorage.Layout storage $ = ZetoAnonNullifierQurrencyStorage
196
+ .layout();
197
+ $.publicInputsBuf = new uint256[](size);
198
+ $.piIndex = 0;
199
+
200
+ _fillEncapsulatedSharedSecret_Q();
201
+ _fillEncryptedValues_Q();
202
+ _fillInputs_Q(nullifiers);
203
+ if (!inputsLocked) {
204
+ _fillRootAndEnables_Q(nullifiers);
322
205
  }
323
- return true;
206
+ _fillOutputs_Q(outputs);
324
207
  }
325
208
 
326
- // function verifyProofLocked(
327
- // uint256[] memory nullifiers,
328
- // uint256[] memory outputs,
329
- // uint256 root,
330
- // Commonlib.Proof calldata proof
331
- // ) public view returns (bool) {
332
- // if (nullifiers.length > 2 || outputs.length > 2) {
333
- // uint256[] memory publicInputs = constructPublicInputs(
334
- // nullifiers,
335
- // outputs,
336
- // root,
337
- // BATCH_INPUT_SIZE_LOCKED,
338
- // true
339
- // );
340
- // // construct the public inputs for batchVerifier
341
- // uint256[BATCH_INPUT_SIZE_LOCKED] memory fixedSizeInputs;
342
- // for (uint256 i = 0; i < fixedSizeInputs.length; i++) {
343
- // fixedSizeInputs[i] = publicInputs[i];
344
- // }
209
+ function _fillEncapsulatedSharedSecret_Q() internal {
210
+ ZetoAnonNullifierQurrencyStorage.Layout storage $ = ZetoAnonNullifierQurrencyStorage
211
+ .layout();
212
+ for (
213
+ uint256 i = 0;
214
+ i < $.dpq.encapsulatedSharedSecret.length;
215
+ ++i
216
+ ) {
217
+ $.publicInputsBuf[$.piIndex++] = $.dpq.encapsulatedSharedSecret[i];
218
+ }
219
+ }
345
220
 
346
- // // Check the proof using batchVerifier
347
- // require(
348
- // _batchLockVerifier.verifyProof(
349
- // proof.pA,
350
- // proof.pB,
351
- // proof.pC,
352
- // fixedSizeInputs
353
- // ),
354
- // "Invalid proof"
355
- // );
356
- // } else {
357
- // uint256[] memory publicInputs = constructPublicInputs(
358
- // nullifiers,
359
- // outputs,
360
- // root,
361
- // INPUT_SIZE_LOCKED,
362
- // true
363
- // );
364
- // // construct the public inputs for verifier
365
- // uint256[INPUT_SIZE_LOCKED] memory fixedSizeInputs;
366
- // for (uint256 i = 0; i < fixedSizeInputs.length; i++) {
367
- // fixedSizeInputs[i] = publicInputs[i];
368
- // }
369
- // // Check the proof
370
- // require(
371
- // _lockVerifier.verifyProof(
372
- // proof.pA,
373
- // proof.pB,
374
- // proof.pC,
375
- // fixedSizeInputs
376
- // ),
377
- // "Invalid proof"
378
- // );
379
- // }
380
- // return true;
381
- // }
221
+ function _fillEncryptedValues_Q() internal {
222
+ ZetoAnonNullifierQurrencyStorage.Layout storage $ = ZetoAnonNullifierQurrencyStorage
223
+ .layout();
224
+ for (uint256 i = 0; i < $.dpq.encryptedValues.length; ++i) {
225
+ $.publicInputsBuf[$.piIndex++] = $.dpq.encryptedValues[i];
226
+ }
227
+ }
382
228
 
383
- function calculateHash(
384
- bytes memory ciphertext
385
- ) internal view returns (uint[2] memory) {
386
- bytes memory ret = new bytes(32); // return is a simple 0 or 1
387
- bool ok;
388
- uint256 result;
389
- bytes memory ct = new bytes(768);
390
- for (uint i = 0; i < ct.length; i++) {
391
- ct[i] = ciphertext[i];
229
+ function _fillInputs_Q(uint256[] memory nullifiers) internal {
230
+ ZetoAnonNullifierQurrencyStorage.Layout storage $ = ZetoAnonNullifierQurrencyStorage
231
+ .layout();
232
+ for (uint256 i = 0; i < nullifiers.length; i++) {
233
+ $.publicInputsBuf[$.piIndex++] = nullifiers[i];
392
234
  }
393
- assembly {
394
- ok := staticcall(
395
- gas(),
396
- 0x02,
397
- add(ct, 0x20),
398
- 768,
399
- add(ret, 0x20),
400
- 0x20
401
- )
402
- result := mload(add(ret, 0x20))
235
+ }
236
+
237
+ function _fillRootAndEnables_Q(uint256[] memory nullifiers) internal {
238
+ ZetoAnonNullifierQurrencyStorage.Layout storage $ = ZetoAnonNullifierQurrencyStorage
239
+ .layout();
240
+ $.publicInputsBuf[$.piIndex++] = $.dpq.root;
241
+ for (uint256 i = 0; i < nullifiers.length; i++) {
242
+ $.publicInputsBuf[$.piIndex++] = (nullifiers[i] == 0) ? 0 : 1;
403
243
  }
404
- require(ok, "hash failed");
244
+ }
405
245
 
406
- bytes32 hash = bytes32(result);
407
- uint[2] memory computed_pubSignals;
408
- // Calculate h0: sum of the first 16 bytes
409
- for (uint i = 0; i < 16; i++) {
410
- computed_pubSignals[0] += uint256(uint8(hash[i])) * (1 << (8 * i));
246
+ function _fillOutputs_Q(uint256[] memory outputs) internal {
247
+ ZetoAnonNullifierQurrencyStorage.Layout storage $ = ZetoAnonNullifierQurrencyStorage
248
+ .layout();
249
+ for (uint256 i = 0; i < outputs.length; i++) {
250
+ $.publicInputsBuf[$.piIndex++] = outputs[i];
411
251
  }
412
- // Calculate h1: sum of the next 16 bytes
413
- for (uint i = 16; i < 32; i++) {
414
- computed_pubSignals[1] +=
415
- uint256(uint8(hash[i])) *
416
- (1 << (8 * (i - 16)));
252
+ }
253
+ }
254
+
255
+ /// @dev ERC-7201 (`erc7201:zeto.storage.Zeto_AnonNullifierQurrency`).
256
+ library ZetoAnonNullifierQurrencyStorage {
257
+ struct DecodedProofQurrency {
258
+ uint256 root;
259
+ uint256 encryptionNonce;
260
+ uint256[] encryptedValues;
261
+ uint256[25] encapsulatedSharedSecret;
262
+ }
263
+
264
+ struct Layout {
265
+ DecodedProofQurrency dpq;
266
+ uint256[] publicInputsBuf;
267
+ uint256 piIndex;
268
+ }
269
+
270
+ bytes32 private constant STORAGE_LOCATION =
271
+ 0x61ea13f87e8d672de1c36df013aa52a47bae99190f6e222ce275d312c118d800;
272
+
273
+ function layout() internal pure returns (Layout storage $) {
274
+ assembly {
275
+ $.slot := STORAGE_LOCATION
417
276
  }
418
- return computed_pubSignals;
419
277
  }
420
278
  }