@waku/rln 0.1.6 → 0.1.7-36f6884.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/index.js +2 -2
- package/bundle/packages/core/dist/lib/connection_manager/connection_limiter.js +17 -0
- package/bundle/packages/core/dist/lib/connection_manager/connection_manager.js +9 -5
- package/bundle/packages/core/dist/lib/connection_manager/dialer.js +17 -0
- package/bundle/packages/core/dist/lib/connection_manager/discovery_dialer.js +17 -0
- package/bundle/packages/core/dist/lib/connection_manager/keep_alive_manager.js +2 -2
- package/bundle/packages/core/dist/lib/connection_manager/shard_reader.js +17 -0
- package/bundle/packages/core/dist/lib/filter/filter.js +3 -3
- package/bundle/packages/core/dist/lib/light_push/light_push.js +2 -2
- package/bundle/packages/core/dist/lib/message/version_0.js +1 -1
- package/bundle/packages/core/dist/lib/metadata/metadata.js +2 -2
- package/bundle/packages/core/dist/lib/store/store.js +2 -2
- package/bundle/packages/interfaces/dist/connection_manager.js +2 -12
- package/bundle/packages/interfaces/dist/{health_indicator.js → health_status.js} +10 -5
- package/bundle/packages/proto/dist/generated/light_push.js +160 -1
- package/bundle/packages/rln/dist/codec.js +2 -2
- package/bundle/packages/rln/dist/contract/abi/price_calculator.js +95 -0
- package/bundle/packages/rln/dist/contract/constants.js +15 -3
- package/bundle/packages/rln/dist/contract/rln_base_contract.js +25 -6
- package/bundle/packages/rln/dist/contract/rln_contract.js +4 -4
- package/bundle/packages/rln/dist/credentials_manager.js +25 -21
- package/bundle/packages/rln/dist/identity.js +8 -6
- package/bundle/packages/rln/dist/keystore/keystore.js +40 -13
- package/bundle/packages/rln/dist/message.js +1 -1
- package/bundle/packages/rln/dist/proof.js +2 -2
- package/bundle/packages/rln/dist/rln.js +2 -2
- package/bundle/packages/rln/dist/utils/bytes.js +103 -58
- package/bundle/packages/rln/dist/utils/epoch.js +2 -2
- package/bundle/packages/rln/dist/utils/hash.js +3 -3
- package/bundle/packages/rln/dist/zerokit.js +17 -17
- package/bundle/packages/utils/dist/common/sharding/index.js +1 -1
- package/bundle/packages/utils/dist/{logger/index.js → logger.js} +3 -3
- package/dist/.tsbuildinfo +1 -1
- package/dist/contract/abi/price_calculator.d.ts +46 -0
- package/dist/contract/abi/price_calculator.js +94 -0
- package/dist/contract/abi/price_calculator.js.map +1 -0
- package/dist/contract/{abi.js → abi/rln.js} +1 -1
- package/dist/contract/abi/rln.js.map +1 -0
- package/dist/contract/constants.d.ts +57 -1
- package/dist/contract/constants.js +14 -2
- package/dist/contract/constants.js.map +1 -1
- package/dist/contract/rln_base_contract.d.ts +9 -0
- package/dist/contract/rln_base_contract.js +23 -4
- 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/contract/{test-setup.d.ts → test_setup.d.ts} +4 -4
- package/dist/contract/{test-setup.js → test_setup.js} +4 -4
- package/dist/contract/{test-setup.js.map → test_setup.js.map} +1 -1
- package/dist/contract/{test-utils.js → test_utils.js} +10 -10
- package/dist/contract/{test-utils.js.map → test_utils.js.map} +1 -1
- package/dist/credentials_manager.d.ts +4 -0
- package/dist/credentials_manager.js +24 -19
- package/dist/credentials_manager.js.map +1 -1
- package/dist/identity.d.ts +5 -2
- package/dist/identity.js +8 -5
- package/dist/identity.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/keystore/keystore.js +38 -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 -20
- package/dist/utils/bytes.js +102 -57
- 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 -93
- package/src/contract/abi/price_calculator.ts +93 -0
- package/src/contract/constants.ts +18 -2
- package/src/contract/rln_base_contract.ts +38 -5
- package/src/contract/rln_contract.ts +5 -2
- package/src/contract/{test-setup.ts → test_setup.ts} +4 -4
- package/src/contract/{test-utils.ts → test_utils.ts} +9 -9
- package/src/credentials_manager.ts +41 -27
- package/src/identity.ts +11 -7
- package/src/index.ts +3 -3
- package/src/keystore/keystore.ts +52 -23
- package/src/proof.ts +2 -2
- package/src/utils/bytes.ts +118 -72
- package/src/utils/hash.ts +15 -5
- package/src/utils/index.ts +1 -6
- package/src/zerokit.ts +30 -22
- package/dist/contract/abi.js.map +0 -1
- /package/bundle/packages/rln/dist/contract/{abi.js → abi/rln.js} +0 -0
- /package/dist/contract/{abi.d.ts → abi/rln.d.ts} +0 -0
- /package/dist/contract/{test-utils.d.ts → test_utils.d.ts} +0 -0
- /package/src/contract/{abi.ts → abi/rln.ts} +0 -0
@@ -1,9 +1,9 @@
|
|
1
1
|
import { hmac } from "@noble/hashes/hmac";
|
2
|
-
import { sha256 } from "@noble/hashes/
|
2
|
+
import { sha256 } from "@noble/hashes/sha2";
|
3
3
|
import { Logger } from "@waku/utils";
|
4
4
|
import { ethers } from "ethers";
|
5
5
|
|
6
|
-
import {
|
6
|
+
import { RLN_CONTRACT, RLN_Q } from "./contract/constants.js";
|
7
7
|
import { RLNBaseContract } from "./contract/rln_base_contract.js";
|
8
8
|
import { IdentityCredential } from "./identity.js";
|
9
9
|
import { Keystore } from "./keystore/index.js";
|
@@ -13,10 +13,8 @@ import type {
|
|
13
13
|
} from "./keystore/index.js";
|
14
14
|
import { KeystoreEntity, Password } from "./keystore/types.js";
|
15
15
|
import { RegisterMembershipOptions, StartRLNOptions } from "./types.js";
|
16
|
-
import {
|
17
|
-
|
18
|
-
extractMetaMaskSigner
|
19
|
-
} from "./utils/index.js";
|
16
|
+
import { BytesUtils } from "./utils/bytes.js";
|
17
|
+
import { extractMetaMaskSigner } from "./utils/index.js";
|
20
18
|
import { Zerokit } from "./zerokit.js";
|
21
19
|
|
22
20
|
const log = new Logger("waku:credentials");
|
@@ -116,7 +114,9 @@ export class RLNCredentialsManager {
|
|
116
114
|
);
|
117
115
|
} else {
|
118
116
|
log.info("Using local implementation to generate identity");
|
119
|
-
identity = this.generateSeededIdentityCredential(
|
117
|
+
identity = await this.generateSeededIdentityCredential(
|
118
|
+
options.signature
|
119
|
+
);
|
120
120
|
}
|
121
121
|
}
|
122
122
|
|
@@ -152,10 +152,10 @@ export class RLNCredentialsManager {
|
|
152
152
|
const address =
|
153
153
|
credentials?.membership.address ||
|
154
154
|
options.address ||
|
155
|
-
|
155
|
+
RLN_CONTRACT.address;
|
156
156
|
|
157
|
-
if (address ===
|
158
|
-
chainId =
|
157
|
+
if (address === RLN_CONTRACT.address) {
|
158
|
+
chainId = RLN_CONTRACT.chainId.toString();
|
159
159
|
log.info(`Using Linea contract with chainId: ${chainId}`);
|
160
160
|
}
|
161
161
|
|
@@ -249,7 +249,9 @@ export class RLNCredentialsManager {
|
|
249
249
|
* @param seed A string seed to generate the identity from
|
250
250
|
* @returns IdentityCredential
|
251
251
|
*/
|
252
|
-
private generateSeededIdentityCredential(
|
252
|
+
private async generateSeededIdentityCredential(
|
253
|
+
seed: string
|
254
|
+
): Promise<IdentityCredential> {
|
253
255
|
log.info("Generating seeded identity credential");
|
254
256
|
// Convert the seed to bytes
|
255
257
|
const encoder = new TextEncoder();
|
@@ -257,26 +259,38 @@ export class RLNCredentialsManager {
|
|
257
259
|
|
258
260
|
// Generate deterministic values using HMAC-SHA256
|
259
261
|
// We use different context strings for each component to ensure they're different
|
260
|
-
const
|
261
|
-
const
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
262
|
+
const idTrapdoorBE = hmac(sha256, seedBytes, encoder.encode("IDTrapdoor"));
|
263
|
+
const idNullifierBE = hmac(
|
264
|
+
sha256,
|
265
|
+
seedBytes,
|
266
|
+
encoder.encode("IDNullifier")
|
267
|
+
);
|
266
268
|
|
267
|
-
|
268
|
-
const
|
269
|
+
const combinedBytes = new Uint8Array([...idTrapdoorBE, ...idNullifierBE]);
|
270
|
+
const idSecretHashBE = sha256(combinedBytes);
|
269
271
|
|
270
|
-
|
271
|
-
const
|
272
|
+
const idCommitmentRawBE = sha256(idSecretHashBE);
|
273
|
+
const idCommitmentBE = this.reduceIdCommitment(idCommitmentRawBE);
|
272
274
|
|
273
|
-
log.info(
|
275
|
+
log.info(
|
276
|
+
"Successfully generated identity credential, storing in Big Endian format"
|
277
|
+
);
|
274
278
|
return new IdentityCredential(
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
idCommitmentBigInt
|
279
|
+
idTrapdoorBE,
|
280
|
+
idNullifierBE,
|
281
|
+
idSecretHashBE,
|
282
|
+
idCommitmentBE
|
280
283
|
);
|
281
284
|
}
|
285
|
+
|
286
|
+
/**
|
287
|
+
* Helper: take 32-byte BE, reduce mod Q, return 32-byte BE
|
288
|
+
*/
|
289
|
+
private reduceIdCommitment(
|
290
|
+
bytesBE: Uint8Array,
|
291
|
+
limit: bigint = RLN_Q
|
292
|
+
): Uint8Array {
|
293
|
+
const nBE = BytesUtils.buildBigIntFromUint8ArrayBE(bytesBE);
|
294
|
+
return BytesUtils.bigIntToUint8Array32BE(nBE % limit);
|
295
|
+
}
|
282
296
|
}
|
package/src/identity.ts
CHANGED
@@ -1,13 +1,19 @@
|
|
1
|
-
import {
|
1
|
+
import { BytesUtils } from "./utils/bytes.js";
|
2
2
|
|
3
3
|
export class IdentityCredential {
|
4
|
+
public IDCommitmentBigInt: bigint;
|
5
|
+
/**
|
6
|
+
* All variables are in little-endian format
|
7
|
+
*/
|
4
8
|
public constructor(
|
5
9
|
public readonly IDTrapdoor: Uint8Array,
|
6
10
|
public readonly IDNullifier: Uint8Array,
|
7
11
|
public readonly IDSecretHash: Uint8Array,
|
8
|
-
public readonly IDCommitment: Uint8Array
|
9
|
-
|
10
|
-
|
12
|
+
public readonly IDCommitment: Uint8Array
|
13
|
+
) {
|
14
|
+
this.IDCommitmentBigInt =
|
15
|
+
BytesUtils.buildBigIntFromUint8ArrayBE(IDCommitment);
|
16
|
+
}
|
11
17
|
|
12
18
|
public static fromBytes(memKeys: Uint8Array): IdentityCredential {
|
13
19
|
if (memKeys.length < 128) {
|
@@ -18,14 +24,12 @@ export class IdentityCredential {
|
|
18
24
|
const idNullifier = memKeys.subarray(32, 64);
|
19
25
|
const idSecretHash = memKeys.subarray(64, 96);
|
20
26
|
const idCommitment = memKeys.subarray(96, 128);
|
21
|
-
const idCommitmentBigInt = buildBigIntFromUint8Array(idCommitment, 32);
|
22
27
|
|
23
28
|
return new IdentityCredential(
|
24
29
|
idTrapdoor,
|
25
30
|
idNullifier,
|
26
31
|
idSecretHash,
|
27
|
-
idCommitment
|
28
|
-
idCommitmentBigInt
|
32
|
+
idCommitment
|
29
33
|
);
|
30
34
|
}
|
31
35
|
}
|
package/src/index.ts
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
import { RLNDecoder, RLNEncoder } from "./codec.js";
|
2
|
-
import { RLN_ABI } from "./contract/abi.js";
|
3
|
-
import {
|
2
|
+
import { RLN_ABI } from "./contract/abi/rln.js";
|
3
|
+
import { RLN_CONTRACT, RLNContract } from "./contract/index.js";
|
4
4
|
import { RLNBaseContract } from "./contract/rln_base_contract.js";
|
5
5
|
import { createRLN } from "./create.js";
|
6
6
|
import { RLNCredentialsManager } from "./credentials_manager.js";
|
@@ -23,7 +23,7 @@ export {
|
|
23
23
|
RLNDecoder,
|
24
24
|
MerkleRootTracker,
|
25
25
|
RLNContract,
|
26
|
-
|
26
|
+
RLN_CONTRACT,
|
27
27
|
extractMetaMaskSigner,
|
28
28
|
RLN_ABI
|
29
29
|
};
|
package/src/keystore/keystore.ts
CHANGED
@@ -14,7 +14,7 @@ import {
|
|
14
14
|
import _ from "lodash";
|
15
15
|
import { v4 as uuidV4 } from "uuid";
|
16
16
|
|
17
|
-
import {
|
17
|
+
import { BytesUtils } from "../utils/bytes.js";
|
18
18
|
|
19
19
|
import { decryptEipKeystore, keccak256Checksum } from "./cipher.js";
|
20
20
|
import { isCredentialValid, isKeystoreValid } from "./schema_validator.js";
|
@@ -250,26 +250,35 @@ export class Keystore {
|
|
250
250
|
const str = bytesToUtf8(bytes);
|
251
251
|
const obj = JSON.parse(str);
|
252
252
|
|
253
|
-
//
|
253
|
+
// Little Endian
|
254
|
+
const idCommitmentLE = Keystore.fromArraylikeToBytes(
|
255
|
+
_.get(obj, "identityCredential.idCommitment", [])
|
256
|
+
);
|
257
|
+
const idTrapdoorLE = Keystore.fromArraylikeToBytes(
|
258
|
+
_.get(obj, "identityCredential.idTrapdoor", [])
|
259
|
+
);
|
260
|
+
const idNullifierLE = Keystore.fromArraylikeToBytes(
|
261
|
+
_.get(obj, "identityCredential.idNullifier", [])
|
262
|
+
);
|
263
|
+
const idSecretHashLE = Keystore.fromArraylikeToBytes(
|
264
|
+
_.get(obj, "identityCredential.idSecretHash", [])
|
265
|
+
);
|
266
|
+
|
267
|
+
// Big Endian
|
268
|
+
const idCommitmentBE = BytesUtils.switchEndianness(idCommitmentLE);
|
269
|
+
const idTrapdoorBE = BytesUtils.switchEndianness(idTrapdoorLE);
|
270
|
+
const idNullifierBE = BytesUtils.switchEndianness(idNullifierLE);
|
271
|
+
const idSecretHashBE = BytesUtils.switchEndianness(idSecretHashLE);
|
272
|
+
const idCommitmentBigInt =
|
273
|
+
BytesUtils.buildBigIntFromUint8ArrayBE(idCommitmentBE);
|
274
|
+
|
254
275
|
return {
|
255
276
|
identity: {
|
256
|
-
IDCommitment:
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
),
|
262
|
-
IDNullifier: Keystore.fromArraylikeToBytes(
|
263
|
-
_.get(obj, "identityCredential.idNullifier", [])
|
264
|
-
),
|
265
|
-
IDCommitmentBigInt: buildBigIntFromUint8Array(
|
266
|
-
Keystore.fromArraylikeToBytes(
|
267
|
-
_.get(obj, "identityCredential.idCommitment", [])
|
268
|
-
)
|
269
|
-
),
|
270
|
-
IDSecretHash: Keystore.fromArraylikeToBytes(
|
271
|
-
_.get(obj, "identityCredential.idSecretHash", [])
|
272
|
-
)
|
277
|
+
IDCommitment: idCommitmentBE,
|
278
|
+
IDTrapdoor: idTrapdoorBE,
|
279
|
+
IDNullifier: idNullifierBE,
|
280
|
+
IDSecretHash: idSecretHashBE,
|
281
|
+
IDCommitmentBigInt: idCommitmentBigInt
|
273
282
|
},
|
274
283
|
membership: {
|
275
284
|
treeIndex: _.get(obj, "treeIndex"),
|
@@ -320,15 +329,35 @@ export class Keystore {
|
|
320
329
|
|
321
330
|
// follows nwaku implementation
|
322
331
|
// https://github.com/waku-org/nwaku/blob/f05528d4be3d3c876a8b07f9bb7dfaae8aa8ec6e/waku/waku_keystore/protocol_types.nim#L98
|
332
|
+
// IdentityCredential is stored in Big Endian format => switch to Little Endian
|
323
333
|
private static fromIdentityToBytes(options: KeystoreEntity): Uint8Array {
|
334
|
+
const { IDCommitment, IDNullifier, IDSecretHash, IDTrapdoor } =
|
335
|
+
options.identity;
|
336
|
+
const idCommitmentLE = BytesUtils.switchEndianness(IDCommitment);
|
337
|
+
const idNullifierLE = BytesUtils.switchEndianness(IDNullifier);
|
338
|
+
const idSecretHashLE = BytesUtils.switchEndianness(IDSecretHash);
|
339
|
+
const idTrapdoorLE = BytesUtils.switchEndianness(IDTrapdoor);
|
340
|
+
|
341
|
+
// eslint-disable-next-line no-console
|
342
|
+
console.log({
|
343
|
+
idCommitmentBE: IDCommitment,
|
344
|
+
idCommitmentLE,
|
345
|
+
idNullifierBE: IDNullifier,
|
346
|
+
idNullifierLE,
|
347
|
+
idSecretHashBE: IDSecretHash,
|
348
|
+
idSecretHashLE,
|
349
|
+
idTrapdoorBE: IDTrapdoor,
|
350
|
+
idTrapdoorLE
|
351
|
+
});
|
352
|
+
|
324
353
|
return utf8ToBytes(
|
325
354
|
JSON.stringify({
|
326
355
|
treeIndex: options.membership.treeIndex,
|
327
356
|
identityCredential: {
|
328
|
-
idCommitment: Array.from(
|
329
|
-
idNullifier: Array.from(
|
330
|
-
idSecretHash: Array.from(
|
331
|
-
idTrapdoor: Array.from(
|
357
|
+
idCommitment: Array.from(idCommitmentLE),
|
358
|
+
idNullifier: Array.from(idNullifierLE),
|
359
|
+
idSecretHash: Array.from(idSecretHashLE),
|
360
|
+
idTrapdoor: Array.from(idTrapdoorLE)
|
332
361
|
},
|
333
362
|
membershipContract: {
|
334
363
|
chainId: options.membership.chainId,
|
package/src/proof.ts
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
import type { IRateLimitProof } from "@waku/interfaces";
|
2
2
|
|
3
|
-
import {
|
3
|
+
import { BytesUtils, poseidonHash } from "./utils/index.js";
|
4
4
|
|
5
5
|
const proofOffset = 128;
|
6
6
|
const rootOffset = proofOffset + 32;
|
@@ -57,7 +57,7 @@ export class Proof implements IRateLimitProof {
|
|
57
57
|
}
|
58
58
|
|
59
59
|
export function proofToBytes(p: IRateLimitProof): Uint8Array {
|
60
|
-
return concatenate(
|
60
|
+
return BytesUtils.concatenate(
|
61
61
|
p.proof,
|
62
62
|
p.merkleRoot,
|
63
63
|
p.epoch,
|
package/src/utils/bytes.ts
CHANGED
@@ -1,84 +1,130 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
let totalLength = 0;
|
8
|
-
for (const arr of input) {
|
9
|
-
totalLength += arr.length;
|
1
|
+
export class BytesUtils {
|
2
|
+
/**
|
3
|
+
* Switches endianness of a byte array
|
4
|
+
*/
|
5
|
+
public static switchEndianness(bytes: Uint8Array): Uint8Array {
|
6
|
+
return new Uint8Array([...bytes].reverse());
|
10
7
|
}
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
8
|
+
|
9
|
+
/**
|
10
|
+
* Builds a BigInt from a big-endian Uint8Array
|
11
|
+
* @param bytes The big-endian bytes to convert
|
12
|
+
* @returns The resulting BigInt in big-endian format
|
13
|
+
*/
|
14
|
+
public static buildBigIntFromUint8ArrayBE(bytes: Uint8Array): bigint {
|
15
|
+
let result = 0n;
|
16
|
+
for (let i = 0; i < bytes.length; i++) {
|
17
|
+
result = (result << 8n) + BigInt(bytes[i]);
|
18
|
+
}
|
19
|
+
return result;
|
16
20
|
}
|
17
|
-
return result;
|
18
|
-
}
|
19
21
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
}
|
22
|
+
/**
|
23
|
+
* Switches endianness of a bigint value
|
24
|
+
* @param value The bigint value to switch endianness for
|
25
|
+
* @returns The bigint value with reversed endianness
|
26
|
+
*/
|
27
|
+
public static switchEndiannessBigInt(value: bigint): bigint {
|
28
|
+
// Convert bigint to byte array
|
29
|
+
const bytes = [];
|
30
|
+
let tempValue = value;
|
31
|
+
while (tempValue > 0n) {
|
32
|
+
bytes.push(Number(tempValue & 0xffn));
|
33
|
+
tempValue >>= 8n;
|
34
|
+
}
|
33
35
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
byteLength: number,
|
39
|
-
noAssert?: boolean
|
40
|
-
): Uint8Array {
|
41
|
-
value = +value;
|
42
|
-
offset = offset >>> 0;
|
43
|
-
byteLength = byteLength >>> 0;
|
44
|
-
if (!noAssert) {
|
45
|
-
const maxBytes = Math.pow(2, 8 * byteLength) - 1;
|
46
|
-
checkInt(buf, value, offset, byteLength, maxBytes, 0);
|
36
|
+
// Reverse bytes and convert back to bigint
|
37
|
+
return bytes
|
38
|
+
.reverse()
|
39
|
+
.reduce((acc, byte) => (acc << 8n) + BigInt(byte), 0n);
|
47
40
|
}
|
48
41
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
42
|
+
/**
|
43
|
+
* Converts a big-endian bigint to a 32-byte big-endian Uint8Array
|
44
|
+
* @param value The big-endian bigint to convert
|
45
|
+
* @returns A 32-byte big-endian Uint8Array
|
46
|
+
*/
|
47
|
+
public static bigIntToUint8Array32BE(value: bigint): Uint8Array {
|
48
|
+
const bytes = new Uint8Array(32);
|
49
|
+
for (let i = 31; i >= 0; i--) {
|
50
|
+
bytes[i] = Number(value & 0xffn);
|
51
|
+
value >>= 8n;
|
52
|
+
}
|
53
|
+
return bytes;
|
54
54
|
}
|
55
55
|
|
56
|
-
|
57
|
-
|
56
|
+
/**
|
57
|
+
* Writes an unsigned integer to a buffer in little-endian format
|
58
|
+
*/
|
59
|
+
public static writeUIntLE(
|
60
|
+
buf: Uint8Array,
|
61
|
+
value: number,
|
62
|
+
offset: number,
|
63
|
+
byteLength: number,
|
64
|
+
noAssert?: boolean
|
65
|
+
): Uint8Array {
|
66
|
+
value = +value;
|
67
|
+
offset = offset >>> 0;
|
68
|
+
byteLength = byteLength >>> 0;
|
69
|
+
if (!noAssert) {
|
70
|
+
const maxBytes = Math.pow(2, 8 * byteLength) - 1;
|
71
|
+
BytesUtils.checkInt(buf, value, offset, byteLength, maxBytes, 0);
|
72
|
+
}
|
58
73
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
74
|
+
let mul = 1;
|
75
|
+
let i = 0;
|
76
|
+
buf[offset] = value & 0xff;
|
77
|
+
while (++i < byteLength && (mul *= 0x100)) {
|
78
|
+
buf[offset + i] = (value / mul) & 0xff;
|
79
|
+
}
|
80
|
+
|
81
|
+
return buf;
|
82
|
+
}
|
83
|
+
|
84
|
+
/**
|
85
|
+
* Fills with zeros to set length
|
86
|
+
* @param array little endian Uint8Array
|
87
|
+
* @param length amount to pad
|
88
|
+
* @returns little endian Uint8Array padded with zeros to set length
|
89
|
+
*/
|
90
|
+
public static zeroPadLE(array: Uint8Array, length: number): Uint8Array {
|
91
|
+
const result = new Uint8Array(length);
|
92
|
+
for (let i = 0; i < length; i++) {
|
93
|
+
result[i] = array[i] || 0;
|
94
|
+
}
|
95
|
+
return result;
|
96
|
+
}
|
97
|
+
|
98
|
+
// Adapted from https://github.com/feross/buffer
|
99
|
+
public static checkInt(
|
100
|
+
buf: Uint8Array,
|
101
|
+
value: number,
|
102
|
+
offset: number,
|
103
|
+
ext: number,
|
104
|
+
max: number,
|
105
|
+
min: number
|
106
|
+
): void {
|
107
|
+
if (value > max || value < min)
|
108
|
+
throw new RangeError('"value" argument is out of bounds');
|
109
|
+
if (offset + ext > buf.length) throw new RangeError("Index out of range");
|
110
|
+
}
|
71
111
|
|
72
|
-
/**
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
112
|
+
/**
|
113
|
+
* Concatenate Uint8Arrays
|
114
|
+
* @param input
|
115
|
+
* @returns concatenation of all Uint8Array received as input
|
116
|
+
*/
|
117
|
+
public static concatenate(...input: Uint8Array[]): Uint8Array {
|
118
|
+
let totalLength = 0;
|
119
|
+
for (const arr of input) {
|
120
|
+
totalLength += arr.length;
|
121
|
+
}
|
122
|
+
const result = new Uint8Array(totalLength);
|
123
|
+
let offset = 0;
|
124
|
+
for (const arr of input) {
|
125
|
+
result.set(arr, offset);
|
126
|
+
offset += arr.length;
|
127
|
+
}
|
128
|
+
return result;
|
82
129
|
}
|
83
|
-
return result;
|
84
130
|
}
|
package/src/utils/hash.ts
CHANGED
@@ -1,15 +1,25 @@
|
|
1
1
|
import * as zerokitRLN from "@waku/zerokit-rln-wasm";
|
2
2
|
|
3
|
-
import {
|
3
|
+
import { BytesUtils } from "./bytes.js";
|
4
4
|
|
5
5
|
export function poseidonHash(...input: Array<Uint8Array>): Uint8Array {
|
6
|
-
const inputLen = writeUIntLE(
|
7
|
-
|
6
|
+
const inputLen = BytesUtils.writeUIntLE(
|
7
|
+
new Uint8Array(8),
|
8
|
+
input.length,
|
9
|
+
0,
|
10
|
+
8
|
11
|
+
);
|
12
|
+
const lenPrefixedData = BytesUtils.concatenate(inputLen, ...input);
|
8
13
|
return zerokitRLN.poseidonHash(lenPrefixedData);
|
9
14
|
}
|
10
15
|
|
11
16
|
export function sha256(input: Uint8Array): Uint8Array {
|
12
|
-
const inputLen = writeUIntLE(
|
13
|
-
|
17
|
+
const inputLen = BytesUtils.writeUIntLE(
|
18
|
+
new Uint8Array(8),
|
19
|
+
input.length,
|
20
|
+
0,
|
21
|
+
8
|
22
|
+
);
|
23
|
+
const lenPrefixedData = BytesUtils.concatenate(inputLen, input);
|
14
24
|
return zerokitRLN.hash(lenPrefixedData);
|
15
25
|
}
|
package/src/utils/index.ts
CHANGED
@@ -1,9 +1,4 @@
|
|
1
1
|
export { extractMetaMaskSigner } from "./metamask.js";
|
2
|
-
export {
|
3
|
-
concatenate,
|
4
|
-
writeUIntLE,
|
5
|
-
buildBigIntFromUint8Array,
|
6
|
-
zeroPadLE
|
7
|
-
} from "./bytes.js";
|
2
|
+
export { BytesUtils } from "./bytes.js";
|
8
3
|
export { sha256, poseidonHash } from "./hash.js";
|
9
4
|
export { dateToEpoch, epochIntToBytes, epochBytesToInt } from "./epoch.js";
|
package/src/zerokit.ts
CHANGED
@@ -5,12 +5,7 @@ import { DEFAULT_RATE_LIMIT, RATE_LIMIT_PARAMS } from "./contract/constants.js";
|
|
5
5
|
import { IdentityCredential } from "./identity.js";
|
6
6
|
import { Proof, proofToBytes } from "./proof.js";
|
7
7
|
import { WitnessCalculator } from "./resources/witness_calculator";
|
8
|
-
import {
|
9
|
-
concatenate,
|
10
|
-
dateToEpoch,
|
11
|
-
epochIntToBytes,
|
12
|
-
writeUIntLE
|
13
|
-
} from "./utils/index.js";
|
8
|
+
import { BytesUtils, dateToEpoch, epochIntToBytes } from "./utils/index.js";
|
14
9
|
|
15
10
|
export class Zerokit {
|
16
11
|
public constructor(
|
@@ -57,13 +52,16 @@ export class Zerokit {
|
|
57
52
|
): void {
|
58
53
|
// serializes a seq of IDCommitments to a byte seq
|
59
54
|
// the order of serialization is |id_commitment_len<8>|id_commitment<var>|
|
60
|
-
const idCommitmentLen = writeUIntLE(
|
55
|
+
const idCommitmentLen = BytesUtils.writeUIntLE(
|
61
56
|
new Uint8Array(8),
|
62
57
|
idCommitments.length,
|
63
58
|
0,
|
64
59
|
8
|
65
60
|
);
|
66
|
-
const idCommitmentBytes = concatenate(
|
61
|
+
const idCommitmentBytes = BytesUtils.concatenate(
|
62
|
+
idCommitmentLen,
|
63
|
+
...idCommitments
|
64
|
+
);
|
67
65
|
zerokitRLN.setLeavesFrom(this.zkRLN, index, idCommitmentBytes);
|
68
66
|
}
|
69
67
|
|
@@ -83,9 +81,19 @@ export class Zerokit {
|
|
83
81
|
rateLimit?: number
|
84
82
|
): Uint8Array {
|
85
83
|
// calculate message length
|
86
|
-
const msgLen = writeUIntLE(
|
87
|
-
|
88
|
-
|
84
|
+
const msgLen = BytesUtils.writeUIntLE(
|
85
|
+
new Uint8Array(8),
|
86
|
+
uint8Msg.length,
|
87
|
+
0,
|
88
|
+
8
|
89
|
+
);
|
90
|
+
const memIndexBytes = BytesUtils.writeUIntLE(
|
91
|
+
new Uint8Array(8),
|
92
|
+
memIndex,
|
93
|
+
0,
|
94
|
+
8
|
95
|
+
);
|
96
|
+
const rateLimitBytes = BytesUtils.writeUIntLE(
|
89
97
|
new Uint8Array(8),
|
90
98
|
rateLimit ?? this.rateLimit,
|
91
99
|
0,
|
@@ -93,7 +101,7 @@ export class Zerokit {
|
|
93
101
|
);
|
94
102
|
|
95
103
|
// [ id_key<32> | id_index<8> | epoch<32> | signal_len<8> | signal<var> | rate_limit<8> ]
|
96
|
-
return concatenate(
|
104
|
+
return BytesUtils.concatenate(
|
97
105
|
idKey,
|
98
106
|
memIndexBytes,
|
99
107
|
epoch,
|
@@ -169,8 +177,8 @@ export class Zerokit {
|
|
169
177
|
}
|
170
178
|
|
171
179
|
// calculate message length
|
172
|
-
const msgLen = writeUIntLE(new Uint8Array(8), msg.length, 0, 8);
|
173
|
-
const rateLimitBytes = writeUIntLE(
|
180
|
+
const msgLen = BytesUtils.writeUIntLE(new Uint8Array(8), msg.length, 0, 8);
|
181
|
+
const rateLimitBytes = BytesUtils.writeUIntLE(
|
174
182
|
new Uint8Array(8),
|
175
183
|
rateLimit ?? this.rateLimit,
|
176
184
|
0,
|
@@ -179,7 +187,7 @@ export class Zerokit {
|
|
179
187
|
|
180
188
|
return zerokitRLN.verifyRLNProof(
|
181
189
|
this.zkRLN,
|
182
|
-
concatenate(pBytes, msgLen, msg, rateLimitBytes)
|
190
|
+
BytesUtils.concatenate(pBytes, msgLen, msg, rateLimitBytes)
|
183
191
|
);
|
184
192
|
}
|
185
193
|
|
@@ -196,19 +204,19 @@ export class Zerokit {
|
|
196
204
|
pBytes = proofToBytes(proof);
|
197
205
|
}
|
198
206
|
// calculate message length
|
199
|
-
const msgLen = writeUIntLE(new Uint8Array(8), msg.length, 0, 8);
|
200
|
-
const rateLimitBytes = writeUIntLE(
|
207
|
+
const msgLen = BytesUtils.writeUIntLE(new Uint8Array(8), msg.length, 0, 8);
|
208
|
+
const rateLimitBytes = BytesUtils.writeUIntLE(
|
201
209
|
new Uint8Array(8),
|
202
210
|
rateLimit ?? this.rateLimit,
|
203
211
|
0,
|
204
212
|
8
|
205
213
|
);
|
206
214
|
|
207
|
-
const rootsBytes = concatenate(...roots);
|
215
|
+
const rootsBytes = BytesUtils.concatenate(...roots);
|
208
216
|
|
209
217
|
return zerokitRLN.verifyWithRoots(
|
210
218
|
this.zkRLN,
|
211
|
-
concatenate(pBytes, msgLen, msg, rateLimitBytes),
|
219
|
+
BytesUtils.concatenate(pBytes, msgLen, msg, rateLimitBytes),
|
212
220
|
rootsBytes
|
213
221
|
);
|
214
222
|
}
|
@@ -226,8 +234,8 @@ export class Zerokit {
|
|
226
234
|
}
|
227
235
|
|
228
236
|
// calculate message length
|
229
|
-
const msgLen = writeUIntLE(new Uint8Array(8), msg.length, 0, 8);
|
230
|
-
const rateLimitBytes = writeUIntLE(
|
237
|
+
const msgLen = BytesUtils.writeUIntLE(new Uint8Array(8), msg.length, 0, 8);
|
238
|
+
const rateLimitBytes = BytesUtils.writeUIntLE(
|
231
239
|
new Uint8Array(8),
|
232
240
|
rateLimit ?? this.rateLimit,
|
233
241
|
0,
|
@@ -236,7 +244,7 @@ export class Zerokit {
|
|
236
244
|
|
237
245
|
return zerokitRLN.verifyWithRoots(
|
238
246
|
this.zkRLN,
|
239
|
-
concatenate(pBytes, msgLen, msg, rateLimitBytes),
|
247
|
+
BytesUtils.concatenate(pBytes, msgLen, msg, rateLimitBytes),
|
240
248
|
new Uint8Array()
|
241
249
|
);
|
242
250
|
}
|