@waku/rln 0.0.1 → 0.0.2-webpack.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 CHANGED
@@ -1,6 +1,6 @@
1
- import * as resources from "./resources";
2
- import * as wc from "./witness_calculator";
3
- import * as zerokitRLN from "./zerokit/rln_wasm";
1
+ import * as resources from "./resources.js";
2
+ import * as wc from "./witness_calculator.js";
3
+ import * as zerokitRLN from "./zerokit/rln_wasm.js";
4
4
 
5
5
  /**
6
6
  * Convert a base64 string into uint8Array
@@ -63,15 +63,104 @@ export class MembershipKey {
63
63
  }
64
64
  }
65
65
 
66
- export class RLNInstance {
67
- zkRLN: number;
68
- witnessCalculator: any;
66
+ // Adapted from https://github.com/feross/buffer
67
+
68
+ function checkInt(
69
+ buf: Uint8Array,
70
+ value: number,
71
+ offset: number,
72
+ ext: number,
73
+ max: number,
74
+ min: number
75
+ ): void {
76
+ if (value > max || value < min)
77
+ throw new RangeError('"value" argument is out of bounds');
78
+ if (offset + ext > buf.length) throw new RangeError("Index out of range");
79
+ }
80
+
81
+ const writeUIntLE = function writeUIntLE(
82
+ buf: Uint8Array,
83
+ value: number,
84
+ offset: number,
85
+ byteLength: number,
86
+ noAssert?: boolean
87
+ ): Uint8Array {
88
+ value = +value;
89
+ offset = offset >>> 0;
90
+ byteLength = byteLength >>> 0;
91
+ if (!noAssert) {
92
+ const maxBytes = Math.pow(2, 8 * byteLength) - 1;
93
+ checkInt(buf, value, offset, byteLength, maxBytes, 0);
94
+ }
95
+
96
+ let mul = 1;
97
+ let i = 0;
98
+ buf[offset] = value & 0xff;
99
+ while (++i < byteLength && (mul *= 0x100)) {
100
+ buf[offset + i] = (value / mul) & 0xff;
101
+ }
69
102
 
70
- constructor(zkRLN: number, wc: any) {
71
- this.zkRLN = zkRLN;
72
- this.witnessCalculator = wc;
103
+ return buf;
104
+ };
105
+
106
+ const DefaultEpochUnitSeconds = 10; // the rln-relay epoch length in seconds
107
+
108
+ export function toEpoch(
109
+ timestamp: Date,
110
+ epochUnitSeconds: number = DefaultEpochUnitSeconds
111
+ ): Uint8Array {
112
+ const unix = Math.floor(timestamp.getTime() / 1000 / epochUnitSeconds);
113
+ return writeUIntLE(new Uint8Array(32), unix, 0, 8);
114
+ }
115
+
116
+ const proofOffset = 128;
117
+ const rootOffset = proofOffset + 32;
118
+ const epochOffset = rootOffset + 32;
119
+ const shareXOffset = epochOffset + 32;
120
+ const shareYOffset = shareXOffset + 32;
121
+ const nullifierOffset = shareYOffset + 32;
122
+ const rlnIdentifierOffset = nullifierOffset + 32;
123
+
124
+ export class RateLimitProof {
125
+ readonly proof: Uint8Array;
126
+ readonly merkleRoot: Uint8Array;
127
+ readonly epoch: Uint8Array;
128
+ readonly shareX: Uint8Array;
129
+ readonly shareY: Uint8Array;
130
+ readonly nullifier: Uint8Array;
131
+ readonly rlnIdentifier: Uint8Array;
132
+
133
+ constructor(proofBytes: Uint8Array) {
134
+ if (proofBytes.length < rlnIdentifierOffset) throw "invalid proof";
135
+ // parse the proof as proof<128> | share_y<32> | nullifier<32> | root<32> | epoch<32> | share_x<32> | rln_identifier<32>
136
+ this.proof = proofBytes.subarray(0, proofOffset);
137
+ this.merkleRoot = proofBytes.subarray(proofOffset, rootOffset);
138
+ this.epoch = proofBytes.subarray(rootOffset, epochOffset);
139
+ this.shareX = proofBytes.subarray(epochOffset, shareXOffset);
140
+ this.shareY = proofBytes.subarray(shareXOffset, shareYOffset);
141
+ this.nullifier = proofBytes.subarray(shareYOffset, nullifierOffset);
142
+ this.rlnIdentifier = proofBytes.subarray(
143
+ nullifierOffset,
144
+ rlnIdentifierOffset
145
+ );
73
146
  }
74
147
 
148
+ toBytes(): Uint8Array {
149
+ return concatenate(
150
+ this.proof,
151
+ this.merkleRoot,
152
+ this.epoch,
153
+ this.shareX,
154
+ this.shareY,
155
+ this.nullifier,
156
+ this.rlnIdentifier
157
+ );
158
+ }
159
+ }
160
+
161
+ export class RLNInstance {
162
+ constructor(private zkRLN: number, private witnessCalculator: any) {}
163
+
75
164
  generateMembershipKey(): MembershipKey {
76
165
  const memKeys = zerokitRLN.generateMembershipKey(this.zkRLN);
77
166
  return new MembershipKey(memKeys);
@@ -87,16 +176,11 @@ export class RLNInstance {
87
176
  epoch: Uint8Array,
88
177
  idKey: Uint8Array
89
178
  ): Uint8Array {
90
- if (epoch.length != 32) throw "invalid epoch";
91
- if (idKey.length != 32) throw "invalid id key";
92
-
93
179
  // calculate message length
94
- const msgLen = Buffer.allocUnsafe(8);
95
- msgLen.writeUIntLE(uint8Msg.length, 0, 8);
180
+ const msgLen = writeUIntLE(new Uint8Array(8), uint8Msg.length, 0, 8);
96
181
 
97
182
  // Converting index to LE bytes
98
- const memIndexBytes = Buffer.allocUnsafe(8);
99
- memIndexBytes.writeUIntLE(memIndex, 0, 8);
183
+ const memIndexBytes = writeUIntLE(new Uint8Array(8), memIndex, 0, 8);
100
184
 
101
185
  // [ id_key<32> | id_index<8> | epoch<32> | signal_len<8> | signal<var> ]
102
186
  return concatenate(idKey, memIndexBytes, epoch, msgLen, uint8Msg);
@@ -105,9 +189,15 @@ export class RLNInstance {
105
189
  async generateProof(
106
190
  msg: Uint8Array,
107
191
  index: number,
108
- epoch: Uint8Array,
192
+ epoch: Uint8Array | Date | undefined,
109
193
  idKey: Uint8Array
110
- ): Promise<Uint8Array> {
194
+ ): Promise<RateLimitProof> {
195
+ if (epoch == undefined) {
196
+ epoch = toEpoch(new Date());
197
+ } else if (epoch instanceof Date) {
198
+ epoch = toEpoch(epoch);
199
+ }
200
+
111
201
  if (epoch.length != 32) throw "invalid epoch";
112
202
  if (idKey.length != 32) throw "invalid id key";
113
203
  if (index < 0) throw "index must be >= 0";
@@ -123,14 +213,19 @@ export class RLNInstance {
123
213
  false
124
214
  ); // no sanity check being used in zerokit
125
215
 
126
- return zerokitRLN.generate_rln_proof_with_witness(
216
+ const proofBytes = zerokitRLN.generate_rln_proof_with_witness(
127
217
  this.zkRLN,
128
218
  calculatedWitness,
129
219
  rlnWitness
130
220
  );
221
+
222
+ return new RateLimitProof(proofBytes);
131
223
  }
132
224
 
133
- verifyProof(proof: Uint8Array): boolean {
225
+ verifyProof(proof: RateLimitProof | Uint8Array): boolean {
226
+ if (proof instanceof RateLimitProof) {
227
+ proof = proof.toBytes();
228
+ }
134
229
  return zerokitRLN.verifyProof(this.zkRLN, proof);
135
230
  }
136
231
  }