@arcanetech/stellar-privacy-pool-zk-sdk 0.11.4 → 1.0.0-rc.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.
package/dist/cli.js CHANGED
@@ -1395,11 +1395,11 @@ async function fetchArtifact(url) {
1395
1395
  }
1396
1396
 
1397
1397
  const ZK_ARTIFACT_GITHUB_REPO = "Polynom-Labs/stellar-pool-zk-sdk";
1398
- const ZK_SDK_PACKAGE_VERSION = "0.11.4";
1398
+ const ZK_SDK_PACKAGE_VERSION = "1.0.0-rc.0";
1399
1399
  const ZK_ARTIFACT_CDN_ORIGIN = "https://static.pl.arcane.finance";
1400
1400
  const ZK_DEFAULT_ARTIFACT_BASE_URL = "https://static.pl.arcane.finance/stellar/0.10.0";
1401
1401
  /** Injected at publish time: stem -> { version, kind, fingerprint? }. */
1402
- const ZK_CIRCUITS_MANIFEST_JSON = "{\"main\":{\"version\":\"0.10.0\",\"kind\":\"direct\"},\"main_10x1\":{\"version\":\"0.11.2\",\"kind\":\"direct\"},\"main_10x1_delegated\":{\"version\":\"0.11.2\",\"kind\":\"delegated\"},\"main_6x6\":{\"version\":\"0.10.0\",\"kind\":\"direct\"},\"main_6x6_delegated\":{\"version\":\"0.10.0\",\"kind\":\"delegated\"},\"main_delegated\":{\"version\":\"0.10.0\",\"kind\":\"delegated\"}}";
1402
+ const ZK_CIRCUITS_MANIFEST_JSON = "{\"main\":{\"version\":\"0.10.0\",\"kind\":\"direct\"},\"main_10x1\":{\"version\":\"1.0.0-rc.0\",\"kind\":\"direct\"},\"main_10x1_delegated\":{\"version\":\"1.0.0-rc.0\",\"kind\":\"delegated\"},\"main_6x6\":{\"version\":\"0.10.0\",\"kind\":\"direct\"},\"main_6x6_delegated\":{\"version\":\"0.10.0\",\"kind\":\"delegated\"},\"main_delegated\":{\"version\":\"0.10.0\",\"kind\":\"delegated\"}}";
1403
1403
  function parsedCircuitsManifest() {
1404
1404
  if (ZK_CIRCUITS_MANIFEST_JSON.length === 0 ||
1405
1405
  ZK_CIRCUITS_MANIFEST_JSON.startsWith("__ZK_")) {
@@ -1960,6 +1960,13 @@ function recipientPublicKeysDecimalFromStealthAddress(stealthAddress) {
1960
1960
  }
1961
1961
  /** First withdraw leg: Merkle witness + owner public key (hex) and matching scalar. */
1962
1962
  function withdrawObjectFromMerkleWitness(witness, ownerPubHex, applicationId, privKeyScalar) {
1963
+ return buildWithdrawObject(witness, ownerPubHex, applicationId, {
1964
+ privKeyScalar,
1965
+ escrowNonce: '0',
1966
+ recipientStellar: ['0', '0'],
1967
+ });
1968
+ }
1969
+ function buildWithdrawObject(witness, ownerPubHex, applicationId, spend) {
1963
1970
  return {
1964
1971
  value: witness.value,
1965
1972
  nullifier: witness.nullifier,
@@ -1967,10 +1974,10 @@ function withdrawObjectFromMerkleWitness(witness, ownerPubHex, applicationId, pr
1967
1974
  asset: witness.withdrawnAsset,
1968
1975
  applicationId,
1969
1976
  ownerPub: [coordHexToDecimal(ownerPubHex.x), coordHexToDecimal(ownerPubHex.y)],
1970
- privKeyScalar,
1977
+ privKeyScalar: spend.privKeyScalar,
1971
1978
  paddingRandom: randomFrDecimal(),
1972
- escrowNonce: '0',
1973
- recipientStellar: ['0', '0'],
1979
+ escrowNonce: spend.escrowNonce,
1980
+ recipientStellar: spend.recipientStellar,
1974
1981
  stateSiblings: witness.stateSiblings,
1975
1982
  stateIndex: witness.stateIndex,
1976
1983
  };
@@ -2101,19 +2108,48 @@ function outputNoteTag(parameters) {
2101
2108
  message: parameters.plaintext,
2102
2109
  });
2103
2110
  }
2111
+ function keystreamForOutputNoteField(parameters) {
2112
+ return poseidonHash(parameters.poseidon, [
2113
+ parameters.nonce,
2114
+ STREAM_DOMAIN,
2115
+ BigInt(parameters.fieldIndex),
2116
+ ]);
2117
+ }
2118
+ function keystreamForAuditSlotField(parameters) {
2119
+ return poseidonHash(parameters.poseidon, [
2120
+ parameters.nonce,
2121
+ STREAM_DOMAIN,
2122
+ parameters.slotIndex,
2123
+ BigInt(parameters.fieldIndex),
2124
+ ]);
2125
+ }
2104
2126
  function encryptFields(parameters) {
2105
2127
  return parameters.plaintext.map((field, index) => {
2106
- const seed = poseidonHash(parameters.poseidon, [
2107
- parameters.nonce,
2108
- STREAM_DOMAIN,
2109
- BigInt(index),
2110
- ]);
2111
- const stream = mimcHash({
2128
+ const keystream = mimcHash({
2112
2129
  mimc7: parameters.mimc7,
2113
- message: seed,
2130
+ message: keystreamForOutputNoteField({
2131
+ poseidon: parameters.poseidon,
2132
+ nonce: parameters.nonce,
2133
+ fieldIndex: index,
2134
+ }),
2114
2135
  key: parameters.key,
2115
2136
  });
2116
- return moduleFr(field + stream);
2137
+ return moduleFr(field + keystream);
2138
+ });
2139
+ }
2140
+ function encryptAuditSlotFields(parameters) {
2141
+ return parameters.plaintext.map((field, index) => {
2142
+ const keystream = mimcHash({
2143
+ mimc7: parameters.mimc7,
2144
+ message: keystreamForAuditSlotField({
2145
+ poseidon: parameters.poseidon,
2146
+ nonce: parameters.nonce,
2147
+ slotIndex: parameters.slotIndex,
2148
+ fieldIndex: index,
2149
+ }),
2150
+ key: parameters.key,
2151
+ });
2152
+ return moduleFr(field + keystream);
2117
2153
  });
2118
2154
  }
2119
2155
  function plaintextBigints(plaintext) {
@@ -2175,21 +2211,42 @@ function precommitmentFromOpening(parameters) {
2175
2211
  ownerKeyHash,
2176
2212
  ]);
2177
2213
  }
2214
+ function deriveSharedAuditKey(parameters) {
2215
+ const [sharedX, sharedY] = sharedKeyFromDepositor({
2216
+ babyJub: parameters.babyJub,
2217
+ ecdhShared: parameters.ecdhShared,
2218
+ ephemeralKeyScalarDecimal: parameters.auditEphemeralScalar,
2219
+ recipientPublicKey: parameters.auditPublicKey,
2220
+ });
2221
+ return {
2222
+ key: deriveEncCipherKey(parameters.poseidon, sharedX),
2223
+ nonce: sharedY,
2224
+ };
2225
+ }
2178
2226
  async function encryptNoteAuditSlot(parameters) {
2179
2227
  if (parameters.plaintext.length !== NOTE_AUDIT_LEN) {
2180
2228
  throw new Error(`encryptNoteAuditSlot: expected ${String(NOTE_AUDIT_LEN)} limbs`);
2181
2229
  }
2230
+ if (!Number.isInteger(parameters.slotIndex) || parameters.slotIndex < 0) {
2231
+ throw new Error('encryptNoteAuditSlot: slotIndex must be a non-negative integer');
2232
+ }
2182
2233
  const { babyJub, mimc7, poseidon } = await primitives();
2183
- const [sharedX, sharedY] = sharedKeyFromDepositor({
2234
+ const { key, nonce } = deriveSharedAuditKey({
2184
2235
  babyJub,
2236
+ poseidon,
2237
+ auditPublicKey: parameters.auditPublicKey,
2238
+ auditEphemeralScalar: parameters.auditEphemeralScalar,
2185
2239
  ecdhShared: parameters.ecdhShared,
2186
- ephemeralKeyScalarDecimal: parameters.auditEphemeralScalar,
2187
- recipientPublicKey: parameters.auditPublicKey,
2188
2240
  });
2189
- const key = deriveEncCipherKey(poseidon, sharedX);
2190
- const nonce = sharedY;
2191
2241
  const message = parameters.plaintext.map((field) => bigintFromDecimal(field));
2192
- const ciphertext = encryptFields({ mimc7, poseidon, key, nonce, plaintext: message });
2242
+ const ciphertext = encryptAuditSlotFields({
2243
+ mimc7,
2244
+ poseidon,
2245
+ key,
2246
+ nonce,
2247
+ plaintext: message,
2248
+ slotIndex: BigInt(parameters.slotIndex),
2249
+ });
2193
2250
  const tag = poseidonMacTag({
2194
2251
  poseidon,
2195
2252
  domain: DOM_AUDIT_TAG,
@@ -2284,6 +2341,7 @@ async function encryptTransactionCiphertextBlob(parameters) {
2284
2341
  auditPublicKey: parameters.witness.noteAuditPublicKey,
2285
2342
  auditEphemeralScalar: parameters.witness.auditEphemeralScalar,
2286
2343
  plaintext,
2344
+ slotIndex: slot,
2287
2345
  ecdhShared: parameters.ecdhShared,
2288
2346
  });
2289
2347
  auditCiphertexts.push(encrypted.ciphertext);