@waku/rln 0.0.6 → 0.0.8-378ad04

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/rln.js CHANGED
@@ -1,20 +1,8 @@
1
1
  import init, * as zerokitRLN from "@waku/zerokit-rln-wasm";
2
- import * as resources from "./resources.js";
2
+ import { writeUIntLE } from "./byte_utils.js";
3
+ import { dateToEpoch, epochIntToBytes } from "./epoch.js";
4
+ import verificationKey from "./resources/verification_key.js";
3
5
  import * as wc from "./witness_calculator.js";
4
- /**
5
- * Convert a base64 string into uint8Array
6
- * @param base64
7
- * @returns Uint8Array
8
- */
9
- function base64ToUint8Array(base64) {
10
- const binary_string = window.atob(base64);
11
- const len = binary_string.length;
12
- const bytes = new Uint8Array(len);
13
- for (let i = 0; i < len; i++) {
14
- bytes[i] = binary_string.charCodeAt(i);
15
- }
16
- return bytes;
17
- }
18
6
  /**
19
7
  * Concatenate Uint8Arrays
20
8
  * @param input
@@ -33,10 +21,18 @@ function concatenate(...input) {
33
21
  }
34
22
  return result;
35
23
  }
24
+ const stringEncoder = new TextEncoder();
36
25
  const DEPTH = 20;
37
- const VERIFICATION_KEY = base64ToUint8Array(resources.verification_key);
38
- const ZKEY = base64ToUint8Array(resources.zkey);
39
- const CIRCUIT = base64ToUint8Array(resources.circuit);
26
+ async function loadWitnessCalculator() {
27
+ const url = new URL("./resources/rln.wasm", import.meta.url);
28
+ const response = await fetch(url);
29
+ return await wc.builder(new Uint8Array(await response.arrayBuffer()), false);
30
+ }
31
+ async function loadZkey() {
32
+ const url = new URL("./resources/rln_final.zkey", import.meta.url);
33
+ const response = await fetch(url);
34
+ return new Uint8Array(await response.arrayBuffer());
35
+ }
40
36
  /**
41
37
  * Create an instance of RLN
42
38
  * @returns RLNInstance
@@ -44,43 +40,22 @@ const CIRCUIT = base64ToUint8Array(resources.circuit);
44
40
  export async function create() {
45
41
  await init();
46
42
  zerokitRLN.init_panic_hook();
47
- const witnessCalculator = await wc.builder(CIRCUIT, false);
48
- const zkRLN = zerokitRLN.newRLN(DEPTH, ZKEY, VERIFICATION_KEY);
43
+ const witnessCalculator = await loadWitnessCalculator();
44
+ const zkey = await loadZkey();
45
+ const vkey = stringEncoder.encode(JSON.stringify(verificationKey));
46
+ const zkRLN = zerokitRLN.newRLN(DEPTH, zkey, vkey);
49
47
  return new RLNInstance(zkRLN, witnessCalculator);
50
48
  }
51
49
  export class MembershipKey {
52
- constructor(memKeys) {
53
- this.IDKey = memKeys.subarray(0, 32);
54
- this.IDCommitment = memKeys.subarray(32);
50
+ constructor(IDKey, IDCommitment) {
51
+ this.IDKey = IDKey;
52
+ this.IDCommitment = IDCommitment;
55
53
  }
56
- }
57
- // Adapted from https://github.com/feross/buffer
58
- function checkInt(buf, value, offset, ext, max, min) {
59
- if (value > max || value < min)
60
- throw new RangeError('"value" argument is out of bounds');
61
- if (offset + ext > buf.length)
62
- throw new RangeError("Index out of range");
63
- }
64
- const writeUIntLE = function writeUIntLE(buf, value, offset, byteLength, noAssert) {
65
- value = +value;
66
- offset = offset >>> 0;
67
- byteLength = byteLength >>> 0;
68
- if (!noAssert) {
69
- const maxBytes = Math.pow(2, 8 * byteLength) - 1;
70
- checkInt(buf, value, offset, byteLength, maxBytes, 0);
71
- }
72
- let mul = 1;
73
- let i = 0;
74
- buf[offset] = value & 0xff;
75
- while (++i < byteLength && (mul *= 0x100)) {
76
- buf[offset + i] = (value / mul) & 0xff;
54
+ static fromBytes(memKeys) {
55
+ const idKey = memKeys.subarray(0, 32);
56
+ const idCommitment = memKeys.subarray(32);
57
+ return new MembershipKey(idKey, idCommitment);
77
58
  }
78
- return buf;
79
- };
80
- const DefaultEpochUnitSeconds = 10; // the rln-relay epoch length in seconds
81
- export function toEpoch(timestamp, epochUnitSeconds = DefaultEpochUnitSeconds) {
82
- const unix = Math.floor(timestamp.getTime() / 1000 / epochUnitSeconds);
83
- return writeUIntLE(new Uint8Array(32), unix, 0, 8);
84
59
  }
85
60
  const proofOffset = 128;
86
61
  const rootOffset = proofOffset + 32;
@@ -89,7 +64,7 @@ const shareXOffset = epochOffset + 32;
89
64
  const shareYOffset = shareXOffset + 32;
90
65
  const nullifierOffset = shareYOffset + 32;
91
66
  const rlnIdentifierOffset = nullifierOffset + 32;
92
- export class RateLimitProof {
67
+ export class Proof {
93
68
  constructor(proofBytes) {
94
69
  if (proofBytes.length < rlnIdentifierOffset)
95
70
  throw "invalid proof";
@@ -102,9 +77,9 @@ export class RateLimitProof {
102
77
  this.nullifier = proofBytes.subarray(shareYOffset, nullifierOffset);
103
78
  this.rlnIdentifier = proofBytes.subarray(nullifierOffset, rlnIdentifierOffset);
104
79
  }
105
- toBytes() {
106
- return concatenate(this.proof, this.merkleRoot, this.epoch, this.shareX, this.shareY, this.nullifier, this.rlnIdentifier);
107
- }
80
+ }
81
+ function proofToBytes(p) {
82
+ return concatenate(p.proof, p.merkleRoot, p.epoch, p.shareX, p.shareY, p.nullifier, p.rlnIdentifier);
108
83
  }
109
84
  export class RLNInstance {
110
85
  constructor(zkRLN, witnessCalculator) {
@@ -113,7 +88,7 @@ export class RLNInstance {
113
88
  }
114
89
  generateMembershipKey() {
115
90
  const memKeys = zerokitRLN.generateMembershipKey(this.zkRLN);
116
- return new MembershipKey(memKeys);
91
+ return MembershipKey.fromBytes(memKeys);
117
92
  }
118
93
  insertMember(idCommitment) {
119
94
  zerokitRLN.insertMember(this.zkRLN, idCommitment);
@@ -128,10 +103,10 @@ export class RLNInstance {
128
103
  }
129
104
  async generateProof(msg, index, epoch, idKey) {
130
105
  if (epoch == undefined) {
131
- epoch = toEpoch(new Date());
106
+ epoch = epochIntToBytes(dateToEpoch(new Date()));
132
107
  }
133
108
  else if (epoch instanceof Date) {
134
- epoch = toEpoch(epoch);
109
+ epoch = epochIntToBytes(dateToEpoch(epoch));
135
110
  }
136
111
  if (epoch.length != 32)
137
112
  throw "invalid epoch";
@@ -144,13 +119,17 @@ export class RLNInstance {
144
119
  const inputs = zerokitRLN.RLNWitnessToJson(this.zkRLN, rlnWitness);
145
120
  const calculatedWitness = await this.witnessCalculator.calculateWitness(inputs, false); // no sanity check being used in zerokit
146
121
  const proofBytes = zerokitRLN.generate_rln_proof_with_witness(this.zkRLN, calculatedWitness, rlnWitness);
147
- return new RateLimitProof(proofBytes);
122
+ return new Proof(proofBytes);
148
123
  }
149
124
  verifyProof(proof) {
150
- if (proof instanceof RateLimitProof) {
151
- proof = proof.toBytes();
125
+ let pBytes;
126
+ if (proof instanceof Uint8Array) {
127
+ pBytes = proof;
128
+ }
129
+ else {
130
+ pBytes = proofToBytes(proof);
152
131
  }
153
- return zerokitRLN.verifyProof(this.zkRLN, proof);
132
+ return zerokitRLN.verifyProof(this.zkRLN, pBytes);
154
133
  }
155
134
  }
156
135
  //# sourceMappingURL=rln.js.map
package/dist/rln.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"rln.js","sourceRoot":"","sources":["../src/rln.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"rln.js","sourceRoot":"","sources":["../src/rln.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@waku/rln",
3
- "version": "0.0.6",
3
+ "version": "0.0.8-378ad04",
4
4
  "description": "Rate Limit Nullifier for js-waku",
5
5
  "types": "./dist/index.d.ts",
6
6
  "module": "./dist/index.js",
@@ -34,7 +34,7 @@
34
34
  "test:lint": "eslint src --ext .ts",
35
35
  "test:prettier": "prettier \"src/**/*.ts\" \"./*.json\" \"*.*js\" \".github/**/*.yml\" --list-different",
36
36
  "test:spelling": "cspell \"{*.md,.github/*.md,src/**/*.ts}\"",
37
- "test:tsc": "tsc",
37
+ "test:tsc": "tsc -p tsconfig.dev.json",
38
38
  "test:browser": "karma start karma.conf.cjs",
39
39
  "watch:build": "tsc -p tsconfig.json -w",
40
40
  "watch:test": "mocha --watch",
@@ -66,6 +66,7 @@
66
66
  "@types/uuid": "^8.3.0",
67
67
  "@typescript-eslint/eslint-plugin": "^5.8.1",
68
68
  "@typescript-eslint/parser": "^5.8.1",
69
+ "@web/rollup-plugin-import-meta-assets": "^1.0.7",
69
70
  "app-root-path": "^3.0.0",
70
71
  "chai": "^4.3.4",
71
72
  "cspell": "^5.14.0",
@@ -75,11 +76,12 @@
75
76
  "eslint-plugin-functional": "^4.0.2",
76
77
  "eslint-plugin-import": "^2.25.3",
77
78
  "eslint-plugin-prettier": "^4.0.0",
78
- "fast-check": "^2.14.0",
79
+ "fast-check": "^2.25.0",
79
80
  "gh-pages": "^3.2.3",
80
81
  "husky": "^7.0.4",
81
82
  "ignore-loader": "^0.1.2",
82
83
  "isomorphic-fetch": "^3.0.0",
84
+ "js-waku": "^0.29.0-29436ea",
83
85
  "jsdom": "^19.0.0",
84
86
  "jsdom-global": "^3.0.2",
85
87
  "karma": "^6.3.12",
@@ -123,6 +125,6 @@
123
125
  ]
124
126
  },
125
127
  "dependencies": {
126
- "@waku/zerokit-rln-wasm": "^0.0.1"
128
+ "@waku/zerokit-rln-wasm": "^0.0.2"
127
129
  }
128
130
  }
@@ -0,0 +1,39 @@
1
+ // Adapted from https://github.com/feross/buffer
2
+
3
+ function checkInt(
4
+ buf: Uint8Array,
5
+ value: number,
6
+ offset: number,
7
+ ext: number,
8
+ max: number,
9
+ min: number
10
+ ): void {
11
+ if (value > max || value < min)
12
+ throw new RangeError('"value" argument is out of bounds');
13
+ if (offset + ext > buf.length) throw new RangeError("Index out of range");
14
+ }
15
+
16
+ export function writeUIntLE(
17
+ buf: Uint8Array,
18
+ value: number,
19
+ offset: number,
20
+ byteLength: number,
21
+ noAssert?: boolean
22
+ ): Uint8Array {
23
+ value = +value;
24
+ offset = offset >>> 0;
25
+ byteLength = byteLength >>> 0;
26
+ if (!noAssert) {
27
+ const maxBytes = Math.pow(2, 8 * byteLength) - 1;
28
+ checkInt(buf, value, offset, byteLength, maxBytes, 0);
29
+ }
30
+
31
+ let mul = 1;
32
+ let i = 0;
33
+ buf[offset] = value & 0xff;
34
+ while (++i < byteLength && (mul *= 0x100)) {
35
+ buf[offset + i] = (value / mul) & 0xff;
36
+ }
37
+
38
+ return buf;
39
+ }
package/src/codec.ts ADDED
@@ -0,0 +1,88 @@
1
+ import debug from "debug";
2
+ import { utils } from "js-waku";
3
+ import {
4
+ Decoder,
5
+ Encoder,
6
+ Message,
7
+ ProtoMessage,
8
+ RateLimitProof,
9
+ } from "js-waku/lib/interfaces";
10
+
11
+ import { RlnMessage } from "./message.js";
12
+ import { MembershipKey, RLNInstance } from "./rln.js";
13
+
14
+ const log = debug("waku:message:rln-encoder");
15
+
16
+ export class RLNEncoder implements Encoder {
17
+ public contentTopic: string;
18
+ private readonly idKey: Uint8Array;
19
+
20
+ constructor(
21
+ private encoder: Encoder,
22
+ private rlnInstance: RLNInstance,
23
+ private index: number,
24
+ membershipKey: MembershipKey
25
+ ) {
26
+ if (index < 0) throw "invalid membership index";
27
+ this.idKey = membershipKey.IDKey;
28
+ this.contentTopic = encoder.contentTopic;
29
+ }
30
+
31
+ async toWire(message: Partial<Message>): Promise<Uint8Array | undefined> {
32
+ message.rateLimitProof = await this.generateProof(message);
33
+
34
+ return this.encoder.toWire(message);
35
+ }
36
+
37
+ async toProtoObj(
38
+ message: Partial<Message>
39
+ ): Promise<ProtoMessage | undefined> {
40
+ const protoMessage = await this.encoder.toProtoObj(message);
41
+ if (!protoMessage) return;
42
+
43
+ protoMessage.rateLimitProof = await this.generateProof(message);
44
+
45
+ return protoMessage;
46
+ }
47
+
48
+ private async generateProof(
49
+ message: Partial<Message>
50
+ ): Promise<RateLimitProof> {
51
+ const signal = toRLNSignal(message);
52
+
53
+ console.time("proof_gen_timer");
54
+ const proof = await this.rlnInstance.generateProof(
55
+ signal,
56
+ this.index,
57
+ message.timestamp,
58
+ this.idKey
59
+ );
60
+ console.timeEnd("proof_gen_timer");
61
+ return proof;
62
+ }
63
+ }
64
+
65
+ export class RLNDecoder<T extends Message> implements Decoder<RlnMessage<T>> {
66
+ constructor(private rlnInstance: RLNInstance, private decoder: Decoder<T>) {}
67
+
68
+ get contentTopic(): string {
69
+ return this.decoder.contentTopic;
70
+ }
71
+
72
+ fromWireToProtoObj(bytes: Uint8Array): Promise<ProtoMessage | undefined> {
73
+ const protoMessage = this.decoder.fromWireToProtoObj(bytes);
74
+ log("Message decoded", protoMessage);
75
+ return Promise.resolve(protoMessage);
76
+ }
77
+
78
+ async fromProtoObj(proto: ProtoMessage): Promise<RlnMessage<T> | undefined> {
79
+ const msg: T | undefined = await this.decoder.fromProtoObj(proto);
80
+ if (!msg) return;
81
+ return new RlnMessage(this.rlnInstance, msg, proto.rateLimitProof);
82
+ }
83
+ }
84
+
85
+ function toRLNSignal(msg: Partial<Message>): Uint8Array {
86
+ const contentTopicBytes = utils.utf8ToBytes(msg.contentTopic ?? "");
87
+ return new Uint8Array([...(msg.payload ?? []), ...contentTopicBytes]);
88
+ }
package/src/epoch.ts ADDED
@@ -0,0 +1,21 @@
1
+ const DefaultEpochUnitSeconds = 10; // the rln-relay epoch length in seconds
2
+
3
+ export function dateToEpoch(
4
+ timestamp: Date,
5
+ epochUnitSeconds: number = DefaultEpochUnitSeconds
6
+ ): number {
7
+ const time = timestamp.getTime();
8
+ return Math.floor(time / 1000 / epochUnitSeconds);
9
+ }
10
+
11
+ export function epochIntToBytes(epoch: number): Uint8Array {
12
+ const bytes = new Uint8Array(32);
13
+ const db = new DataView(bytes.buffer);
14
+ db.setUint32(0, epoch, true);
15
+ return bytes;
16
+ }
17
+
18
+ export function epochBytesToInt(bytes: Uint8Array): number {
19
+ const dv = new DataView(bytes.buffer);
20
+ return dv.getUint32(0, true);
21
+ }
package/src/index.ts CHANGED
@@ -1,4 +1,6 @@
1
- import type { MembershipKey, RateLimitProof, RLNInstance } from "./rln.js";
1
+ import { RLNDecoder, RLNEncoder } from "./codec.js";
2
+ import type { Proof, RLNInstance } from "./rln.js";
3
+ import { MembershipKey } from "./rln.js";
2
4
 
3
5
  // reexport the create function, dynamically imported from rln.ts
4
6
  export async function create(): Promise<RLNInstance> {
@@ -9,4 +11,4 @@ export async function create(): Promise<RLNInstance> {
9
11
  return await rlnModule.create();
10
12
  }
11
13
 
12
- export { RLNInstance, MembershipKey, RateLimitProof };
14
+ export { RLNInstance, MembershipKey, Proof, RLNEncoder, RLNDecoder };
package/src/message.ts ADDED
@@ -0,0 +1,37 @@
1
+ import { Message, RateLimitProof } from "js-waku/lib/interfaces";
2
+
3
+ import { epochBytesToInt } from "./epoch.js";
4
+ import { RLNInstance } from "./rln.js";
5
+
6
+ export class RlnMessage<T extends Message> implements Message {
7
+ constructor(
8
+ public rlnInstance: RLNInstance,
9
+ public msg: T,
10
+ public rateLimitProof: RateLimitProof | undefined
11
+ ) {}
12
+
13
+ public verify(): boolean | undefined {
14
+ return this.rateLimitProof
15
+ ? this.rlnInstance.verifyProof(this.rateLimitProof)
16
+ : undefined;
17
+ }
18
+
19
+ get payload(): Uint8Array | undefined {
20
+ return this.msg.payload;
21
+ }
22
+
23
+ get contentTopic(): string | undefined {
24
+ return this.msg.contentTopic;
25
+ }
26
+
27
+ get timestamp(): Date | undefined {
28
+ return this.msg.timestamp;
29
+ }
30
+
31
+ get epoch(): number | undefined {
32
+ const bytes = this.msg.rateLimitProof?.epoch;
33
+ if (!bytes) return;
34
+
35
+ return epochBytesToInt(bytes);
36
+ }
37
+ }
package/src/rln.ts CHANGED
@@ -1,22 +1,11 @@
1
1
  import init, * as zerokitRLN from "@waku/zerokit-rln-wasm";
2
+ import { RateLimitProof } from "js-waku/lib/interfaces";
2
3
 
3
- import * as resources from "./resources.js";
4
+ import { writeUIntLE } from "./byte_utils.js";
5
+ import { dateToEpoch, epochIntToBytes } from "./epoch.js";
6
+ import verificationKey from "./resources/verification_key.js";
4
7
  import * as wc from "./witness_calculator.js";
5
-
6
- /**
7
- * Convert a base64 string into uint8Array
8
- * @param base64
9
- * @returns Uint8Array
10
- */
11
- function base64ToUint8Array(base64: string): Uint8Array {
12
- const binary_string = window.atob(base64);
13
- const len = binary_string.length;
14
- const bytes = new Uint8Array(len);
15
- for (let i = 0; i < len; i++) {
16
- bytes[i] = binary_string.charCodeAt(i);
17
- }
18
- return bytes;
19
- }
8
+ import { WitnessCalculator } from "./witness_calculator.js";
20
9
 
21
10
  /**
22
11
  * Concatenate Uint8Arrays
@@ -37,10 +26,21 @@ function concatenate(...input: Uint8Array[]): Uint8Array {
37
26
  return result;
38
27
  }
39
28
 
29
+ const stringEncoder = new TextEncoder();
30
+
40
31
  const DEPTH = 20;
41
- const VERIFICATION_KEY = base64ToUint8Array(resources.verification_key);
42
- const ZKEY = base64ToUint8Array(resources.zkey);
43
- const CIRCUIT = base64ToUint8Array(resources.circuit);
32
+
33
+ async function loadWitnessCalculator(): Promise<WitnessCalculator> {
34
+ const url = new URL("./resources/rln.wasm", import.meta.url);
35
+ const response = await fetch(url);
36
+ return await wc.builder(new Uint8Array(await response.arrayBuffer()), false);
37
+ }
38
+
39
+ async function loadZkey(): Promise<Uint8Array> {
40
+ const url = new URL("./resources/rln_final.zkey", import.meta.url);
41
+ const response = await fetch(url);
42
+ return new Uint8Array(await response.arrayBuffer());
43
+ }
44
44
 
45
45
  /**
46
46
  * Create an instance of RLN
@@ -49,72 +49,26 @@ const CIRCUIT = base64ToUint8Array(resources.circuit);
49
49
  export async function create(): Promise<RLNInstance> {
50
50
  await init();
51
51
  zerokitRLN.init_panic_hook();
52
-
53
- const witnessCalculator = await wc.builder(CIRCUIT, false);
54
- const zkRLN = zerokitRLN.newRLN(DEPTH, ZKEY, VERIFICATION_KEY);
52
+ const witnessCalculator = await loadWitnessCalculator();
53
+ const zkey = await loadZkey();
54
+ const vkey = stringEncoder.encode(JSON.stringify(verificationKey));
55
+ const zkRLN = zerokitRLN.newRLN(DEPTH, zkey, vkey);
55
56
  return new RLNInstance(zkRLN, witnessCalculator);
56
57
  }
57
58
 
58
59
  export class MembershipKey {
59
- readonly IDKey: Uint8Array;
60
- readonly IDCommitment: Uint8Array;
61
-
62
- constructor(memKeys: Uint8Array) {
63
- this.IDKey = memKeys.subarray(0, 32);
64
- this.IDCommitment = memKeys.subarray(32);
60
+ constructor(
61
+ public readonly IDKey: Uint8Array,
62
+ public readonly IDCommitment: Uint8Array
63
+ ) {}
64
+
65
+ static fromBytes(memKeys: Uint8Array): MembershipKey {
66
+ const idKey = memKeys.subarray(0, 32);
67
+ const idCommitment = memKeys.subarray(32);
68
+ return new MembershipKey(idKey, idCommitment);
65
69
  }
66
70
  }
67
71
 
68
- // Adapted from https://github.com/feross/buffer
69
-
70
- function checkInt(
71
- buf: Uint8Array,
72
- value: number,
73
- offset: number,
74
- ext: number,
75
- max: number,
76
- min: number
77
- ): void {
78
- if (value > max || value < min)
79
- throw new RangeError('"value" argument is out of bounds');
80
- if (offset + ext > buf.length) throw new RangeError("Index out of range");
81
- }
82
-
83
- const writeUIntLE = function writeUIntLE(
84
- buf: Uint8Array,
85
- value: number,
86
- offset: number,
87
- byteLength: number,
88
- noAssert?: boolean
89
- ): Uint8Array {
90
- value = +value;
91
- offset = offset >>> 0;
92
- byteLength = byteLength >>> 0;
93
- if (!noAssert) {
94
- const maxBytes = Math.pow(2, 8 * byteLength) - 1;
95
- checkInt(buf, value, offset, byteLength, maxBytes, 0);
96
- }
97
-
98
- let mul = 1;
99
- let i = 0;
100
- buf[offset] = value & 0xff;
101
- while (++i < byteLength && (mul *= 0x100)) {
102
- buf[offset + i] = (value / mul) & 0xff;
103
- }
104
-
105
- return buf;
106
- };
107
-
108
- const DefaultEpochUnitSeconds = 10; // the rln-relay epoch length in seconds
109
-
110
- export function toEpoch(
111
- timestamp: Date,
112
- epochUnitSeconds: number = DefaultEpochUnitSeconds
113
- ): Uint8Array {
114
- const unix = Math.floor(timestamp.getTime() / 1000 / epochUnitSeconds);
115
- return writeUIntLE(new Uint8Array(32), unix, 0, 8);
116
- }
117
-
118
72
  const proofOffset = 128;
119
73
  const rootOffset = proofOffset + 32;
120
74
  const epochOffset = rootOffset + 32;
@@ -123,7 +77,7 @@ const shareYOffset = shareXOffset + 32;
123
77
  const nullifierOffset = shareYOffset + 32;
124
78
  const rlnIdentifierOffset = nullifierOffset + 32;
125
79
 
126
- export class RateLimitProof {
80
+ export class Proof implements RateLimitProof {
127
81
  readonly proof: Uint8Array;
128
82
  readonly merkleRoot: Uint8Array;
129
83
  readonly epoch: Uint8Array;
@@ -146,26 +100,29 @@ export class RateLimitProof {
146
100
  rlnIdentifierOffset
147
101
  );
148
102
  }
103
+ }
149
104
 
150
- toBytes(): Uint8Array {
151
- return concatenate(
152
- this.proof,
153
- this.merkleRoot,
154
- this.epoch,
155
- this.shareX,
156
- this.shareY,
157
- this.nullifier,
158
- this.rlnIdentifier
159
- );
160
- }
105
+ function proofToBytes(p: RateLimitProof): Uint8Array {
106
+ return concatenate(
107
+ p.proof,
108
+ p.merkleRoot,
109
+ p.epoch,
110
+ p.shareX,
111
+ p.shareY,
112
+ p.nullifier,
113
+ p.rlnIdentifier
114
+ );
161
115
  }
162
116
 
163
117
  export class RLNInstance {
164
- constructor(private zkRLN: number, private witnessCalculator: any) {}
118
+ constructor(
119
+ private zkRLN: number,
120
+ private witnessCalculator: WitnessCalculator
121
+ ) {}
165
122
 
166
123
  generateMembershipKey(): MembershipKey {
167
124
  const memKeys = zerokitRLN.generateMembershipKey(this.zkRLN);
168
- return new MembershipKey(memKeys);
125
+ return MembershipKey.fromBytes(memKeys);
169
126
  }
170
127
 
171
128
  insertMember(idCommitment: Uint8Array): void {
@@ -195,9 +152,9 @@ export class RLNInstance {
195
152
  idKey: Uint8Array
196
153
  ): Promise<RateLimitProof> {
197
154
  if (epoch == undefined) {
198
- epoch = toEpoch(new Date());
155
+ epoch = epochIntToBytes(dateToEpoch(new Date()));
199
156
  } else if (epoch instanceof Date) {
200
- epoch = toEpoch(epoch);
157
+ epoch = epochIntToBytes(dateToEpoch(epoch));
201
158
  }
202
159
 
203
160
  if (epoch.length != 32) throw "invalid epoch";
@@ -221,13 +178,16 @@ export class RLNInstance {
221
178
  rlnWitness
222
179
  );
223
180
 
224
- return new RateLimitProof(proofBytes);
181
+ return new Proof(proofBytes);
225
182
  }
226
183
 
227
184
  verifyProof(proof: RateLimitProof | Uint8Array): boolean {
228
- if (proof instanceof RateLimitProof) {
229
- proof = proof.toBytes();
185
+ let pBytes: Uint8Array;
186
+ if (proof instanceof Uint8Array) {
187
+ pBytes = proof;
188
+ } else {
189
+ pBytes = proofToBytes(proof);
230
190
  }
231
- return zerokitRLN.verifyProof(this.zkRLN, proof);
191
+ return zerokitRLN.verifyProof(this.zkRLN, pBytes);
232
192
  }
233
193
  }