@waku/rln 0.0.6 → 0.0.8-38fdb53
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/bundle/assets/rln-fb4d7b4b.wasm +0 -0
- package/bundle/assets/rln_final-a641c06e.zkey +0 -0
- package/bundle/assets/rln_wasm_bg-0185b546.wasm +0 -0
- package/bundle/index.js +1 -1
- package/bundle/rln-7c06a1d6.js +1147 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/encoder.d.ts +19 -0
- package/dist/encoder.js +54 -0
- package/dist/encoder.js.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/resources/rln.wasm +0 -0
- package/dist/resources/rln_final.zkey +0 -0
- package/dist/resources/verification_key.d.ts +12 -0
- package/dist/resources/verification_key.js +121 -0
- package/dist/resources/verification_key.js.map +1 -0
- package/dist/rln.d.ts +6 -4
- package/dist/rln.js +37 -32
- package/dist/rln.js.map +1 -1
- package/package.json +5 -3
- package/src/encoder.ts +81 -0
- package/src/index.ts +2 -2
- package/src/rln.ts +54 -46
- package/src/witness_calculator.d.ts +5 -1
- package/bundle/rln-b6bbd489.js +0 -1027
- package/dist/resources.d.ts +0 -4
- package/dist/resources.js +0 -5
- package/dist/resources.js.map +0 -1
- package/src/resources.ts +0 -10
package/src/encoder.ts
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
import debug from "debug";
|
2
|
+
import { proto_message, utils } from "js-waku";
|
3
|
+
import {
|
4
|
+
Decoder,
|
5
|
+
Encoder,
|
6
|
+
Message,
|
7
|
+
ProtoMessage,
|
8
|
+
} from "js-waku/lib/interfaces";
|
9
|
+
|
10
|
+
import { MembershipKey, RLNInstance } from "./rln.js";
|
11
|
+
|
12
|
+
const log = debug("waku:message:rln-encoder");
|
13
|
+
|
14
|
+
export class RLNEncoder implements Encoder {
|
15
|
+
public contentTopic: string;
|
16
|
+
private readonly idKey: Uint8Array;
|
17
|
+
|
18
|
+
constructor(
|
19
|
+
private encoder: Encoder,
|
20
|
+
private rlnInstance: RLNInstance,
|
21
|
+
private index: number,
|
22
|
+
membershipKey: MembershipKey
|
23
|
+
) {
|
24
|
+
if (index < 0) throw "invalid membership index";
|
25
|
+
this.idKey = membershipKey.IDKey;
|
26
|
+
this.contentTopic = encoder.contentTopic;
|
27
|
+
}
|
28
|
+
|
29
|
+
async encode(message: Message): Promise<Uint8Array | undefined> {
|
30
|
+
const protoMessage = await this.encodeProto(message);
|
31
|
+
if (!protoMessage) return;
|
32
|
+
return proto_message.WakuMessage.encode(protoMessage);
|
33
|
+
}
|
34
|
+
|
35
|
+
async encodeProto(message: Message): Promise<ProtoMessage | undefined> {
|
36
|
+
const protoMessage = await this.encoder.encodeProto(message);
|
37
|
+
if (!protoMessage) return;
|
38
|
+
|
39
|
+
const signal = toRLNSignal(message);
|
40
|
+
|
41
|
+
console.time("proof_gen_timer");
|
42
|
+
const proof = await this.rlnInstance.generateProof(
|
43
|
+
signal,
|
44
|
+
this.index,
|
45
|
+
message.timestamp,
|
46
|
+
this.idKey
|
47
|
+
);
|
48
|
+
console.timeEnd("proof_gen_timer");
|
49
|
+
|
50
|
+
protoMessage.rateLimitProof = proof;
|
51
|
+
|
52
|
+
return protoMessage;
|
53
|
+
}
|
54
|
+
}
|
55
|
+
|
56
|
+
export class RLNDecoder implements Decoder<Message> {
|
57
|
+
public contentTopic: string;
|
58
|
+
|
59
|
+
constructor(private decoder: Decoder<Message>) {
|
60
|
+
this.contentTopic = decoder.contentTopic;
|
61
|
+
}
|
62
|
+
|
63
|
+
decodeProto(bytes: Uint8Array): Promise<ProtoMessage | undefined> {
|
64
|
+
const protoMessage = proto_message.WakuMessage.decode(bytes);
|
65
|
+
log("Message decoded", protoMessage);
|
66
|
+
return Promise.resolve(protoMessage);
|
67
|
+
}
|
68
|
+
|
69
|
+
async decode(proto: ProtoMessage): Promise<Message | undefined> {
|
70
|
+
const msg = await this.decoder.decode(proto);
|
71
|
+
if (msg) {
|
72
|
+
msg.rateLimitProof = proto.rateLimitProof;
|
73
|
+
}
|
74
|
+
return msg;
|
75
|
+
}
|
76
|
+
}
|
77
|
+
|
78
|
+
function toRLNSignal(msg: Message): Uint8Array {
|
79
|
+
const contentTopicBytes = utils.utf8ToBytes(msg.contentTopic ?? "");
|
80
|
+
return new Uint8Array([...(msg.payload ?? []), ...contentTopicBytes]);
|
81
|
+
}
|
package/src/index.ts
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
import type { MembershipKey,
|
1
|
+
import type { MembershipKey, Proof, RLNInstance } from "./rln.js";
|
2
2
|
|
3
3
|
// reexport the create function, dynamically imported from rln.ts
|
4
4
|
export async function create(): Promise<RLNInstance> {
|
@@ -9,4 +9,4 @@ export async function create(): Promise<RLNInstance> {
|
|
9
9
|
return await rlnModule.create();
|
10
10
|
}
|
11
11
|
|
12
|
-
export { RLNInstance, MembershipKey,
|
12
|
+
export { RLNInstance, MembershipKey, Proof };
|
package/src/rln.ts
CHANGED
@@ -1,22 +1,9 @@
|
|
1
1
|
import init, * as zerokitRLN from "@waku/zerokit-rln-wasm";
|
2
|
+
import { RateLimitProof } from "js-waku/lib/interfaces";
|
2
3
|
|
3
|
-
import
|
4
|
+
import verificationKey from "./resources/verification_key.js";
|
4
5
|
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
|
-
}
|
6
|
+
import { WitnessCalculator } from "./witness_calculator.js";
|
20
7
|
|
21
8
|
/**
|
22
9
|
* Concatenate Uint8Arrays
|
@@ -37,10 +24,21 @@ function concatenate(...input: Uint8Array[]): Uint8Array {
|
|
37
24
|
return result;
|
38
25
|
}
|
39
26
|
|
27
|
+
const stringEncoder = new TextEncoder();
|
28
|
+
|
40
29
|
const DEPTH = 20;
|
41
|
-
|
42
|
-
|
43
|
-
const
|
30
|
+
|
31
|
+
async function loadWitnessCalculator(): Promise<WitnessCalculator> {
|
32
|
+
const url = new URL("./resources/rln.wasm", import.meta.url);
|
33
|
+
const response = await fetch(url);
|
34
|
+
return await wc.builder(new Uint8Array(await response.arrayBuffer()), false);
|
35
|
+
}
|
36
|
+
|
37
|
+
async function loadZkey(): Promise<Uint8Array> {
|
38
|
+
const url = new URL("./resources/rln_final.zkey", import.meta.url);
|
39
|
+
const response = await fetch(url);
|
40
|
+
return new Uint8Array(await response.arrayBuffer());
|
41
|
+
}
|
44
42
|
|
45
43
|
/**
|
46
44
|
* Create an instance of RLN
|
@@ -49,19 +47,23 @@ const CIRCUIT = base64ToUint8Array(resources.circuit);
|
|
49
47
|
export async function create(): Promise<RLNInstance> {
|
50
48
|
await init();
|
51
49
|
zerokitRLN.init_panic_hook();
|
52
|
-
|
53
|
-
const
|
54
|
-
const
|
50
|
+
const witnessCalculator = await loadWitnessCalculator();
|
51
|
+
const zkey = await loadZkey();
|
52
|
+
const vkey = stringEncoder.encode(JSON.stringify(verificationKey));
|
53
|
+
const zkRLN = zerokitRLN.newRLN(DEPTH, zkey, vkey);
|
55
54
|
return new RLNInstance(zkRLN, witnessCalculator);
|
56
55
|
}
|
57
56
|
|
58
57
|
export class MembershipKey {
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
58
|
+
constructor(
|
59
|
+
public readonly IDKey: Uint8Array,
|
60
|
+
public readonly IDCommitment: Uint8Array
|
61
|
+
) {}
|
62
|
+
|
63
|
+
static fromBytes(memKeys: Uint8Array): MembershipKey {
|
64
|
+
const idKey = memKeys.subarray(0, 32);
|
65
|
+
const idCommitment = memKeys.subarray(32);
|
66
|
+
return new MembershipKey(idKey, idCommitment);
|
65
67
|
}
|
66
68
|
}
|
67
69
|
|
@@ -123,7 +125,7 @@ const shareYOffset = shareXOffset + 32;
|
|
123
125
|
const nullifierOffset = shareYOffset + 32;
|
124
126
|
const rlnIdentifierOffset = nullifierOffset + 32;
|
125
127
|
|
126
|
-
export class RateLimitProof {
|
128
|
+
export class Proof implements RateLimitProof {
|
127
129
|
readonly proof: Uint8Array;
|
128
130
|
readonly merkleRoot: Uint8Array;
|
129
131
|
readonly epoch: Uint8Array;
|
@@ -146,26 +148,29 @@ export class RateLimitProof {
|
|
146
148
|
rlnIdentifierOffset
|
147
149
|
);
|
148
150
|
}
|
151
|
+
}
|
149
152
|
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
}
|
153
|
+
function proofToBytes(p: RateLimitProof): Uint8Array {
|
154
|
+
return concatenate(
|
155
|
+
p.proof,
|
156
|
+
p.merkleRoot,
|
157
|
+
p.epoch,
|
158
|
+
p.shareX,
|
159
|
+
p.shareY,
|
160
|
+
p.nullifier,
|
161
|
+
p.rlnIdentifier
|
162
|
+
);
|
161
163
|
}
|
162
164
|
|
163
165
|
export class RLNInstance {
|
164
|
-
constructor(
|
166
|
+
constructor(
|
167
|
+
private zkRLN: number,
|
168
|
+
private witnessCalculator: WitnessCalculator
|
169
|
+
) {}
|
165
170
|
|
166
171
|
generateMembershipKey(): MembershipKey {
|
167
172
|
const memKeys = zerokitRLN.generateMembershipKey(this.zkRLN);
|
168
|
-
return
|
173
|
+
return MembershipKey.fromBytes(memKeys);
|
169
174
|
}
|
170
175
|
|
171
176
|
insertMember(idCommitment: Uint8Array): void {
|
@@ -221,13 +226,16 @@ export class RLNInstance {
|
|
221
226
|
rlnWitness
|
222
227
|
);
|
223
228
|
|
224
|
-
return new
|
229
|
+
return new Proof(proofBytes);
|
225
230
|
}
|
226
231
|
|
227
232
|
verifyProof(proof: RateLimitProof | Uint8Array): boolean {
|
228
|
-
|
229
|
-
|
233
|
+
let pBytes: Uint8Array;
|
234
|
+
if (proof instanceof Uint8Array) {
|
235
|
+
pBytes = proof;
|
236
|
+
} else {
|
237
|
+
pBytes = proofToBytes(proof);
|
230
238
|
}
|
231
|
-
return zerokitRLN.verifyProof(this.zkRLN,
|
239
|
+
return zerokitRLN.verifyProof(this.zkRLN, pBytes);
|
232
240
|
}
|
233
241
|
}
|