@lfdecentralizedtrust/zeto-contracts 0.2.2 → 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 (152) hide show
  1. package/README.md +70 -162
  2. package/contracts/factory.sol +30 -34
  3. package/contracts/factory_upgradeable.sol +11 -7
  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 +74 -26
  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 +6 -1
  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 +217 -361
  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 +8 -0
  104. package/ignition/modules/zeto_anon_burnable.ts +8 -7
  105. package/ignition/modules/zeto_anon_enc_nullifier.ts +31 -0
  106. package/ignition/modules/zeto_anon_enc_nullifier_kyc.ts +2 -2
  107. package/ignition/modules/zeto_anon_nullifier.ts +28 -4
  108. package/ignition/modules/zeto_anon_nullifier_burnable.ts +50 -16
  109. package/ignition/modules/zeto_anon_nullifier_kyc.ts +27 -12
  110. package/ignition/modules/zeto_nf_anon_nullifier.ts +14 -10
  111. package/package.json +4 -2
  112. package/scripts/deploy_cloneable.ts +19 -10
  113. package/scripts/deploy_upgradeable.ts +9 -5
  114. package/scripts/tokens/Zeto_Anon.ts +3 -3
  115. package/scripts/tokens/Zeto_AnonBurnable.ts +1 -1
  116. package/scripts/tokens/Zeto_AnonEnc.ts +12 -3
  117. package/scripts/tokens/Zeto_AnonEncNullifier.ts +5 -3
  118. package/scripts/tokens/Zeto_AnonEncNullifierKyc.ts +1 -1
  119. package/scripts/tokens/Zeto_AnonEncNullifierNonRepudiation.ts +1 -1
  120. package/scripts/tokens/Zeto_AnonNullifier.ts +1 -1
  121. package/scripts/tokens/Zeto_AnonNullifierBurnable.ts +1 -1
  122. package/scripts/tokens/Zeto_AnonNullifierKyc.ts +1 -1
  123. package/scripts/tokens/Zeto_AnonNullifierQurrency.ts +1 -1
  124. package/scripts/tokens/Zeto_NfAnon.ts +2 -2
  125. package/scripts/tokens/Zeto_NfAnonNullifier.ts +1 -1
  126. package/test/factory.ts +46 -73
  127. package/test/lib/anon_nullifier_helpers.ts +89 -0
  128. package/test/lib/anon_zeto_helpers.ts +76 -0
  129. package/test/lib/deploy.ts +3 -2
  130. package/test/lib/utils.ts +74 -35
  131. package/test/test/escrow1.ts +185 -58
  132. package/test/test/escrow2.ts +200 -107
  133. package/test/test/qurrency.ts +13 -33
  134. package/test/usdc-shielding.ts +39 -26
  135. package/test/utils.ts +144 -21
  136. package/test/zeto_anon.ts +956 -465
  137. package/test/zeto_anon_enc.ts +881 -142
  138. package/test/zeto_anon_enc_nullifier.ts +847 -38
  139. package/test/zeto_anon_enc_nullifier_kyc.ts +120 -181
  140. package/test/zeto_anon_enc_nullifier_non_repudiation.ts +77 -46
  141. package/test/zeto_anon_nullifier.ts +1212 -953
  142. package/test/zeto_anon_nullifier_kyc.ts +674 -655
  143. package/test/zeto_anon_nullifier_qurrency.ts +452 -306
  144. package/test/zeto_nf_anon.ts +737 -137
  145. package/test/zeto_nf_anon_nullifier.ts +876 -246
  146. package/contracts/lib/zeto_base.sol +0 -293
  147. package/contracts/lib/zeto_fungible_withdraw.sol +0 -132
  148. package/contracts/lib/zeto_fungible_withdraw_nullifier.sol +0 -144
  149. package/contracts/lib/zeto_nullifier.sol +0 -340
  150. package/contracts/zkDvP.sol_ +0 -273
  151. package/test/zkDvP.ts_ +0 -455
  152. /package/contracts/lib/{common.sol → common/common.sol} +0 -0
@@ -15,35 +15,32 @@
15
15
  // limitations under the License.
16
16
  pragma solidity ^0.8.27;
17
17
 
18
- import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
19
- import {Groth16Verifier_Deposit} from "./verifiers/verifier_deposit.sol";
20
- import {Groth16Verifier_WithdrawNullifier} from "./verifiers/verifier_withdraw_nullifier.sol";
21
- import {Groth16Verifier_WithdrawNullifierBatch} from "./verifiers/verifier_withdraw_nullifier_batch.sol";
22
- import {Groth16Verifier_AnonEncNullifierNonRepudiation} from "./verifiers/verifier_anon_enc_nullifier_non_repudiation.sol";
23
- import {Groth16Verifier_AnonEncNullifierNonRepudiationBatch} from "./verifiers/verifier_anon_enc_nullifier_non_repudiation_batch.sol";
24
- import {ZetoNullifier} from "./lib/zeto_nullifier.sol";
25
- import {ZetoFungibleWithdrawWithNullifiers} from "./lib/zeto_fungible_withdraw_nullifier.sol";
26
- import {Commonlib} from "./lib/common.sol";
27
- import {IZetoInitializable} from "./lib/interfaces/izeto_initializable.sol";
18
+ import {Commonlib} from "./lib/common/common.sol";
19
+ import {IZetoInitializable} from "./lib/interfaces/IZetoInitializable.sol";
20
+ import {Zeto_AnonEncNullifier} from "./zeto_anon_enc_nullifier.sol";
28
21
 
29
- uint256 constant INPUT_SIZE = 36;
30
- uint256 constant BATCH_INPUT_SIZE = 140;
31
-
32
- /// @title A sample implementation of a Zeto based fungible token with anonymity, encryption and history masking
22
+ /// @title A sample implementation of a Zeto based fungible token with
23
+ /// anonymity, encryption, history masking via nullifiers, and
24
+ /// non-repudiation through arbiter-decryptable transfer envelopes.
33
25
  /// @author Kaleido, Inc.
34
- /// @dev The proof has the following statements:
35
- /// - each value in the output commitments must be a positive number in the range 0 ~ (2\*\*40 - 1)
36
- /// - the sum of the nullified values match the sum of output values
37
- /// - the hashes in the input and output match the hash(value, salt, owner public key) formula
38
- /// - 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
39
- /// - the encrypted value in the input is derived from the receiver's UTXO value and encrypted with a shared secret using the ECDH protocol between the sender and receiver (this guarantees data availability for the receiver)
40
- /// - the nullifiers represent input commitments that are included in a Sparse Merkle Tree represented by the root hash
41
- contract Zeto_AnonEncNullifierNonRepudiation is
42
- IZetoInitializable,
43
- ZetoNullifier,
44
- ZetoFungibleWithdrawWithNullifiers,
45
- UUPSUpgradeable
46
- {
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 Adds a second encryption envelope (the "authority" envelope) on
30
+ /// top of {Zeto_AnonEncNullifier}, encrypted to the configured
31
+ /// arbiter's BabyJubjub public key. The transfer ZK circuit asserts
32
+ /// that the same plaintext is encrypted to both the receiver and the
33
+ /// arbiter, so the arbiter can later decrypt every transfer envelope
34
+ /// it observes on-chain. This is what gives the contract its
35
+ /// non-repudiation property: the sender cannot later deny the
36
+ /// contents of a transfer to the arbiter.
37
+ contract Zeto_AnonEncNullifierNonRepudiation is Zeto_AnonEncNullifier {
38
+ /// @dev Non-repudiation-specific state ({ZetoAnonEncNullifierNonRepudiationStorage}, ERC-7201).
39
+
40
+ /// @dev Per-contract event for non-repudiable transfers. Carries both
41
+ /// the receiver-bound encryption envelope and the
42
+ /// authority-bound envelope, alongside the ECDH public key and
43
+ /// nonce required to decrypt them.
47
44
  event UTXOTransferNonRepudiation(
48
45
  uint256[] inputs,
49
46
  uint256[] outputs,
@@ -55,257 +52,253 @@ contract Zeto_AnonEncNullifierNonRepudiation is
55
52
  bytes data
56
53
  );
57
54
 
58
- Groth16Verifier_AnonEncNullifierNonRepudiation internal _verifier;
59
- Groth16Verifier_AnonEncNullifierNonRepudiationBatch internal _batchVerifier;
60
- // the arbiter public key that must be used to
61
- // encrypt the secrets of every transaction
62
- uint256[2] private arbiter;
55
+ /// @dev Lock the implementation contract on construction. Restated at
56
+ /// every leaf in the inheritance graph for H-2 robustness.
57
+ /// @custom:oz-upgrades-unsafe-allow constructor
58
+ constructor() {
59
+ _disableInitializers();
60
+ }
63
61
 
64
62
  function initialize(
65
- string memory name,
66
- string memory symbol,
63
+ string calldata name,
64
+ string calldata symbol,
67
65
  address initialOwner,
68
66
  IZetoInitializable.VerifiersInfo calldata verifiers
69
- ) public initializer {
70
- __ZetoNullifier_init(name, symbol, initialOwner);
71
- __ZetoFungibleWithdrawWithNullifiers_init(
72
- (Groth16Verifier_Deposit)(verifiers.depositVerifier),
73
- (Groth16Verifier_WithdrawNullifier)(verifiers.withdrawVerifier),
74
- (Groth16Verifier_WithdrawNullifierBatch)(
75
- verifiers.batchWithdrawVerifier
76
- )
77
- );
78
- _verifier = (Groth16Verifier_AnonEncNullifierNonRepudiation)(
79
- verifiers.verifier
80
- );
81
- _batchVerifier = (Groth16Verifier_AnonEncNullifierNonRepudiationBatch)(
82
- verifiers.batchVerifier
67
+ ) public virtual override initializer {
68
+ __ZetoAnonEncNullifierNonRepudiation_init(
69
+ name,
70
+ symbol,
71
+ initialOwner,
72
+ verifiers
83
73
  );
84
74
  }
85
75
 
86
- function _authorizeUpgrade(address) internal override onlyOwner {}
76
+ function __ZetoAnonEncNullifierNonRepudiation_init(
77
+ string calldata name_,
78
+ string calldata symbol_,
79
+ address initialOwner,
80
+ IZetoInitializable.VerifiersInfo calldata verifiers
81
+ ) internal onlyInitializing {
82
+ __ZetoAnonEncNullifier_init(name_, symbol_, initialOwner, verifiers);
83
+ }
87
84
 
88
85
  function setArbiter(uint256[2] memory _arbiter) public onlyOwner {
89
- arbiter = _arbiter;
86
+ ZetoAnonEncNullifierNonRepudiationStorage.layout().arbiter = _arbiter;
90
87
  }
91
88
 
92
89
  function getArbiter() public view returns (uint256[2] memory) {
93
- return arbiter;
90
+ uint256[2] storage a = ZetoAnonEncNullifierNonRepudiationStorage.layout()
91
+ .arbiter;
92
+ return [a[0], a[1]];
94
93
  }
95
94
 
96
- function constructPublicInputs(
95
+ function emitTransferEvent(
97
96
  uint256[] memory nullifiers,
98
97
  uint256[] memory outputs,
99
- uint256 root,
100
- uint256 encryptionNonce,
101
- uint256[2] memory ecdhPublicKey,
102
- uint256[] memory encryptedValuesForReceiver,
103
- uint256[] memory encryptedValuesForAuthority,
104
- uint256 size
105
- ) internal view returns (uint256[] memory publicInputs) {
106
- publicInputs = new uint256[](size);
107
- uint256 piIndex = 0;
108
- // copy the ecdh public key
109
- for (uint256 i = 0; i < ecdhPublicKey.length; ++i) {
110
- publicInputs[piIndex++] = ecdhPublicKey[i];
111
- }
112
- // copy the encrypted value, salt and parity bit for receiver
113
- for (uint256 i = 0; i < encryptedValuesForReceiver.length; ++i) {
114
- publicInputs[piIndex++] = encryptedValuesForReceiver[i];
115
- }
116
- // copy the encrypted value, salt and parity bit for authority
117
- for (uint256 i = 0; i < encryptedValuesForAuthority.length; ++i) {
118
- publicInputs[piIndex++] = encryptedValuesForAuthority[i];
119
- }
120
- // copy input commitments
121
- for (uint256 i = 0; i < nullifiers.length; i++) {
122
- publicInputs[piIndex++] = nullifiers[i];
123
- }
124
-
125
- // copy root
126
- publicInputs[piIndex++] = root;
127
-
128
- // populate enables
129
- for (uint256 i = 0; i < nullifiers.length; i++) {
130
- publicInputs[piIndex++] = (nullifiers[i] == 0) ? 0 : 1;
131
- }
132
-
133
- // copy output commitments
134
- for (uint256 i = 0; i < outputs.length; i++) {
135
- publicInputs[piIndex++] = outputs[i];
136
- }
137
-
138
- // copy encryption nonce
139
- publicInputs[piIndex++] = encryptionNonce;
140
-
141
- // copy arbiter pub key
142
- publicInputs[piIndex++] = arbiter[0];
143
- publicInputs[piIndex++] = arbiter[1];
144
- return publicInputs;
98
+ bytes memory proof,
99
+ bytes memory data
100
+ ) internal override {
101
+ ZetoAnonEncNullifierNonRepudiationStorage.DecodedProofNonRepudiation
102
+ memory dp;
103
+ (dp, ) = decodeProof_NonRepudiation(proof);
104
+ emit UTXOTransferNonRepudiation(
105
+ nullifiers,
106
+ outputs,
107
+ dp.encryptionNonce,
108
+ dp.ecdhPublicKey,
109
+ dp.encryptedValuesForReceiver,
110
+ dp.encryptedValuesForAuthority,
111
+ msg.sender,
112
+ data
113
+ );
145
114
  }
146
115
 
147
116
  /**
148
- * @dev the main function of the contract, which transfers values from one account (represented by Babyjubjub public keys)
149
- * to one or more receiver accounts (also represented by Babyjubjub public keys). One of the two nullifiers may be zero
150
- * if the transaction only needs one UTXO to be spent. Equally one of the two outputs may be zero if the transaction
151
- * only needs to create one new UTXO.
117
+ * @dev Layout of `proof` (ABI-encoded tuple):
118
+ * (uint256 root,
119
+ * uint256 encryptionNonce,
120
+ * uint256[2] ecdhPublicKey,
121
+ * uint256[] encryptedValuesForReceiver,
122
+ * uint256[] encryptedValuesForAuthority,
123
+ * Commonlib.Proof groth16Proof)
152
124
  *
153
- * @param nullifiers Array of nullifiers that are secretly bound to UTXOs to be spent by the transaction.
154
- * @param outputs Array of new UTXOs to generate, for future transactions to spend.
155
- * @param root The root hash of the Sparse Merkle Tree that contains the nullifiers.
156
- * @param encryptionNonce The nonce used to derive the shared secret for encryption by the receiver.
157
- * @param encryptedValuesForReceiver Array of encrypted values, salts and public keys for the receiver UTXO
158
- * @param encryptedValuesForAuthority Array of encrypted values, salts and public keys for the input UTXOs and output UTXOs.
159
- * @param proof A zero knowledge proof that the submitter is authorized to spend the inputs, and
160
- * that the outputs are valid in terms of obeying mass conservation rules.
125
+ * Public-inputs layout:
126
+ * ecdhPublicKey
127
+ * ++ encryptedValuesForReceiver
128
+ * ++ encryptedValuesForAuthority
129
+ * ++ nullifiers
130
+ * ++ root
131
+ * ++ enabled-flags
132
+ * ++ outputs
133
+ * ++ encryptionNonce
134
+ * ++ arbiter
161
135
  *
162
- * Emits a {UTXOTransferNonRepudiation} event.
136
+ * Root validation is performed here for the unlocked path so the
137
+ * proof bytes are decoded exactly once per transition.
163
138
  */
164
- function transfer(
139
+ function constructPublicInputs(
165
140
  uint256[] memory nullifiers,
166
141
  uint256[] memory outputs,
167
- uint256 root,
168
- uint256 encryptionNonce,
169
- uint256[2] memory ecdhPublicKey,
170
- uint256[] memory encryptedValuesForReceiver,
171
- uint256[] memory encryptedValuesForAuthority,
172
- Commonlib.Proof calldata proof,
173
- bytes calldata data
174
- ) public returns (bool) {
175
- // Check and pad commitments
176
- nullifiers = checkAndPadCommitments(nullifiers);
177
- outputs = checkAndPadCommitments(outputs);
178
- validateTransactionProposal(nullifiers, outputs, root, false);
179
-
180
- // Check the proof
181
- if (nullifiers.length > 2 || outputs.length > 2) {
182
- require(
183
- (encryptedValuesForAuthority.length == 64),
184
- "Cipher Text for Authority must have a length of 64 with input or outputs number more than 2 and less than 10"
185
- );
186
- uint256[] memory publicInputs = constructPublicInputs(
187
- nullifiers,
188
- outputs,
189
- root,
190
- encryptionNonce,
191
- ecdhPublicKey,
192
- encryptedValuesForReceiver,
193
- encryptedValuesForAuthority,
194
- BATCH_INPUT_SIZE
195
- );
196
- // construct the public inputs for batchVerifier
197
- uint256[BATCH_INPUT_SIZE] memory fixedSizeInputs;
198
- for (uint256 i = 0; i < fixedSizeInputs.length; i++) {
199
- fixedSizeInputs[i] = publicInputs[i];
200
- }
142
+ bytes memory proof,
143
+ bool inputsLocked
144
+ ) internal override returns (uint256[] memory, Commonlib.Proof memory) {
145
+ (
146
+ ZetoAnonEncNullifierNonRepudiationStorage.DecodedProofNonRepudiation
147
+ memory dp,
148
+ Commonlib.Proof memory proofStruct
149
+ ) = decodeProof_NonRepudiation(proof);
201
150
 
202
- // Check the proof using batchVerifier
203
- require(
204
- _batchVerifier.verifyProof(
205
- proof.pA,
206
- proof.pB,
207
- proof.pC,
208
- fixedSizeInputs
209
- ),
210
- "Invalid proof (batch)"
211
- );
212
- } else {
213
- require(
214
- (encryptedValuesForAuthority.length == 16),
215
- "Cipher Text for Authority must have a length of 16 for no more than 2 inputs or outputs"
216
- );
217
- uint256[] memory publicInputs = constructPublicInputs(
218
- nullifiers,
219
- outputs,
220
- root,
221
- encryptionNonce,
222
- ecdhPublicKey,
223
- encryptedValuesForReceiver,
224
- encryptedValuesForAuthority,
225
- INPUT_SIZE
226
- );
227
- // construct the public inputs for verifier
228
- uint256[INPUT_SIZE] memory fixedSizeInputs;
229
- for (uint256 i = 0; i < fixedSizeInputs.length; i++) {
230
- fixedSizeInputs[i] = publicInputs[i];
231
- }
232
- // Check the proof
233
- require(
234
- _verifier.verifyProof(
235
- proof.pA,
236
- proof.pB,
237
- proof.pC,
238
- fixedSizeInputs
239
- ),
240
- "Invalid proof"
241
- );
151
+ if (!inputsLocked) {
152
+ validateRoot(dp.root);
242
153
  }
243
154
 
244
- // accept the transaction to consume the input UTXOs and produce new UTXOs
245
- uint256[] memory empty;
246
- processInputsAndOutputs(nullifiers, outputs, empty, address(0));
155
+ ZetoAnonEncNullifierNonRepudiationStorage.layout().dpnr = dp;
247
156
 
248
- uint256[] memory encryptedValuesReceiverArray = new uint256[](
249
- encryptedValuesForReceiver.length
250
- );
251
- uint256[] memory encryptedValuesAuthorityArray = new uint256[](
252
- encryptedValuesForAuthority.length
157
+ uint256 size = _calcSize_NonRepudiation(nullifiers, outputs);
158
+ uint256[] memory publicInputs = new uint256[](size);
159
+ _fillPublicInputs_NonRepudiation(publicInputs, nullifiers, outputs);
160
+
161
+ return (publicInputs, proofStruct);
162
+ }
163
+
164
+ function decodeProof_NonRepudiation(
165
+ bytes memory proof
166
+ )
167
+ private
168
+ pure
169
+ returns (
170
+ ZetoAnonEncNullifierNonRepudiationStorage.DecodedProofNonRepudiation
171
+ memory dp,
172
+ Commonlib.Proof memory proofStruct
173
+ )
174
+ {
175
+ (
176
+ dp.root,
177
+ dp.encryptionNonce,
178
+ dp.ecdhPublicKey,
179
+ dp.encryptedValuesForReceiver,
180
+ dp.encryptedValuesForAuthority,
181
+ proofStruct
182
+ ) = abi.decode(
183
+ proof,
184
+ (
185
+ uint256,
186
+ uint256,
187
+ uint256[2],
188
+ uint256[],
189
+ uint256[],
190
+ Commonlib.Proof
191
+ )
253
192
  );
254
- for (uint256 i = 0; i < encryptedValuesForReceiver.length; ++i) {
255
- encryptedValuesReceiverArray[i] = encryptedValuesForReceiver[i];
256
- }
257
- for (uint256 i = 0; i < encryptedValuesForAuthority.length; ++i) {
258
- encryptedValuesAuthorityArray[i] = encryptedValuesForAuthority[i];
259
- }
193
+ }
260
194
 
261
- emit UTXOTransferNonRepudiation(
195
+ function _calcSize_NonRepudiation(
196
+ uint256[] memory nullifiers,
197
+ uint256[] memory outputs
198
+ ) internal view returns (uint256) {
199
+ return
200
+ ZetoAnonEncNullifierNonRepudiationStorage.layout().dpnr.ecdhPublicKey.length +
201
+ ZetoAnonEncNullifierNonRepudiationStorage.layout().dpnr.encryptedValuesForReceiver.length +
202
+ ZetoAnonEncNullifierNonRepudiationStorage.layout().dpnr.encryptedValuesForAuthority.length +
203
+ (nullifiers.length * 2) + // nullifiers + enabled flags
204
+ outputs.length +
205
+ 2 + // root + encryptionNonce
206
+ 2; // arbiter public key
207
+ }
208
+
209
+ function _fillPublicInputs_NonRepudiation(
210
+ uint256[] memory publicInputs,
211
+ uint256[] memory nullifiers,
212
+ uint256[] memory outputs
213
+ ) internal view {
214
+ uint256 piIndex = 0;
215
+ piIndex = _fillEcdhAndEncrypted_NR(publicInputs, piIndex);
216
+ piIndex = _fillNullifiersAndRoot_NR(publicInputs, nullifiers, piIndex);
217
+ piIndex = _fillEnablesAndOutputs_NR(
218
+ publicInputs,
262
219
  nullifiers,
263
220
  outputs,
264
- encryptionNonce,
265
- ecdhPublicKey,
266
- encryptedValuesReceiverArray,
267
- encryptedValuesAuthorityArray,
268
- msg.sender,
269
- data
221
+ piIndex
270
222
  );
271
- return true;
223
+ _fillNonceAndArbiter_NR(publicInputs, piIndex);
272
224
  }
273
225
 
274
- function deposit(
275
- uint256 amount,
276
- uint256[] memory outputs,
277
- Commonlib.Proof calldata proof,
278
- bytes calldata data
279
- ) public {
280
- _deposit(amount, outputs, proof);
281
- _mint(outputs, data);
226
+ function _fillEcdhAndEncrypted_NR(
227
+ uint256[] memory publicInputs,
228
+ uint256 piIndex
229
+ ) internal view returns (uint256) {
230
+ for (uint256 i = 0; i < ZetoAnonEncNullifierNonRepudiationStorage.layout().dpnr.ecdhPublicKey.length; ++i) {
231
+ publicInputs[piIndex++] = ZetoAnonEncNullifierNonRepudiationStorage.layout().dpnr.ecdhPublicKey[i];
232
+ }
233
+ for (uint256 i = 0; i < ZetoAnonEncNullifierNonRepudiationStorage.layout().dpnr.encryptedValuesForReceiver.length; ++i) {
234
+ publicInputs[piIndex++] = ZetoAnonEncNullifierNonRepudiationStorage.layout().dpnr.encryptedValuesForReceiver[i];
235
+ }
236
+ for (uint256 i = 0; i < ZetoAnonEncNullifierNonRepudiationStorage.layout().dpnr.encryptedValuesForAuthority.length; ++i) {
237
+ publicInputs[piIndex++] = ZetoAnonEncNullifierNonRepudiationStorage.layout().dpnr.encryptedValuesForAuthority[i];
238
+ }
239
+ return piIndex;
282
240
  }
283
241
 
284
- function withdraw(
285
- uint256 amount,
242
+ function _fillNullifiersAndRoot_NR(
243
+ uint256[] memory publicInputs,
286
244
  uint256[] memory nullifiers,
287
- uint256 output,
288
- uint256 root,
289
- Commonlib.Proof calldata proof,
290
- bytes calldata data
291
- ) public {
292
- uint256[] memory outputs = new uint256[](nullifiers.length);
293
- outputs[0] = output;
294
- // Check and pad commitments
295
- nullifiers = checkAndPadCommitments(nullifiers);
296
- outputs = checkAndPadCommitments(outputs);
297
- validateTransactionProposal(nullifiers, outputs, root, false);
245
+ uint256 piIndex
246
+ ) internal view returns (uint256) {
247
+ for (uint256 i = 0; i < nullifiers.length; i++) {
248
+ publicInputs[piIndex++] = nullifiers[i];
249
+ }
250
+ publicInputs[piIndex++] = ZetoAnonEncNullifierNonRepudiationStorage.layout().dpnr.root;
251
+ return piIndex;
252
+ }
298
253
 
299
- _withdrawWithNullifiers(amount, nullifiers, output, root, proof);
300
- uint256[] memory empty;
301
- processInputsAndOutputs(nullifiers, outputs, empty, address(0));
302
- emit UTXOWithdraw(amount, nullifiers, output, msg.sender, data);
254
+ function _fillEnablesAndOutputs_NR(
255
+ uint256[] memory publicInputs,
256
+ uint256[] memory nullifiers,
257
+ uint256[] memory outputs,
258
+ uint256 piIndex
259
+ ) internal pure returns (uint256) {
260
+ for (uint256 i = 0; i < nullifiers.length; i++) {
261
+ publicInputs[piIndex++] = (nullifiers[i] == 0) ? 0 : 1;
262
+ }
263
+ for (uint256 i = 0; i < outputs.length; i++) {
264
+ publicInputs[piIndex++] = outputs[i];
265
+ }
266
+ return piIndex;
303
267
  }
304
268
 
305
- function mint(
306
- uint256[] memory utxos,
307
- bytes calldata data
308
- ) public onlyOwner {
309
- _mint(utxos, data);
269
+ function _fillNonceAndArbiter_NR(
270
+ uint256[] memory publicInputs,
271
+ uint256 piIndex
272
+ ) internal view {
273
+ publicInputs[piIndex++] = ZetoAnonEncNullifierNonRepudiationStorage.layout().dpnr.encryptionNonce;
274
+ uint256[2] storage arb = ZetoAnonEncNullifierNonRepudiationStorage.layout()
275
+ .arbiter;
276
+ publicInputs[piIndex++] = arb[0];
277
+ publicInputs[piIndex++] = arb[1];
278
+ }
279
+ }
280
+
281
+ /// @dev ERC-7201 (`erc7201:zeto.storage.Zeto_AnonEncNullifierNonRepudiation`).
282
+ library ZetoAnonEncNullifierNonRepudiationStorage {
283
+ struct DecodedProofNonRepudiation {
284
+ uint256 root;
285
+ uint256 encryptionNonce;
286
+ uint256[2] ecdhPublicKey;
287
+ uint256[] encryptedValuesForReceiver;
288
+ uint256[] encryptedValuesForAuthority;
289
+ }
290
+
291
+ struct Layout {
292
+ DecodedProofNonRepudiation dpnr;
293
+ uint256[2] arbiter;
294
+ }
295
+
296
+ bytes32 private constant STORAGE_LOCATION =
297
+ 0x077d29c08c3f481ec46575d42e52007dfbbb47114226730e96bb8e7b43c49600;
298
+
299
+ function layout() internal pure returns (Layout storage $) {
300
+ assembly {
301
+ $.slot := STORAGE_LOCATION
302
+ }
310
303
  }
311
304
  }