@waku/rln 0.0.7 → 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,5 +1,7 @@
1
1
  import init, * as zerokitRLN from "@waku/zerokit-rln-wasm";
2
- import verificationKey from "./resources/verification_key.json";
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
6
  /**
5
7
  * Concatenate Uint8Arrays
@@ -45,38 +47,15 @@ export async function create() {
45
47
  return new RLNInstance(zkRLN, witnessCalculator);
46
48
  }
47
49
  export class MembershipKey {
48
- constructor(memKeys) {
49
- this.IDKey = memKeys.subarray(0, 32);
50
- this.IDCommitment = memKeys.subarray(32);
50
+ constructor(IDKey, IDCommitment) {
51
+ this.IDKey = IDKey;
52
+ this.IDCommitment = IDCommitment;
51
53
  }
52
- }
53
- // Adapted from https://github.com/feross/buffer
54
- function checkInt(buf, value, offset, ext, max, min) {
55
- if (value > max || value < min)
56
- throw new RangeError('"value" argument is out of bounds');
57
- if (offset + ext > buf.length)
58
- throw new RangeError("Index out of range");
59
- }
60
- const writeUIntLE = function writeUIntLE(buf, value, offset, byteLength, noAssert) {
61
- value = +value;
62
- offset = offset >>> 0;
63
- byteLength = byteLength >>> 0;
64
- if (!noAssert) {
65
- const maxBytes = Math.pow(2, 8 * byteLength) - 1;
66
- checkInt(buf, value, offset, byteLength, maxBytes, 0);
67
- }
68
- let mul = 1;
69
- let i = 0;
70
- buf[offset] = value & 0xff;
71
- while (++i < byteLength && (mul *= 0x100)) {
72
- 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);
73
58
  }
74
- return buf;
75
- };
76
- const DefaultEpochUnitSeconds = 10; // the rln-relay epoch length in seconds
77
- export function toEpoch(timestamp, epochUnitSeconds = DefaultEpochUnitSeconds) {
78
- const unix = Math.floor(timestamp.getTime() / 1000 / epochUnitSeconds);
79
- return writeUIntLE(new Uint8Array(32), unix, 0, 8);
80
59
  }
81
60
  const proofOffset = 128;
82
61
  const rootOffset = proofOffset + 32;
@@ -85,7 +64,7 @@ const shareXOffset = epochOffset + 32;
85
64
  const shareYOffset = shareXOffset + 32;
86
65
  const nullifierOffset = shareYOffset + 32;
87
66
  const rlnIdentifierOffset = nullifierOffset + 32;
88
- export class RateLimitProof {
67
+ export class Proof {
89
68
  constructor(proofBytes) {
90
69
  if (proofBytes.length < rlnIdentifierOffset)
91
70
  throw "invalid proof";
@@ -98,9 +77,9 @@ export class RateLimitProof {
98
77
  this.nullifier = proofBytes.subarray(shareYOffset, nullifierOffset);
99
78
  this.rlnIdentifier = proofBytes.subarray(nullifierOffset, rlnIdentifierOffset);
100
79
  }
101
- toBytes() {
102
- return concatenate(this.proof, this.merkleRoot, this.epoch, this.shareX, this.shareY, this.nullifier, this.rlnIdentifier);
103
- }
80
+ }
81
+ function proofToBytes(p) {
82
+ return concatenate(p.proof, p.merkleRoot, p.epoch, p.shareX, p.shareY, p.nullifier, p.rlnIdentifier);
104
83
  }
105
84
  export class RLNInstance {
106
85
  constructor(zkRLN, witnessCalculator) {
@@ -109,7 +88,7 @@ export class RLNInstance {
109
88
  }
110
89
  generateMembershipKey() {
111
90
  const memKeys = zerokitRLN.generateMembershipKey(this.zkRLN);
112
- return new MembershipKey(memKeys);
91
+ return MembershipKey.fromBytes(memKeys);
113
92
  }
114
93
  insertMember(idCommitment) {
115
94
  zerokitRLN.insertMember(this.zkRLN, idCommitment);
@@ -124,10 +103,10 @@ export class RLNInstance {
124
103
  }
125
104
  async generateProof(msg, index, epoch, idKey) {
126
105
  if (epoch == undefined) {
127
- epoch = toEpoch(new Date());
106
+ epoch = epochIntToBytes(dateToEpoch(new Date()));
128
107
  }
129
108
  else if (epoch instanceof Date) {
130
- epoch = toEpoch(epoch);
109
+ epoch = epochIntToBytes(dateToEpoch(epoch));
131
110
  }
132
111
  if (epoch.length != 32)
133
112
  throw "invalid epoch";
@@ -140,13 +119,17 @@ export class RLNInstance {
140
119
  const inputs = zerokitRLN.RLNWitnessToJson(this.zkRLN, rlnWitness);
141
120
  const calculatedWitness = await this.witnessCalculator.calculateWitness(inputs, false); // no sanity check being used in zerokit
142
121
  const proofBytes = zerokitRLN.generate_rln_proof_with_witness(this.zkRLN, calculatedWitness, rlnWitness);
143
- return new RateLimitProof(proofBytes);
122
+ return new Proof(proofBytes);
144
123
  }
145
124
  verifyProof(proof) {
146
- if (proof instanceof RateLimitProof) {
147
- proof = proof.toBytes();
125
+ let pBytes;
126
+ if (proof instanceof Uint8Array) {
127
+ pBytes = proof;
128
+ }
129
+ else {
130
+ pBytes = proofToBytes(proof);
148
131
  }
149
- return zerokitRLN.verifyProof(this.zkRLN, proof);
132
+ return zerokitRLN.verifyProof(this.zkRLN, pBytes);
150
133
  }
151
134
  }
152
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.7",
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",
@@ -76,11 +76,12 @@
76
76
  "eslint-plugin-functional": "^4.0.2",
77
77
  "eslint-plugin-import": "^2.25.3",
78
78
  "eslint-plugin-prettier": "^4.0.0",
79
- "fast-check": "^2.14.0",
79
+ "fast-check": "^2.25.0",
80
80
  "gh-pages": "^3.2.3",
81
81
  "husky": "^7.0.4",
82
82
  "ignore-loader": "^0.1.2",
83
83
  "isomorphic-fetch": "^3.0.0",
84
+ "js-waku": "^0.29.0-29436ea",
84
85
  "jsdom": "^19.0.0",
85
86
  "jsdom-global": "^3.0.2",
86
87
  "karma": "^6.3.12",
@@ -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,7 +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 verificationKey from "./resources/verification_key.json";
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";
8
+ import { WitnessCalculator } from "./witness_calculator.js";
5
9
 
6
10
  /**
7
11
  * Concatenate Uint8Arrays
@@ -26,7 +30,7 @@ const stringEncoder = new TextEncoder();
26
30
 
27
31
  const DEPTH = 20;
28
32
 
29
- async function loadWitnessCalculator(): Promise<any> {
33
+ async function loadWitnessCalculator(): Promise<WitnessCalculator> {
30
34
  const url = new URL("./resources/rln.wasm", import.meta.url);
31
35
  const response = await fetch(url);
32
36
  return await wc.builder(new Uint8Array(await response.arrayBuffer()), false);
@@ -53,63 +57,16 @@ export async function create(): Promise<RLNInstance> {
53
57
  }
54
58
 
55
59
  export class MembershipKey {
56
- readonly IDKey: Uint8Array;
57
- readonly IDCommitment: Uint8Array;
58
-
59
- constructor(memKeys: Uint8Array) {
60
- this.IDKey = memKeys.subarray(0, 32);
61
- this.IDCommitment = memKeys.subarray(32);
62
- }
63
- }
64
-
65
- // Adapted from https://github.com/feross/buffer
66
-
67
- function checkInt(
68
- buf: Uint8Array,
69
- value: number,
70
- offset: number,
71
- ext: number,
72
- max: number,
73
- min: number
74
- ): void {
75
- if (value > max || value < min)
76
- throw new RangeError('"value" argument is out of bounds');
77
- if (offset + ext > buf.length) throw new RangeError("Index out of range");
78
- }
79
-
80
- const writeUIntLE = function writeUIntLE(
81
- buf: Uint8Array,
82
- value: number,
83
- offset: number,
84
- byteLength: number,
85
- noAssert?: boolean
86
- ): Uint8Array {
87
- value = +value;
88
- offset = offset >>> 0;
89
- byteLength = byteLength >>> 0;
90
- if (!noAssert) {
91
- const maxBytes = Math.pow(2, 8 * byteLength) - 1;
92
- checkInt(buf, value, offset, byteLength, maxBytes, 0);
93
- }
94
-
95
- let mul = 1;
96
- let i = 0;
97
- buf[offset] = value & 0xff;
98
- while (++i < byteLength && (mul *= 0x100)) {
99
- buf[offset + i] = (value / mul) & 0xff;
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);
100
69
  }
101
-
102
- return buf;
103
- };
104
-
105
- const DefaultEpochUnitSeconds = 10; // the rln-relay epoch length in seconds
106
-
107
- export function toEpoch(
108
- timestamp: Date,
109
- epochUnitSeconds: number = DefaultEpochUnitSeconds
110
- ): Uint8Array {
111
- const unix = Math.floor(timestamp.getTime() / 1000 / epochUnitSeconds);
112
- return writeUIntLE(new Uint8Array(32), unix, 0, 8);
113
70
  }
114
71
 
115
72
  const proofOffset = 128;
@@ -120,7 +77,7 @@ const shareYOffset = shareXOffset + 32;
120
77
  const nullifierOffset = shareYOffset + 32;
121
78
  const rlnIdentifierOffset = nullifierOffset + 32;
122
79
 
123
- export class RateLimitProof {
80
+ export class Proof implements RateLimitProof {
124
81
  readonly proof: Uint8Array;
125
82
  readonly merkleRoot: Uint8Array;
126
83
  readonly epoch: Uint8Array;
@@ -143,26 +100,29 @@ export class RateLimitProof {
143
100
  rlnIdentifierOffset
144
101
  );
145
102
  }
103
+ }
146
104
 
147
- toBytes(): Uint8Array {
148
- return concatenate(
149
- this.proof,
150
- this.merkleRoot,
151
- this.epoch,
152
- this.shareX,
153
- this.shareY,
154
- this.nullifier,
155
- this.rlnIdentifier
156
- );
157
- }
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
+ );
158
115
  }
159
116
 
160
117
  export class RLNInstance {
161
- constructor(private zkRLN: number, private witnessCalculator: any) {}
118
+ constructor(
119
+ private zkRLN: number,
120
+ private witnessCalculator: WitnessCalculator
121
+ ) {}
162
122
 
163
123
  generateMembershipKey(): MembershipKey {
164
124
  const memKeys = zerokitRLN.generateMembershipKey(this.zkRLN);
165
- return new MembershipKey(memKeys);
125
+ return MembershipKey.fromBytes(memKeys);
166
126
  }
167
127
 
168
128
  insertMember(idCommitment: Uint8Array): void {
@@ -192,9 +152,9 @@ export class RLNInstance {
192
152
  idKey: Uint8Array
193
153
  ): Promise<RateLimitProof> {
194
154
  if (epoch == undefined) {
195
- epoch = toEpoch(new Date());
155
+ epoch = epochIntToBytes(dateToEpoch(new Date()));
196
156
  } else if (epoch instanceof Date) {
197
- epoch = toEpoch(epoch);
157
+ epoch = epochIntToBytes(dateToEpoch(epoch));
198
158
  }
199
159
 
200
160
  if (epoch.length != 32) throw "invalid epoch";
@@ -218,13 +178,16 @@ export class RLNInstance {
218
178
  rlnWitness
219
179
  );
220
180
 
221
- return new RateLimitProof(proofBytes);
181
+ return new Proof(proofBytes);
222
182
  }
223
183
 
224
184
  verifyProof(proof: RateLimitProof | Uint8Array): boolean {
225
- if (proof instanceof RateLimitProof) {
226
- proof = proof.toBytes();
185
+ let pBytes: Uint8Array;
186
+ if (proof instanceof Uint8Array) {
187
+ pBytes = proof;
188
+ } else {
189
+ pBytes = proofToBytes(proof);
227
190
  }
228
- return zerokitRLN.verifyProof(this.zkRLN, proof);
191
+ return zerokitRLN.verifyProof(this.zkRLN, pBytes);
229
192
  }
230
193
  }
@@ -1,4 +1,8 @@
1
1
  export async function builder(
2
2
  code: Uint8Array,
3
3
  sanityCheck: bool
4
- ): Promise<any>;
4
+ ): Promise<WitnessCalculator>;
5
+
6
+ export class WitnessCalculator {
7
+ calculateWitness(input, sanityCheck): Array<bigint>;
8
+ }