@waku/rln 0.1.6-ace7ca2.0 → 0.1.6-b133417.0
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/packages/rln/dist/contract/rln_base_contract.js +8 -32
- package/bundle/packages/rln/dist/contract/rln_contract.js +2 -2
- package/bundle/packages/rln/dist/credentials_manager.js +17 -11
- package/bundle/packages/rln/dist/identity.js +5 -0
- package/bundle/packages/rln/dist/keystore/keystore.js +18 -11
- package/bundle/packages/rln/dist/proof.js +2 -2
- package/bundle/packages/rln/dist/utils/bytes.js +108 -61
- package/bundle/packages/rln/dist/utils/hash.js +3 -3
- package/bundle/packages/rln/dist/zerokit.js +17 -17
- package/dist/.tsbuildinfo +1 -1
- package/dist/contract/rln_base_contract.d.ts +0 -6
- package/dist/contract/rln_base_contract.js +8 -32
- package/dist/contract/rln_base_contract.js.map +1 -1
- package/dist/contract/rln_contract.js +2 -2
- package/dist/contract/rln_contract.js.map +1 -1
- package/dist/credentials_manager.d.ts +4 -0
- package/dist/credentials_manager.js +18 -11
- package/dist/credentials_manager.js.map +1 -1
- package/dist/identity.d.ts +1 -0
- package/dist/identity.js +4 -0
- package/dist/identity.js.map +1 -1
- package/dist/keystore/keystore.js +18 -11
- package/dist/keystore/keystore.js.map +1 -1
- package/dist/proof.js +2 -2
- package/dist/proof.js.map +1 -1
- package/dist/utils/bytes.d.ts +42 -16
- package/dist/utils/bytes.js +107 -60
- package/dist/utils/bytes.js.map +1 -1
- package/dist/utils/hash.js +5 -5
- package/dist/utils/hash.js.map +1 -1
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.js +1 -1
- package/dist/utils/index.js.map +1 -1
- package/dist/zerokit.js +17 -17
- package/dist/zerokit.js.map +1 -1
- package/package.json +1 -1
- package/src/contract/rln_base_contract.ts +17 -50
- package/src/contract/rln_contract.ts +5 -2
- package/src/credentials_manager.ts +31 -15
- package/src/identity.ts +7 -1
- package/src/keystore/keystore.ts +25 -11
- package/src/proof.ts +2 -2
- package/src/utils/bytes.ts +117 -67
- package/src/utils/hash.ts +15 -5
- package/src/utils/index.ts +1 -6
- package/src/zerokit.ts +30 -22
@@ -13,9 +13,9 @@ import '../../../../node_modules/multiformats/dist/src/bases/base8.js';
|
|
13
13
|
import '../../../../node_modules/multiformats/dist/src/bases/identity.js';
|
14
14
|
import '../../../../node_modules/multiformats/dist/src/codecs/json.js';
|
15
15
|
import { Logger } from '../../../utils/dist/logger/index.js';
|
16
|
-
import {
|
16
|
+
import { BytesUtils } from '../utils/bytes.js';
|
17
17
|
import { RLN_ABI } from './abi.js';
|
18
|
-
import {
|
18
|
+
import { DEFAULT_RATE_LIMIT, RATE_LIMIT_PARAMS } from './constants.js';
|
19
19
|
import { MembershipState } from './types.js';
|
20
20
|
import { Contract } from '../../../../node_modules/@ethersproject/contracts/lib.esm/index.js';
|
21
21
|
import { BigNumber } from '../../../../node_modules/@ethersproject/bignumber/lib.esm/bignumber.js';
|
@@ -27,11 +27,6 @@ class RLNBaseContract {
|
|
27
27
|
rateLimit;
|
28
28
|
minRateLimit;
|
29
29
|
maxRateLimit;
|
30
|
-
/**
|
31
|
-
* Default Q value for the RLN contract.
|
32
|
-
* @see https://github.com/waku-org/waku-rlnv2-contract/blob/b7e9a9b1bc69256a2a3076c1f099b50ce84e7eff/src/WakuRlnV2.sol#L25
|
33
|
-
*/
|
34
|
-
idCommitmentBigIntLimit = DEFAULT_Q;
|
35
30
|
_members = new Map();
|
36
31
|
_membersFilter;
|
37
32
|
_membershipErasedFilter;
|
@@ -70,14 +65,12 @@ class RLNBaseContract {
|
|
70
65
|
*/
|
71
66
|
static async create(options) {
|
72
67
|
const instance = new RLNBaseContract(options);
|
73
|
-
const [min, max
|
68
|
+
const [min, max] = await Promise.all([
|
74
69
|
instance.contract.minMembershipRateLimit(),
|
75
|
-
instance.contract.maxMembershipRateLimit()
|
76
|
-
instance.contract.Q()
|
70
|
+
instance.contract.maxMembershipRateLimit()
|
77
71
|
]);
|
78
72
|
instance.minRateLimit = BigNumber.from(min).toNumber();
|
79
73
|
instance.maxRateLimit = BigNumber.from(max).toNumber();
|
80
|
-
instance.idCommitmentBigIntLimit = BigInt(idCommitmentBigIntLimit.toString());
|
81
74
|
instance.validateRateLimit(instance.rateLimit);
|
82
75
|
return instance;
|
83
76
|
}
|
@@ -345,28 +338,11 @@ class RLNBaseContract {
|
|
345
338
|
log.error(`Error in withdraw: ${error.message}`);
|
346
339
|
}
|
347
340
|
}
|
348
|
-
getIdCommitmentBigInt(bytes) {
|
349
|
-
let idCommitmentBigIntBE = buildBigIntFromUint8ArrayBE(bytes);
|
350
|
-
log.info("getIdCommitmentBigInt", {
|
351
|
-
idCommitmentBigIntBE,
|
352
|
-
idCommitmentBigIntLimit: this.idCommitmentBigIntLimit
|
353
|
-
});
|
354
|
-
if (!this.contract) {
|
355
|
-
throw Error("RLN contract is not initialized");
|
356
|
-
}
|
357
|
-
const idCommitmentBigIntLimit = this.contract.idCommitmentBigIntLimit;
|
358
|
-
if (idCommitmentBigIntBE >= idCommitmentBigIntLimit) {
|
359
|
-
log.warn(`ID commitment is greater than Q, reducing it by Q(idCommitmentBigIntLimit): ${idCommitmentBigIntBE} % ${idCommitmentBigIntLimit}`);
|
360
|
-
idCommitmentBigIntBE = idCommitmentBigIntBE % idCommitmentBigIntLimit;
|
361
|
-
}
|
362
|
-
return idCommitmentBigIntBE;
|
363
|
-
}
|
364
341
|
async registerWithIdentity(identity) {
|
365
342
|
try {
|
366
343
|
log.info(`Registering identity with rate limit: ${this.rateLimit} messages/epoch`);
|
367
|
-
const idCommitmentBigInt = this.getIdCommitmentBigInt(identity.IDCommitment);
|
368
344
|
// Check if the ID commitment is already registered
|
369
|
-
const existingIndex = await this.getMemberIndex(
|
345
|
+
const existingIndex = await this.getMemberIndex(identity.IDCommitmentBigInt);
|
370
346
|
if (existingIndex) {
|
371
347
|
throw new Error(`ID commitment is already registered with index ${existingIndex}`);
|
372
348
|
}
|
@@ -375,9 +351,9 @@ class RLNBaseContract {
|
|
375
351
|
if (remainingRateLimit < this.rateLimit) {
|
376
352
|
throw new Error(`Not enough remaining rate limit. Requested: ${this.rateLimit}, Available: ${remainingRateLimit}`);
|
377
353
|
}
|
378
|
-
const estimatedGas = await this.contract.estimateGas.register(
|
354
|
+
const estimatedGas = await this.contract.estimateGas.register(identity.IDCommitmentBigInt, this.rateLimit, []);
|
379
355
|
const gasLimit = estimatedGas.add(10000);
|
380
|
-
const txRegisterResponse = await this.contract.register(
|
356
|
+
const txRegisterResponse = await this.contract.register(identity.IDCommitmentBigInt, this.rateLimit, [], {
|
381
357
|
gasLimit
|
382
358
|
});
|
383
359
|
const txRegisterReceipt = await txRegisterResponse.wait();
|
@@ -441,7 +417,7 @@ class RLNBaseContract {
|
|
441
417
|
async registerWithPermitAndErase(identity, permit, idCommitmentsToErase) {
|
442
418
|
try {
|
443
419
|
log.info(`Registering identity with permit and rate limit: ${this.rateLimit} messages/epoch`);
|
444
|
-
const txRegisterResponse = await this.contract.registerWithPermit(permit.owner, permit.deadline, permit.v, permit.r, permit.s,
|
420
|
+
const txRegisterResponse = await this.contract.registerWithPermit(permit.owner, permit.deadline, permit.v, permit.r, permit.s, BytesUtils.buildBigIntFromUint8ArrayBE(identity.IDCommitment), this.rateLimit, idCommitmentsToErase.map((id) => BigNumber.from(id)));
|
445
421
|
const txRegisterReceipt = await txRegisterResponse.wait();
|
446
422
|
const memberRegistered = txRegisterReceipt.events?.find((event) => event.event === "MembershipRegistered");
|
447
423
|
if (!memberRegistered || !memberRegistered.args) {
|
@@ -4,7 +4,7 @@ import '../../../interfaces/dist/health_indicator.js';
|
|
4
4
|
import { hexToBytes } from '../../../utils/dist/bytes/index.js';
|
5
5
|
import { Logger } from '../../../utils/dist/logger/index.js';
|
6
6
|
import { MerkleRootTracker } from '../root_tracker.js';
|
7
|
-
import {
|
7
|
+
import { BytesUtils } from '../utils/bytes.js';
|
8
8
|
import { RLNBaseContract } from './rln_base_contract.js';
|
9
9
|
import { BigNumber } from '../../../../node_modules/@ethersproject/bignumber/lib.esm/bignumber.js';
|
10
10
|
|
@@ -83,7 +83,7 @@ class RLNContract extends RLNBaseContract {
|
|
83
83
|
if (typeof index === "number" || typeof index === "string") {
|
84
84
|
index = BigNumber.from(index);
|
85
85
|
}
|
86
|
-
const idCommitment = zeroPadLE(hexToBytes(_idCommitment), 32);
|
86
|
+
const idCommitment = BytesUtils.zeroPadLE(hexToBytes(_idCommitment), 32);
|
87
87
|
rlnInstance.zerokit.insertMember(idCommitment);
|
88
88
|
const numericIndex = index.toNumber();
|
89
89
|
this._members.set(numericIndex, {
|
@@ -15,12 +15,12 @@ import '../../../node_modules/multiformats/dist/src/bases/base8.js';
|
|
15
15
|
import '../../../node_modules/multiformats/dist/src/bases/identity.js';
|
16
16
|
import '../../../node_modules/multiformats/dist/src/codecs/json.js';
|
17
17
|
import { Logger } from '../../utils/dist/logger/index.js';
|
18
|
-
import { LINEA_CONTRACT } from './contract/constants.js';
|
18
|
+
import { LINEA_CONTRACT, DEFAULT_Q } from './contract/constants.js';
|
19
19
|
import { RLNBaseContract } from './contract/rln_base_contract.js';
|
20
20
|
import { IdentityCredential } from './identity.js';
|
21
21
|
import { Keystore } from './keystore/keystore.js';
|
22
|
+
import { BytesUtils } from './utils/bytes.js';
|
22
23
|
import { extractMetaMaskSigner } from './utils/metamask.js';
|
23
|
-
import { switchEndianness } from './utils/bytes.js';
|
24
24
|
import './utils/epoch.js';
|
25
25
|
|
26
26
|
const log = new Logger("waku:credentials");
|
@@ -202,15 +202,21 @@ class RLNCredentialsManager {
|
|
202
202
|
const idNullifierBE = hmac(sha256, seedBytes, encoder.encode("IDNullifier"));
|
203
203
|
const combinedBytes = new Uint8Array([...idTrapdoorBE, ...idNullifierBE]);
|
204
204
|
const idSecretHashBE = sha256(combinedBytes);
|
205
|
-
const
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
205
|
+
const idCommitmentRawBE = sha256(idSecretHashBE);
|
206
|
+
const idCommitmentBE = this.reduceIdCommitment(idCommitmentRawBE);
|
207
|
+
log.info("Successfully generated identity credential, storing in Big Endian format");
|
208
|
+
return new IdentityCredential(idTrapdoorBE, idNullifierBE, idSecretHashBE, idCommitmentBE);
|
209
|
+
}
|
210
|
+
/**
|
211
|
+
* Helper: take 32-byte BE, reduce mod Q, return 32-byte BE
|
212
|
+
*/
|
213
|
+
reduceIdCommitment(bytesBE, limit = DEFAULT_Q) {
|
214
|
+
const nBE = BytesUtils.buildBigIntFromUint8ArrayBE(bytesBE);
|
215
|
+
if (nBE >= limit) {
|
216
|
+
log.warn(`ID commitment is greater than Q, reducing it by Q: ${nBE} % ${limit}`);
|
217
|
+
return BytesUtils.bigIntToUint8Array32BE(nBE % limit);
|
218
|
+
}
|
219
|
+
return bytesBE;
|
214
220
|
}
|
215
221
|
}
|
216
222
|
|
@@ -1,8 +1,11 @@
|
|
1
|
+
import { BytesUtils } from './utils/bytes.js';
|
2
|
+
|
1
3
|
class IdentityCredential {
|
2
4
|
IDTrapdoor;
|
3
5
|
IDNullifier;
|
4
6
|
IDSecretHash;
|
5
7
|
IDCommitment;
|
8
|
+
IDCommitmentBigInt;
|
6
9
|
/**
|
7
10
|
* All variables are in little-endian format
|
8
11
|
*/
|
@@ -11,6 +14,8 @@ class IdentityCredential {
|
|
11
14
|
this.IDNullifier = IDNullifier;
|
12
15
|
this.IDSecretHash = IDSecretHash;
|
13
16
|
this.IDCommitment = IDCommitment;
|
17
|
+
this.IDCommitmentBigInt =
|
18
|
+
BytesUtils.buildBigIntFromUint8ArrayBE(IDCommitment);
|
14
19
|
}
|
15
20
|
static fromBytes(memKeys) {
|
16
21
|
if (memKeys.length < 128) {
|
@@ -17,6 +17,7 @@ import { Logger } from '../../../utils/dist/logger/index.js';
|
|
17
17
|
import { sha256 } from '../../../../node_modules/ethereum-cryptography/esm/sha256.js';
|
18
18
|
import { bytesToUtf8 } from '../../../../node_modules/ethereum-cryptography/esm/utils.js';
|
19
19
|
import _ from '../../../../node_modules/lodash/lodash.js';
|
20
|
+
import { BytesUtils } from '../utils/bytes.js';
|
20
21
|
import { keccak256Checksum, decryptEipKeystore } from './cipher.js';
|
21
22
|
import { isKeystoreValid, isCredentialValid } from './schema_validator.js';
|
22
23
|
import { __exports as lib } from '../../../../_virtual/index.js';
|
@@ -163,16 +164,24 @@ class Keystore {
|
|
163
164
|
try {
|
164
165
|
const str = bytesToUtf8(bytes);
|
165
166
|
const obj = JSON.parse(str);
|
167
|
+
// Little Endian
|
166
168
|
const idCommitmentLE = Keystore.fromArraylikeToBytes(_.get(obj, "identityCredential.idCommitment", []));
|
167
169
|
const idTrapdoorLE = Keystore.fromArraylikeToBytes(_.get(obj, "identityCredential.idTrapdoor", []));
|
168
170
|
const idNullifierLE = Keystore.fromArraylikeToBytes(_.get(obj, "identityCredential.idNullifier", []));
|
169
171
|
const idSecretHashLE = Keystore.fromArraylikeToBytes(_.get(obj, "identityCredential.idSecretHash", []));
|
172
|
+
// Big Endian
|
173
|
+
const idCommitmentBE = BytesUtils.switchEndianness(idCommitmentLE);
|
174
|
+
const idTrapdoorBE = BytesUtils.switchEndianness(idTrapdoorLE);
|
175
|
+
const idNullifierBE = BytesUtils.switchEndianness(idNullifierLE);
|
176
|
+
const idSecretHashBE = BytesUtils.switchEndianness(idSecretHashLE);
|
177
|
+
const idCommitmentBigInt = BytesUtils.buildBigIntFromUint8ArrayBE(idCommitmentBE);
|
170
178
|
return {
|
171
179
|
identity: {
|
172
|
-
IDCommitment:
|
173
|
-
IDTrapdoor:
|
174
|
-
IDNullifier:
|
175
|
-
IDSecretHash:
|
180
|
+
IDCommitment: idCommitmentBE,
|
181
|
+
IDTrapdoor: idTrapdoorBE,
|
182
|
+
IDNullifier: idNullifierBE,
|
183
|
+
IDSecretHash: idSecretHashBE,
|
184
|
+
IDCommitmentBigInt: idCommitmentBigInt
|
176
185
|
},
|
177
186
|
membership: {
|
178
187
|
treeIndex: _.get(obj, "treeIndex"),
|
@@ -208,17 +217,15 @@ class Keystore {
|
|
208
217
|
}
|
209
218
|
// follows nwaku implementation
|
210
219
|
// https://github.com/waku-org/nwaku/blob/f05528d4be3d3c876a8b07f9bb7dfaae8aa8ec6e/waku/waku_keystore/protocol_types.nim#L98
|
220
|
+
// IdentityCredential is stored in Big Endian format => switch to Little Endian
|
211
221
|
static fromIdentityToBytes(options) {
|
212
|
-
function toLittleEndian(bytes) {
|
213
|
-
return new Uint8Array(bytes).reverse();
|
214
|
-
}
|
215
222
|
return utf8ToBytes(JSON.stringify({
|
216
223
|
treeIndex: options.membership.treeIndex,
|
217
224
|
identityCredential: {
|
218
|
-
idCommitment: Array.from(
|
219
|
-
idNullifier: Array.from(
|
220
|
-
idSecretHash: Array.from(
|
221
|
-
idTrapdoor: Array.from(
|
225
|
+
idCommitment: Array.from(BytesUtils.switchEndianness(options.identity.IDCommitment)),
|
226
|
+
idNullifier: Array.from(BytesUtils.switchEndianness(options.identity.IDNullifier)),
|
227
|
+
idSecretHash: Array.from(BytesUtils.switchEndianness(options.identity.IDSecretHash)),
|
228
|
+
idTrapdoor: Array.from(BytesUtils.switchEndianness(options.identity.IDTrapdoor))
|
222
229
|
},
|
223
230
|
membershipContract: {
|
224
231
|
chainId: options.membership.chainId,
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import {
|
1
|
+
import { BytesUtils } from './utils/bytes.js';
|
2
2
|
import { poseidonHash } from './utils/hash.js';
|
3
3
|
import './utils/epoch.js';
|
4
4
|
|
@@ -48,7 +48,7 @@ class Proof {
|
|
48
48
|
}
|
49
49
|
}
|
50
50
|
function proofToBytes(p) {
|
51
|
-
return concatenate(p.proof, p.merkleRoot, p.epoch, p.shareX, p.shareY, p.nullifier, p.rlnIdentifier);
|
51
|
+
return BytesUtils.concatenate(p.proof, p.merkleRoot, p.epoch, p.shareX, p.shareY, p.nullifier, p.rlnIdentifier);
|
52
52
|
}
|
53
53
|
|
54
54
|
export { Proof, proofToBytes };
|
@@ -1,63 +1,110 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
result
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
1
|
+
class BytesUtils {
|
2
|
+
/**
|
3
|
+
* Switches endianness of a byte array
|
4
|
+
*/
|
5
|
+
static switchEndianness(bytes) {
|
6
|
+
return new Uint8Array(bytes.reverse());
|
7
|
+
}
|
8
|
+
/**
|
9
|
+
* Builds a BigInt from a big-endian Uint8Array
|
10
|
+
* @param bytes The big-endian bytes to convert
|
11
|
+
* @returns The resulting BigInt in big-endian format
|
12
|
+
*/
|
13
|
+
static buildBigIntFromUint8ArrayBE(bytes) {
|
14
|
+
let result = 0n;
|
15
|
+
for (let i = 0; i < bytes.length; i++) {
|
16
|
+
result = (result << 8n) + BigInt(bytes[i]);
|
17
|
+
}
|
18
|
+
return result;
|
19
|
+
}
|
20
|
+
/**
|
21
|
+
* Switches endianness of a bigint value
|
22
|
+
* @param value The bigint value to switch endianness for
|
23
|
+
* @returns The bigint value with reversed endianness
|
24
|
+
*/
|
25
|
+
static switchEndiannessBigInt(value) {
|
26
|
+
// Convert bigint to byte array
|
27
|
+
const bytes = [];
|
28
|
+
let tempValue = value;
|
29
|
+
while (tempValue > 0n) {
|
30
|
+
bytes.push(Number(tempValue & 0xffn));
|
31
|
+
tempValue >>= 8n;
|
32
|
+
}
|
33
|
+
// Reverse bytes and convert back to bigint
|
34
|
+
return bytes
|
35
|
+
.reverse()
|
36
|
+
.reduce((acc, byte) => (acc << 8n) + BigInt(byte), 0n);
|
37
|
+
}
|
38
|
+
/**
|
39
|
+
* Converts a big-endian bigint to a 32-byte big-endian Uint8Array
|
40
|
+
* @param value The big-endian bigint to convert
|
41
|
+
* @returns A 32-byte big-endian Uint8Array
|
42
|
+
*/
|
43
|
+
static bigIntToUint8Array32BE(value) {
|
44
|
+
const bytes = new Uint8Array(32);
|
45
|
+
for (let i = 31; i >= 0; i--) {
|
46
|
+
bytes[i] = Number(value & 0xffn);
|
47
|
+
value >>= 8n;
|
48
|
+
}
|
49
|
+
return bytes;
|
50
|
+
}
|
51
|
+
/**
|
52
|
+
* Writes an unsigned integer to a buffer in little-endian format
|
53
|
+
*/
|
54
|
+
static writeUIntLE(buf, value, offset, byteLength, noAssert) {
|
55
|
+
value = +value;
|
56
|
+
offset = offset >>> 0;
|
57
|
+
byteLength = byteLength >>> 0;
|
58
|
+
if (!noAssert) {
|
59
|
+
const maxBytes = Math.pow(2, 8 * byteLength) - 1;
|
60
|
+
BytesUtils.checkInt(buf, value, offset, byteLength, maxBytes, 0);
|
61
|
+
}
|
62
|
+
let mul = 1;
|
63
|
+
let i = 0;
|
64
|
+
buf[offset] = value & 0xff;
|
65
|
+
while (++i < byteLength && (mul *= 0x100)) {
|
66
|
+
buf[offset + i] = (value / mul) & 0xff;
|
67
|
+
}
|
68
|
+
return buf;
|
69
|
+
}
|
70
|
+
/**
|
71
|
+
* Fills with zeros to set length
|
72
|
+
* @param array little endian Uint8Array
|
73
|
+
* @param length amount to pad
|
74
|
+
* @returns little endian Uint8Array padded with zeros to set length
|
75
|
+
*/
|
76
|
+
static zeroPadLE(array, length) {
|
77
|
+
const result = new Uint8Array(length);
|
78
|
+
for (let i = 0; i < length; i++) {
|
79
|
+
result[i] = array[i] || 0;
|
80
|
+
}
|
81
|
+
return result;
|
82
|
+
}
|
83
|
+
// Adapted from https://github.com/feross/buffer
|
84
|
+
static checkInt(buf, value, offset, ext, max, min) {
|
85
|
+
if (value > max || value < min)
|
86
|
+
throw new RangeError('"value" argument is out of bounds');
|
87
|
+
if (offset + ext > buf.length)
|
88
|
+
throw new RangeError("Index out of range");
|
89
|
+
}
|
90
|
+
/**
|
91
|
+
* Concatenate Uint8Arrays
|
92
|
+
* @param input
|
93
|
+
* @returns concatenation of all Uint8Array received as input
|
94
|
+
*/
|
95
|
+
static concatenate(...input) {
|
96
|
+
let totalLength = 0;
|
97
|
+
for (const arr of input) {
|
98
|
+
totalLength += arr.length;
|
99
|
+
}
|
100
|
+
const result = new Uint8Array(totalLength);
|
101
|
+
let offset = 0;
|
102
|
+
for (const arr of input) {
|
103
|
+
result.set(arr, offset);
|
104
|
+
offset += arr.length;
|
105
|
+
}
|
106
|
+
return result;
|
107
|
+
}
|
61
108
|
}
|
62
109
|
|
63
|
-
export {
|
110
|
+
export { BytesUtils };
|
@@ -1,9 +1,9 @@
|
|
1
1
|
import { poseidonHash as poseidonHash$1 } from '../../../../node_modules/@waku/zerokit-rln-wasm/rln_wasm.js';
|
2
|
-
import {
|
2
|
+
import { BytesUtils } from './bytes.js';
|
3
3
|
|
4
4
|
function poseidonHash(...input) {
|
5
|
-
const inputLen = writeUIntLE(new Uint8Array(8), input.length, 0, 8);
|
6
|
-
const lenPrefixedData = concatenate(inputLen, ...input);
|
5
|
+
const inputLen = BytesUtils.writeUIntLE(new Uint8Array(8), input.length, 0, 8);
|
6
|
+
const lenPrefixedData = BytesUtils.concatenate(inputLen, ...input);
|
7
7
|
return poseidonHash$1(lenPrefixedData);
|
8
8
|
}
|
9
9
|
|
@@ -2,7 +2,7 @@ import { generateExtendedMembershipKey, generateSeededExtendedMembershipKey, ins
|
|
2
2
|
import { DEFAULT_RATE_LIMIT, RATE_LIMIT_PARAMS } from './contract/constants.js';
|
3
3
|
import { IdentityCredential } from './identity.js';
|
4
4
|
import { Proof, proofToBytes } from './proof.js';
|
5
|
-
import {
|
5
|
+
import { BytesUtils } from './utils/bytes.js';
|
6
6
|
import { epochIntToBytes, dateToEpoch } from './utils/epoch.js';
|
7
7
|
|
8
8
|
class Zerokit {
|
@@ -40,8 +40,8 @@ class Zerokit {
|
|
40
40
|
insertMembers(index, ...idCommitments) {
|
41
41
|
// serializes a seq of IDCommitments to a byte seq
|
42
42
|
// the order of serialization is |id_commitment_len<8>|id_commitment<var>|
|
43
|
-
const idCommitmentLen = writeUIntLE(new Uint8Array(8), idCommitments.length, 0, 8);
|
44
|
-
const idCommitmentBytes = concatenate(idCommitmentLen, ...idCommitments);
|
43
|
+
const idCommitmentLen = BytesUtils.writeUIntLE(new Uint8Array(8), idCommitments.length, 0, 8);
|
44
|
+
const idCommitmentBytes = BytesUtils.concatenate(idCommitmentLen, ...idCommitments);
|
45
45
|
setLeavesFrom(this.zkRLN, index, idCommitmentBytes);
|
46
46
|
}
|
47
47
|
deleteMember(index) {
|
@@ -52,11 +52,11 @@ class Zerokit {
|
|
52
52
|
}
|
53
53
|
serializeMessage(uint8Msg, memIndex, epoch, idKey, rateLimit) {
|
54
54
|
// calculate message length
|
55
|
-
const msgLen = writeUIntLE(new Uint8Array(8), uint8Msg.length, 0, 8);
|
56
|
-
const memIndexBytes = writeUIntLE(new Uint8Array(8), memIndex, 0, 8);
|
57
|
-
const rateLimitBytes = writeUIntLE(new Uint8Array(8), rateLimit ?? this.rateLimit, 0, 8);
|
55
|
+
const msgLen = BytesUtils.writeUIntLE(new Uint8Array(8), uint8Msg.length, 0, 8);
|
56
|
+
const memIndexBytes = BytesUtils.writeUIntLE(new Uint8Array(8), memIndex, 0, 8);
|
57
|
+
const rateLimitBytes = BytesUtils.writeUIntLE(new Uint8Array(8), rateLimit ?? this.rateLimit, 0, 8);
|
58
58
|
// [ id_key<32> | id_index<8> | epoch<32> | signal_len<8> | signal<var> | rate_limit<8> ]
|
59
|
-
return concatenate(idKey, memIndexBytes, epoch, msgLen, uint8Msg, rateLimitBytes);
|
59
|
+
return BytesUtils.concatenate(idKey, memIndexBytes, epoch, msgLen, uint8Msg, rateLimitBytes);
|
60
60
|
}
|
61
61
|
async generateRLNProof(msg, index, epoch, idSecretHash, rateLimit) {
|
62
62
|
if (epoch === undefined) {
|
@@ -92,9 +92,9 @@ class Zerokit {
|
|
92
92
|
pBytes = proofToBytes(proof);
|
93
93
|
}
|
94
94
|
// calculate message length
|
95
|
-
const msgLen = writeUIntLE(new Uint8Array(8), msg.length, 0, 8);
|
96
|
-
const rateLimitBytes = writeUIntLE(new Uint8Array(8), rateLimit ?? this.rateLimit, 0, 8);
|
97
|
-
return verifyRLNProof(this.zkRLN, concatenate(pBytes, msgLen, msg, rateLimitBytes));
|
95
|
+
const msgLen = BytesUtils.writeUIntLE(new Uint8Array(8), msg.length, 0, 8);
|
96
|
+
const rateLimitBytes = BytesUtils.writeUIntLE(new Uint8Array(8), rateLimit ?? this.rateLimit, 0, 8);
|
97
|
+
return verifyRLNProof(this.zkRLN, BytesUtils.concatenate(pBytes, msgLen, msg, rateLimitBytes));
|
98
98
|
}
|
99
99
|
verifyWithRoots(proof, msg, roots, rateLimit) {
|
100
100
|
let pBytes;
|
@@ -105,10 +105,10 @@ class Zerokit {
|
|
105
105
|
pBytes = proofToBytes(proof);
|
106
106
|
}
|
107
107
|
// calculate message length
|
108
|
-
const msgLen = writeUIntLE(new Uint8Array(8), msg.length, 0, 8);
|
109
|
-
const rateLimitBytes = writeUIntLE(new Uint8Array(8), rateLimit ?? this.rateLimit, 0, 8);
|
110
|
-
const rootsBytes = concatenate(...roots);
|
111
|
-
return verifyWithRoots(this.zkRLN, concatenate(pBytes, msgLen, msg, rateLimitBytes), rootsBytes);
|
108
|
+
const msgLen = BytesUtils.writeUIntLE(new Uint8Array(8), msg.length, 0, 8);
|
109
|
+
const rateLimitBytes = BytesUtils.writeUIntLE(new Uint8Array(8), rateLimit ?? this.rateLimit, 0, 8);
|
110
|
+
const rootsBytes = BytesUtils.concatenate(...roots);
|
111
|
+
return verifyWithRoots(this.zkRLN, BytesUtils.concatenate(pBytes, msgLen, msg, rateLimitBytes), rootsBytes);
|
112
112
|
}
|
113
113
|
verifyWithNoRoot(proof, msg, rateLimit) {
|
114
114
|
let pBytes;
|
@@ -119,9 +119,9 @@ class Zerokit {
|
|
119
119
|
pBytes = proofToBytes(proof);
|
120
120
|
}
|
121
121
|
// calculate message length
|
122
|
-
const msgLen = writeUIntLE(new Uint8Array(8), msg.length, 0, 8);
|
123
|
-
const rateLimitBytes = writeUIntLE(new Uint8Array(8), rateLimit ?? this.rateLimit, 0, 8);
|
124
|
-
return verifyWithRoots(this.zkRLN, concatenate(pBytes, msgLen, msg, rateLimitBytes), new Uint8Array());
|
122
|
+
const msgLen = BytesUtils.writeUIntLE(new Uint8Array(8), msg.length, 0, 8);
|
123
|
+
const rateLimitBytes = BytesUtils.writeUIntLE(new Uint8Array(8), rateLimit ?? this.rateLimit, 0, 8);
|
124
|
+
return verifyWithRoots(this.zkRLN, BytesUtils.concatenate(pBytes, msgLen, msg, rateLimitBytes), new Uint8Array());
|
125
125
|
}
|
126
126
|
}
|
127
127
|
|