@waku/rln 0.1.2 → 0.1.3-f6d5deb

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 (82) hide show
  1. package/bundle/index.js +40916 -39697
  2. package/dist/codec.d.ts +2 -1
  3. package/dist/codec.js +7 -1
  4. package/dist/codec.js.map +1 -1
  5. package/dist/{constants.js → contract/constants.js} +3 -3
  6. package/dist/contract/constants.js.map +1 -0
  7. package/dist/contract/index.d.ts +2 -0
  8. package/dist/contract/index.js +3 -0
  9. package/dist/contract/index.js.map +1 -0
  10. package/dist/{rln_contract.d.ts → contract/rln_contract.d.ts} +3 -2
  11. package/dist/{rln_contract.js → contract/rln_contract.js} +24 -18
  12. package/dist/contract/rln_contract.js.map +1 -0
  13. package/dist/identity.d.ts +9 -0
  14. package/dist/identity.js +24 -0
  15. package/dist/identity.js.map +1 -0
  16. package/dist/index.d.ts +7 -5
  17. package/dist/index.js +7 -5
  18. package/dist/index.js.map +1 -1
  19. package/dist/keystore/cipher.js +1 -1
  20. package/dist/keystore/cipher.js.map +1 -1
  21. package/dist/keystore/credential_validation_generated.js.map +1 -1
  22. package/dist/keystore/keystore.js +21 -18
  23. package/dist/keystore/keystore.js.map +1 -1
  24. package/dist/keystore/keystore_validation_generated.js.map +1 -1
  25. package/dist/keystore/schema_validator.js.map +1 -1
  26. package/dist/keystore/types.d.ts +1 -1
  27. package/dist/message.js +7 -4
  28. package/dist/message.js.map +1 -1
  29. package/dist/proof.d.ts +21 -0
  30. package/dist/proof.js +49 -0
  31. package/dist/proof.js.map +1 -0
  32. package/dist/resources/verification_key.d.ts +9 -9
  33. package/dist/resources/witness_calculator.js.map +1 -0
  34. package/dist/rln.d.ts +6 -48
  35. package/dist/rln.js +25 -194
  36. package/dist/rln.js.map +1 -1
  37. package/dist/root_tracker.js +5 -2
  38. package/dist/root_tracker.js.map +1 -1
  39. package/dist/{byte_utils.d.ts → utils/bytes.d.ts} +7 -1
  40. package/dist/{byte_utils.js → utils/bytes.js} +21 -3
  41. package/dist/utils/bytes.js.map +1 -0
  42. package/dist/utils/epoch.js.map +1 -0
  43. package/dist/utils/hash.d.ts +2 -0
  44. package/dist/utils/hash.js +13 -0
  45. package/dist/utils/hash.js.map +1 -0
  46. package/dist/utils/index.d.ts +4 -0
  47. package/dist/utils/index.js +5 -0
  48. package/dist/utils/index.js.map +1 -0
  49. package/dist/{metamask.js → utils/metamask.js} +1 -0
  50. package/dist/utils/metamask.js.map +1 -0
  51. package/dist/zerokit.d.ts +19 -0
  52. package/dist/zerokit.js +105 -0
  53. package/dist/zerokit.js.map +1 -0
  54. package/package.json +18 -23
  55. package/src/codec.ts +8 -4
  56. package/src/identity.ts +27 -0
  57. package/src/index.ts +8 -12
  58. package/src/message.ts +4 -4
  59. package/src/proof.ts +67 -0
  60. package/src/rln.ts +32 -308
  61. package/src/root_tracker.ts +4 -1
  62. package/src/zerokit.ts +181 -0
  63. package/dist/.tsbuildinfo +0 -1
  64. package/dist/byte_utils.js.map +0 -1
  65. package/dist/constants.js.map +0 -1
  66. package/dist/epoch.js.map +0 -1
  67. package/dist/metamask.js.map +0 -1
  68. package/dist/rln_contract.js.map +0 -1
  69. package/dist/witness_calculator.js.map +0 -1
  70. package/src/byte_utils.ts +0 -63
  71. package/src/constants.ts +0 -68
  72. package/src/epoch.ts +0 -30
  73. package/src/metamask.ts +0 -16
  74. package/src/rln_contract.ts +0 -350
  75. package/src/witness_calculator.d.ts +0 -8
  76. package/src/witness_calculator.js +0 -335
  77. /package/dist/{constants.d.ts → contract/constants.d.ts} +0 -0
  78. /package/dist/{witness_calculator.d.ts → resources/witness_calculator.d.ts} +0 -0
  79. /package/dist/{witness_calculator.js → resources/witness_calculator.js} +0 -0
  80. /package/dist/{epoch.d.ts → utils/epoch.d.ts} +0 -0
  81. /package/dist/{epoch.js → utils/epoch.js} +0 -0
  82. /package/dist/{metamask.d.ts → utils/metamask.d.ts} +0 -0
package/src/rln.ts CHANGED
@@ -1,53 +1,32 @@
1
1
  import { createDecoder, createEncoder } from "@waku/core";
2
- import type { IRateLimitProof } from "@waku/interfaces";
3
2
  import type {
4
3
  ContentTopic,
5
4
  IDecodedMessage,
6
- EncoderOptions as WakuEncoderOptions,
5
+ EncoderOptions as WakuEncoderOptions
7
6
  } from "@waku/interfaces";
8
7
  import init from "@waku/zerokit-rln-wasm";
9
8
  import * as zerokitRLN from "@waku/zerokit-rln-wasm";
10
9
  import { ethers } from "ethers";
11
10
 
12
- import { buildBigIntFromUint8Array, writeUIntLE } from "./byte_utils.js";
13
- import type { RLNDecoder, RLNEncoder } from "./codec.js";
14
- import { createRLNDecoder, createRLNEncoder } from "./codec.js";
15
- import { SEPOLIA_CONTRACT } from "./constants.js";
16
- import { dateToEpoch, epochIntToBytes } from "./epoch.js";
11
+ import {
12
+ createRLNDecoder,
13
+ createRLNEncoder,
14
+ type RLNDecoder,
15
+ type RLNEncoder
16
+ } from "./codec.js";
17
+ import { RLNContract, SEPOLIA_CONTRACT } from "./contract/index.js";
18
+ import { IdentityCredential } from "./identity.js";
17
19
  import { Keystore } from "./keystore/index.js";
18
20
  import type {
19
21
  DecryptedCredentials,
20
- EncryptedCredentials,
22
+ EncryptedCredentials
21
23
  } from "./keystore/index.js";
22
24
  import { KeystoreEntity, Password } from "./keystore/types.js";
23
- import { extractMetaMaskSigner } from "./metamask.js";
24
25
  import verificationKey from "./resources/verification_key.js";
25
- import { RLNContract } from "./rln_contract.js";
26
- import * as wc from "./witness_calculator.js";
27
- import { WitnessCalculator } from "./witness_calculator.js";
28
-
29
- /**
30
- * Concatenate Uint8Arrays
31
- * @param input
32
- * @returns concatenation of all Uint8Array received as input
33
- */
34
- function concatenate(...input: Uint8Array[]): Uint8Array {
35
- let totalLength = 0;
36
- for (const arr of input) {
37
- totalLength += arr.length;
38
- }
39
- const result = new Uint8Array(totalLength);
40
- let offset = 0;
41
- for (const arr of input) {
42
- result.set(arr, offset);
43
- offset += arr.length;
44
- }
45
- return result;
46
- }
47
-
48
- const stringEncoder = new TextEncoder();
49
-
50
- const DEPTH = 20;
26
+ import * as wc from "./resources/witness_calculator.js";
27
+ import { WitnessCalculator } from "./resources/witness_calculator.js";
28
+ import { extractMetaMaskSigner } from "./utils/index.js";
29
+ import { Zerokit } from "./zerokit.js";
51
30
 
52
31
  async function loadWitnessCalculator(): Promise<WitnessCalculator> {
53
32
  const url = new URL("./resources/rln.wasm", import.meta.url);
@@ -66,114 +45,21 @@ async function loadZkey(): Promise<Uint8Array> {
66
45
  * @returns RLNInstance
67
46
  */
68
47
  export async function create(): Promise<RLNInstance> {
48
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
69
49
  await (init as any)?.();
70
50
  zerokitRLN.init_panic_hook();
51
+
71
52
  const witnessCalculator = await loadWitnessCalculator();
72
53
  const zkey = await loadZkey();
73
- const vkey = stringEncoder.encode(JSON.stringify(verificationKey));
74
- const zkRLN = zerokitRLN.newRLN(DEPTH, zkey, vkey);
75
- return new RLNInstance(zkRLN, witnessCalculator);
76
- }
77
54
 
78
- export class IdentityCredential {
79
- constructor(
80
- public readonly IDTrapdoor: Uint8Array,
81
- public readonly IDNullifier: Uint8Array,
82
- public readonly IDSecretHash: Uint8Array,
83
- public readonly IDCommitment: Uint8Array,
84
- public readonly IDCommitmentBigInt: bigint
85
- ) {}
86
-
87
- static fromBytes(memKeys: Uint8Array): IdentityCredential {
88
- const idTrapdoor = memKeys.subarray(0, 32);
89
- const idNullifier = memKeys.subarray(32, 64);
90
- const idSecretHash = memKeys.subarray(64, 96);
91
- const idCommitment = memKeys.subarray(96);
92
- const idCommitmentBigInt = buildBigIntFromUint8Array(idCommitment);
93
-
94
- return new IdentityCredential(
95
- idTrapdoor,
96
- idNullifier,
97
- idSecretHash,
98
- idCommitment,
99
- idCommitmentBigInt
100
- );
101
- }
102
- }
103
-
104
- const proofOffset = 128;
105
- const rootOffset = proofOffset + 32;
106
- const epochOffset = rootOffset + 32;
107
- const shareXOffset = epochOffset + 32;
108
- const shareYOffset = shareXOffset + 32;
109
- const nullifierOffset = shareYOffset + 32;
110
- const rlnIdentifierOffset = nullifierOffset + 32;
111
-
112
- export class ProofMetadata {
113
- constructor(
114
- public readonly nullifier: Uint8Array,
115
- public readonly shareX: Uint8Array,
116
- public readonly shareY: Uint8Array,
117
- public readonly externalNullifier: Uint8Array
118
- ) {}
119
- }
120
- export class Proof implements IRateLimitProof {
121
- readonly proof: Uint8Array;
122
- readonly merkleRoot: Uint8Array;
123
- readonly epoch: Uint8Array;
124
- readonly shareX: Uint8Array;
125
- readonly shareY: Uint8Array;
126
- readonly nullifier: Uint8Array;
127
- readonly rlnIdentifier: Uint8Array;
128
-
129
- constructor(proofBytes: Uint8Array) {
130
- if (proofBytes.length < rlnIdentifierOffset) throw "invalid proof";
131
- // parse the proof as proof<128> | share_y<32> | nullifier<32> | root<32> | epoch<32> | share_x<32> | rln_identifier<32>
132
- this.proof = proofBytes.subarray(0, proofOffset);
133
- this.merkleRoot = proofBytes.subarray(proofOffset, rootOffset);
134
- this.epoch = proofBytes.subarray(rootOffset, epochOffset);
135
- this.shareX = proofBytes.subarray(epochOffset, shareXOffset);
136
- this.shareY = proofBytes.subarray(shareXOffset, shareYOffset);
137
- this.nullifier = proofBytes.subarray(shareYOffset, nullifierOffset);
138
- this.rlnIdentifier = proofBytes.subarray(
139
- nullifierOffset,
140
- rlnIdentifierOffset
141
- );
142
- }
143
-
144
- extractMetadata(): ProofMetadata {
145
- const externalNullifier = poseidonHash(this.epoch, this.rlnIdentifier);
146
- return new ProofMetadata(
147
- this.nullifier,
148
- this.shareX,
149
- this.shareY,
150
- externalNullifier
151
- );
152
- }
153
- }
154
-
155
- export function proofToBytes(p: IRateLimitProof): Uint8Array {
156
- return concatenate(
157
- p.proof,
158
- p.merkleRoot,
159
- p.epoch,
160
- p.shareX,
161
- p.shareY,
162
- p.nullifier,
163
- p.rlnIdentifier
164
- );
165
- }
55
+ const stringEncoder = new TextEncoder();
56
+ const vkey = stringEncoder.encode(JSON.stringify(verificationKey));
166
57
 
167
- export function poseidonHash(...input: Array<Uint8Array>): Uint8Array {
168
- const inputLen = writeUIntLE(new Uint8Array(8), input.length, 0, 8);
169
- const lenPrefixedData = concatenate(inputLen, ...input);
170
- return zerokitRLN.poseidonHash(lenPrefixedData);
171
- }
58
+ const DEPTH = 20;
59
+ const zkRLN = zerokitRLN.newRLN(DEPTH, zkey, vkey);
60
+ const zerokit = new Zerokit(zkRLN, witnessCalculator);
172
61
 
173
- export function sha256(input: Uint8Array): Uint8Array {
174
- const inputLen = writeUIntLE(new Uint8Array(8), input.length, 0, 8);
175
- const lenPrefixedData = concatenate(inputLen, input);
176
- return zerokitRLN.hash(lenPrefixedData);
62
+ return new RLNInstance(zerokit);
177
63
  }
178
64
 
179
65
  type StartRLNOptions = {
@@ -210,10 +96,7 @@ export class RLNInstance {
210
96
  private keystore = Keystore.create();
211
97
  private _credentials: undefined | DecryptedCredentials;
212
98
 
213
- constructor(
214
- private zkRLN: number,
215
- private witnessCalculator: WitnessCalculator
216
- ) {}
99
+ constructor(public zerokit: Zerokit) {}
217
100
 
218
101
  public get contract(): undefined | RLNContract {
219
102
  return this._contract;
@@ -246,7 +129,7 @@ export class RLNInstance {
246
129
  this._signer = signer!;
247
130
  this._contract = await RLNContract.init(this, {
248
131
  registryAddress: registryAddress!,
249
- signer: signer!,
132
+ signer: signer!
250
133
  });
251
134
  this.started = true;
252
135
  } finally {
@@ -279,7 +162,7 @@ export class RLNInstance {
279
162
 
280
163
  return {
281
164
  signer,
282
- registryAddress,
165
+ registryAddress
283
166
  };
284
167
  }
285
168
 
@@ -307,7 +190,7 @@ export class RLNInstance {
307
190
 
308
191
  return {
309
192
  keystore,
310
- credentials: decryptedCredentials,
193
+ credentials: decryptedCredentials
311
194
  };
312
195
  }
313
196
 
@@ -321,7 +204,9 @@ export class RLNInstance {
321
204
  let identity = "identity" in options && options.identity;
322
205
 
323
206
  if ("signature" in options) {
324
- identity = await this.generateSeededIdentityCredential(options.signature);
207
+ identity = this.zerokit.generateSeededIdentityCredential(
208
+ options.signature
209
+ );
325
210
  }
326
211
 
327
212
  if (!identity) {
@@ -359,7 +244,7 @@ export class RLNInstance {
359
244
  encoder: createEncoder(options),
360
245
  rlnInstance: this,
361
246
  index: credentials.membership.treeIndex,
362
- credential: credentials.identity,
247
+ credential: credentials.identity
363
248
  });
364
249
  }
365
250
 
@@ -381,7 +266,7 @@ export class RLNInstance {
381
266
  }
382
267
 
383
268
  const chainId = credentials.membership.chainId;
384
- const network = await this._contract.registry.getNetwork();
269
+ const network = await this._contract.registry.provider.getNetwork();
385
270
  const currentChainId = network.chainId;
386
271
  if (chainId !== currentChainId) {
387
272
  throw Error(
@@ -395,168 +280,7 @@ export class RLNInstance {
395
280
  ): RLNDecoder<IDecodedMessage> {
396
281
  return createRLNDecoder({
397
282
  rlnInstance: this,
398
- decoder: createDecoder(contentTopic),
283
+ decoder: createDecoder(contentTopic)
399
284
  });
400
285
  }
401
-
402
- generateIdentityCredentials(): IdentityCredential {
403
- const memKeys = zerokitRLN.generateExtendedMembershipKey(this.zkRLN); // TODO: rename this function in zerokit rln-wasm
404
- return IdentityCredential.fromBytes(memKeys);
405
- }
406
-
407
- generateSeededIdentityCredential(seed: string): IdentityCredential {
408
- const seedBytes = stringEncoder.encode(seed);
409
- // TODO: rename this function in zerokit rln-wasm
410
- const memKeys = zerokitRLN.generateSeededExtendedMembershipKey(
411
- this.zkRLN,
412
- seedBytes
413
- );
414
- return IdentityCredential.fromBytes(memKeys);
415
- }
416
-
417
- insertMember(idCommitment: Uint8Array): void {
418
- zerokitRLN.insertMember(this.zkRLN, idCommitment);
419
- }
420
-
421
- insertMembers(index: number, ...idCommitments: Array<Uint8Array>): void {
422
- // serializes a seq of IDCommitments to a byte seq
423
- // the order of serialization is |id_commitment_len<8>|id_commitment<var>|
424
- const idCommitmentLen = writeUIntLE(
425
- new Uint8Array(8),
426
- idCommitments.length,
427
- 0,
428
- 8
429
- );
430
- const idCommitmentBytes = concatenate(idCommitmentLen, ...idCommitments);
431
- zerokitRLN.setLeavesFrom(this.zkRLN, index, idCommitmentBytes);
432
- }
433
-
434
- deleteMember(index: number): void {
435
- zerokitRLN.deleteLeaf(this.zkRLN, index);
436
- }
437
-
438
- getMerkleRoot(): Uint8Array {
439
- return zerokitRLN.getRoot(this.zkRLN);
440
- }
441
-
442
- serializeMessage(
443
- uint8Msg: Uint8Array,
444
- memIndex: number,
445
- epoch: Uint8Array,
446
- idKey: Uint8Array
447
- ): Uint8Array {
448
- // calculate message length
449
- const msgLen = writeUIntLE(new Uint8Array(8), uint8Msg.length, 0, 8);
450
-
451
- // Converting index to LE bytes
452
- const memIndexBytes = writeUIntLE(new Uint8Array(8), memIndex, 0, 8);
453
-
454
- // [ id_key<32> | id_index<8> | epoch<32> | signal_len<8> | signal<var> ]
455
- return concatenate(idKey, memIndexBytes, epoch, msgLen, uint8Msg);
456
- }
457
-
458
- async generateRLNProof(
459
- msg: Uint8Array,
460
- index: number,
461
- epoch: Uint8Array | Date | undefined,
462
- idSecretHash: Uint8Array
463
- ): Promise<IRateLimitProof> {
464
- if (epoch == undefined) {
465
- epoch = epochIntToBytes(dateToEpoch(new Date()));
466
- } else if (epoch instanceof Date) {
467
- epoch = epochIntToBytes(dateToEpoch(epoch));
468
- }
469
-
470
- if (epoch.length != 32) throw "invalid epoch";
471
- if (idSecretHash.length != 32) throw "invalid id secret hash";
472
- if (index < 0) throw "index must be >= 0";
473
-
474
- const serialized_msg = this.serializeMessage(
475
- msg,
476
- index,
477
- epoch,
478
- idSecretHash
479
- );
480
- const rlnWitness = zerokitRLN.getSerializedRLNWitness(
481
- this.zkRLN,
482
- serialized_msg
483
- );
484
- const inputs = zerokitRLN.RLNWitnessToJson(this.zkRLN, rlnWitness);
485
- const calculatedWitness = await this.witnessCalculator.calculateWitness(
486
- inputs,
487
- false
488
- ); // no sanity check being used in zerokit
489
-
490
- const proofBytes = zerokitRLN.generate_rln_proof_with_witness(
491
- this.zkRLN,
492
- calculatedWitness,
493
- rlnWitness
494
- );
495
-
496
- return new Proof(proofBytes);
497
- }
498
-
499
- verifyRLNProof(
500
- proof: IRateLimitProof | Uint8Array,
501
- msg: Uint8Array
502
- ): boolean {
503
- let pBytes: Uint8Array;
504
- if (proof instanceof Uint8Array) {
505
- pBytes = proof;
506
- } else {
507
- pBytes = proofToBytes(proof);
508
- }
509
-
510
- // calculate message length
511
- const msgLen = writeUIntLE(new Uint8Array(8), msg.length, 0, 8);
512
-
513
- return zerokitRLN.verifyRLNProof(
514
- this.zkRLN,
515
- concatenate(pBytes, msgLen, msg)
516
- );
517
- }
518
-
519
- verifyWithRoots(
520
- proof: IRateLimitProof | Uint8Array,
521
- msg: Uint8Array,
522
- ...roots: Array<Uint8Array>
523
- ): boolean {
524
- let pBytes: Uint8Array;
525
- if (proof instanceof Uint8Array) {
526
- pBytes = proof;
527
- } else {
528
- pBytes = proofToBytes(proof);
529
- }
530
- // calculate message length
531
- const msgLen = writeUIntLE(new Uint8Array(8), msg.length, 0, 8);
532
-
533
- const rootsBytes = concatenate(...roots);
534
-
535
- return zerokitRLN.verifyWithRoots(
536
- this.zkRLN,
537
- concatenate(pBytes, msgLen, msg),
538
- rootsBytes
539
- );
540
- }
541
-
542
- verifyWithNoRoot(
543
- proof: IRateLimitProof | Uint8Array,
544
- msg: Uint8Array
545
- ): boolean {
546
- let pBytes: Uint8Array;
547
- if (proof instanceof Uint8Array) {
548
- pBytes = proof;
549
- } else {
550
- pBytes = proofToBytes(proof);
551
- }
552
-
553
- // calculate message length
554
- const msgLen = writeUIntLE(new Uint8Array(8), msg.length, 0, 8);
555
-
556
- return zerokitRLN.verifyWithRoots(
557
- this.zkRLN,
558
- concatenate(pBytes, msgLen, msg),
559
- new Uint8Array()
560
- );
561
- }
562
286
  }
@@ -1,5 +1,8 @@
1
1
  class RootPerBlock {
2
- constructor(public root: Uint8Array, public blockNumber: number) {}
2
+ constructor(
3
+ public root: Uint8Array,
4
+ public blockNumber: number
5
+ ) {}
3
6
  }
4
7
 
5
8
  const maxBufferSize = 20;
package/src/zerokit.ts ADDED
@@ -0,0 +1,181 @@
1
+ import type { IRateLimitProof } from "@waku/interfaces";
2
+ import * as zerokitRLN from "@waku/zerokit-rln-wasm";
3
+
4
+ import { IdentityCredential } from "./identity.js";
5
+ import { Proof, proofToBytes } from "./proof.js";
6
+ import { WitnessCalculator } from "./resources/witness_calculator.js";
7
+ import {
8
+ concatenate,
9
+ dateToEpoch,
10
+ epochIntToBytes,
11
+ writeUIntLE
12
+ } from "./utils/index.js";
13
+
14
+ export class Zerokit {
15
+ constructor(
16
+ private zkRLN: number,
17
+ private witnessCalculator: WitnessCalculator
18
+ ) {}
19
+
20
+ generateIdentityCredentials(): IdentityCredential {
21
+ const memKeys = zerokitRLN.generateExtendedMembershipKey(this.zkRLN); // TODO: rename this function in zerokit rln-wasm
22
+ return IdentityCredential.fromBytes(memKeys);
23
+ }
24
+
25
+ generateSeededIdentityCredential(seed: string): IdentityCredential {
26
+ const stringEncoder = new TextEncoder();
27
+ const seedBytes = stringEncoder.encode(seed);
28
+ // TODO: rename this function in zerokit rln-wasm
29
+ const memKeys = zerokitRLN.generateSeededExtendedMembershipKey(
30
+ this.zkRLN,
31
+ seedBytes
32
+ );
33
+ return IdentityCredential.fromBytes(memKeys);
34
+ }
35
+
36
+ insertMember(idCommitment: Uint8Array): void {
37
+ zerokitRLN.insertMember(this.zkRLN, idCommitment);
38
+ }
39
+
40
+ insertMembers(index: number, ...idCommitments: Array<Uint8Array>): void {
41
+ // serializes a seq of IDCommitments to a byte seq
42
+ // the order of serialization is |id_commitment_len<8>|id_commitment<var>|
43
+ const idCommitmentLen = writeUIntLE(
44
+ new Uint8Array(8),
45
+ idCommitments.length,
46
+ 0,
47
+ 8
48
+ );
49
+ const idCommitmentBytes = concatenate(idCommitmentLen, ...idCommitments);
50
+ zerokitRLN.setLeavesFrom(this.zkRLN, index, idCommitmentBytes);
51
+ }
52
+
53
+ deleteMember(index: number): void {
54
+ zerokitRLN.deleteLeaf(this.zkRLN, index);
55
+ }
56
+
57
+ getMerkleRoot(): Uint8Array {
58
+ return zerokitRLN.getRoot(this.zkRLN);
59
+ }
60
+
61
+ serializeMessage(
62
+ uint8Msg: Uint8Array,
63
+ memIndex: number,
64
+ epoch: Uint8Array,
65
+ idKey: Uint8Array
66
+ ): Uint8Array {
67
+ // calculate message length
68
+ const msgLen = writeUIntLE(new Uint8Array(8), uint8Msg.length, 0, 8);
69
+
70
+ // Converting index to LE bytes
71
+ const memIndexBytes = writeUIntLE(new Uint8Array(8), memIndex, 0, 8);
72
+
73
+ // [ id_key<32> | id_index<8> | epoch<32> | signal_len<8> | signal<var> ]
74
+ return concatenate(idKey, memIndexBytes, epoch, msgLen, uint8Msg);
75
+ }
76
+
77
+ async generateRLNProof(
78
+ msg: Uint8Array,
79
+ index: number,
80
+ epoch: Uint8Array | Date | undefined,
81
+ idSecretHash: Uint8Array
82
+ ): Promise<IRateLimitProof> {
83
+ if (epoch == undefined) {
84
+ epoch = epochIntToBytes(dateToEpoch(new Date()));
85
+ } else if (epoch instanceof Date) {
86
+ epoch = epochIntToBytes(dateToEpoch(epoch));
87
+ }
88
+
89
+ if (epoch.length != 32) throw "invalid epoch";
90
+ if (idSecretHash.length != 32) throw "invalid id secret hash";
91
+ if (index < 0) throw "index must be >= 0";
92
+
93
+ const serialized_msg = this.serializeMessage(
94
+ msg,
95
+ index,
96
+ epoch,
97
+ idSecretHash
98
+ );
99
+ const rlnWitness = zerokitRLN.getSerializedRLNWitness(
100
+ this.zkRLN,
101
+ serialized_msg
102
+ );
103
+ const inputs = zerokitRLN.RLNWitnessToJson(this.zkRLN, rlnWitness);
104
+ const calculatedWitness = await this.witnessCalculator.calculateWitness(
105
+ inputs,
106
+ false
107
+ ); // no sanity check being used in zerokit
108
+
109
+ const proofBytes = zerokitRLN.generate_rln_proof_with_witness(
110
+ this.zkRLN,
111
+ calculatedWitness,
112
+ rlnWitness
113
+ );
114
+
115
+ return new Proof(proofBytes);
116
+ }
117
+
118
+ verifyRLNProof(
119
+ proof: IRateLimitProof | Uint8Array,
120
+ msg: Uint8Array
121
+ ): boolean {
122
+ let pBytes: Uint8Array;
123
+ if (proof instanceof Uint8Array) {
124
+ pBytes = proof;
125
+ } else {
126
+ pBytes = proofToBytes(proof);
127
+ }
128
+
129
+ // calculate message length
130
+ const msgLen = writeUIntLE(new Uint8Array(8), msg.length, 0, 8);
131
+
132
+ return zerokitRLN.verifyRLNProof(
133
+ this.zkRLN,
134
+ concatenate(pBytes, msgLen, msg)
135
+ );
136
+ }
137
+
138
+ verifyWithRoots(
139
+ proof: IRateLimitProof | Uint8Array,
140
+ msg: Uint8Array,
141
+ ...roots: Array<Uint8Array>
142
+ ): boolean {
143
+ let pBytes: Uint8Array;
144
+ if (proof instanceof Uint8Array) {
145
+ pBytes = proof;
146
+ } else {
147
+ pBytes = proofToBytes(proof);
148
+ }
149
+ // calculate message length
150
+ const msgLen = writeUIntLE(new Uint8Array(8), msg.length, 0, 8);
151
+
152
+ const rootsBytes = concatenate(...roots);
153
+
154
+ return zerokitRLN.verifyWithRoots(
155
+ this.zkRLN,
156
+ concatenate(pBytes, msgLen, msg),
157
+ rootsBytes
158
+ );
159
+ }
160
+
161
+ verifyWithNoRoot(
162
+ proof: IRateLimitProof | Uint8Array,
163
+ msg: Uint8Array
164
+ ): boolean {
165
+ let pBytes: Uint8Array;
166
+ if (proof instanceof Uint8Array) {
167
+ pBytes = proof;
168
+ } else {
169
+ pBytes = proofToBytes(proof);
170
+ }
171
+
172
+ // calculate message length
173
+ const msgLen = writeUIntLE(new Uint8Array(8), msg.length, 0, 8);
174
+
175
+ return zerokitRLN.verifyWithRoots(
176
+ this.zkRLN,
177
+ concatenate(pBytes, msgLen, msg),
178
+ new Uint8Array()
179
+ );
180
+ }
181
+ }