@waku/rln 0.0.1

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/src/rln.ts ADDED
@@ -0,0 +1,136 @@
1
+ import * as resources from "./resources";
2
+ import * as wc from "./witness_calculator";
3
+ import * as zerokitRLN from "./zerokit/rln_wasm";
4
+
5
+ /**
6
+ * Convert a base64 string into uint8Array
7
+ * @param base64
8
+ * @returns Uint8Array
9
+ */
10
+ function base64ToUint8Array(base64: string): Uint8Array {
11
+ const binary_string = window.atob(base64);
12
+ const len = binary_string.length;
13
+ const bytes = new Uint8Array(len);
14
+ for (let i = 0; i < len; i++) {
15
+ bytes[i] = binary_string.charCodeAt(i);
16
+ }
17
+ return bytes;
18
+ }
19
+
20
+ /**
21
+ * Concatenate Uint8Arrays
22
+ * @param input
23
+ * @returns concatenation of all Uint8Array received as input
24
+ */
25
+ function concatenate(...input: Uint8Array[]): Uint8Array {
26
+ let totalLength = 0;
27
+ for (const arr of input) {
28
+ totalLength += arr.length;
29
+ }
30
+ const result = new Uint8Array(totalLength);
31
+ let offset = 0;
32
+ for (const arr of input) {
33
+ result.set(arr, offset);
34
+ offset += arr.length;
35
+ }
36
+ return result;
37
+ }
38
+
39
+ const DEPTH = 20;
40
+ const VERIFICATION_KEY = base64ToUint8Array(resources.verification_key);
41
+ const ZKEY = base64ToUint8Array(resources.zkey);
42
+ const CIRCUIT = base64ToUint8Array(resources.circuit);
43
+
44
+ zerokitRLN.init_panic_hook();
45
+
46
+ /**
47
+ * Create an instance of RLN
48
+ * @returns RLNInstance
49
+ */
50
+ export async function create(): Promise<RLNInstance> {
51
+ const witnessCalculator = await wc.builder(CIRCUIT, false);
52
+ const zkRLN = zerokitRLN.newRLN(DEPTH, ZKEY, VERIFICATION_KEY);
53
+ return new RLNInstance(zkRLN, witnessCalculator);
54
+ }
55
+
56
+ export class MembershipKey {
57
+ readonly IDKey: Uint8Array;
58
+ readonly IDCommitment: Uint8Array;
59
+
60
+ constructor(memKeys: Uint8Array) {
61
+ this.IDKey = memKeys.subarray(0, 32);
62
+ this.IDCommitment = memKeys.subarray(32);
63
+ }
64
+ }
65
+
66
+ export class RLNInstance {
67
+ zkRLN: number;
68
+ witnessCalculator: any;
69
+
70
+ constructor(zkRLN: number, wc: any) {
71
+ this.zkRLN = zkRLN;
72
+ this.witnessCalculator = wc;
73
+ }
74
+
75
+ generateMembershipKey(): MembershipKey {
76
+ const memKeys = zerokitRLN.generateMembershipKey(this.zkRLN);
77
+ return new MembershipKey(memKeys);
78
+ }
79
+
80
+ inserMember(idCommitment: Uint8Array): void {
81
+ zerokitRLN.insertMember(this.zkRLN, idCommitment);
82
+ }
83
+
84
+ serializeMessage(
85
+ uint8Msg: Uint8Array,
86
+ memIndex: number,
87
+ epoch: Uint8Array,
88
+ idKey: Uint8Array
89
+ ): Uint8Array {
90
+ if (epoch.length != 32) throw "invalid epoch";
91
+ if (idKey.length != 32) throw "invalid id key";
92
+
93
+ // calculate message length
94
+ const msgLen = Buffer.allocUnsafe(8);
95
+ msgLen.writeUIntLE(uint8Msg.length, 0, 8);
96
+
97
+ // Converting index to LE bytes
98
+ const memIndexBytes = Buffer.allocUnsafe(8);
99
+ memIndexBytes.writeUIntLE(memIndex, 0, 8);
100
+
101
+ // [ id_key<32> | id_index<8> | epoch<32> | signal_len<8> | signal<var> ]
102
+ return concatenate(idKey, memIndexBytes, epoch, msgLen, uint8Msg);
103
+ }
104
+
105
+ async generateProof(
106
+ msg: Uint8Array,
107
+ index: number,
108
+ epoch: Uint8Array,
109
+ idKey: Uint8Array
110
+ ): Promise<Uint8Array> {
111
+ if (epoch.length != 32) throw "invalid epoch";
112
+ if (idKey.length != 32) throw "invalid id key";
113
+ if (index < 0) throw "index must be >= 0";
114
+
115
+ const serialized_msg = this.serializeMessage(msg, index, epoch, idKey);
116
+ const rlnWitness = zerokitRLN.getSerializedRLNWitness(
117
+ this.zkRLN,
118
+ serialized_msg
119
+ );
120
+ const inputs = zerokitRLN.RLNWitnessToJson(this.zkRLN, rlnWitness);
121
+ const calculatedWitness = await this.witnessCalculator.calculateWitness(
122
+ inputs,
123
+ false
124
+ ); // no sanity check being used in zerokit
125
+
126
+ return zerokitRLN.generate_rln_proof_with_witness(
127
+ this.zkRLN,
128
+ calculatedWitness,
129
+ rlnWitness
130
+ );
131
+ }
132
+
133
+ verifyProof(proof: Uint8Array): boolean {
134
+ return zerokitRLN.verifyProof(this.zkRLN, proof);
135
+ }
136
+ }
@@ -0,0 +1,4 @@
1
+ export async function builder(
2
+ code: Uint8Array,
3
+ sanityCheck: bool
4
+ ): Promise<any>;