@waku/rln 0.1.8-e224c05.0 → 0.1.8-e800af3.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/_virtual/utils.js +2 -2
- package/bundle/_virtual/utils2.js +2 -2
- package/bundle/index.js +6 -1
- package/bundle/node_modules/@chainsafe/bls-keystore/node_modules/@noble/hashes/_sha2.js +1 -1
- package/bundle/node_modules/@chainsafe/bls-keystore/node_modules/@noble/hashes/hmac.js +1 -1
- package/bundle/node_modules/@chainsafe/bls-keystore/node_modules/@noble/hashes/pbkdf2.js +1 -1
- package/bundle/node_modules/@chainsafe/bls-keystore/node_modules/@noble/hashes/scrypt.js +1 -1
- package/bundle/node_modules/@chainsafe/bls-keystore/node_modules/@noble/hashes/sha256.js +1 -1
- package/bundle/node_modules/@chainsafe/bls-keystore/node_modules/@noble/hashes/sha512.js +1 -1
- package/bundle/node_modules/@chainsafe/bls-keystore/node_modules/@noble/hashes/utils.js +1 -1
- package/bundle/node_modules/@chainsafe/bls-keystore/node_modules/ethereum-cryptography/random.js +1 -1
- package/bundle/node_modules/@chainsafe/bls-keystore/node_modules/ethereum-cryptography/utils.js +2 -2
- package/bundle/node_modules/@chainsafe/is-ip/lib/is-ip.js +12 -0
- package/bundle/node_modules/@chainsafe/is-ip/lib/parse.js +26 -0
- package/bundle/node_modules/@chainsafe/is-ip/lib/parser.js +202 -0
- package/bundle/node_modules/@multiformats/multiaddr/dist/src/constants.js +43 -0
- package/bundle/node_modules/@multiformats/multiaddr/dist/src/errors.js +17 -0
- package/bundle/node_modules/@multiformats/multiaddr/dist/src/registry.js +245 -0
- package/bundle/node_modules/@multiformats/multiaddr/dist/src/utils.js +191 -0
- package/bundle/node_modules/@multiformats/multiaddr/dist/src/validation.js +30 -0
- package/bundle/node_modules/@noble/hashes/esm/hmac.js +88 -0
- package/bundle/node_modules/@noble/hashes/esm/sha3.js +1 -1
- package/bundle/node_modules/@noble/hashes/esm/utils.js +8 -1
- package/bundle/node_modules/@waku/zerokit-rln-wasm/rln_wasm.js +517 -255
- package/bundle/node_modules/it-length-prefixed/dist/src/decode.js +6 -0
- package/bundle/node_modules/multiformats/dist/src/bases/base10.js +3 -1
- package/bundle/node_modules/multiformats/dist/src/bases/base16.js +4 -2
- package/bundle/node_modules/multiformats/dist/src/bases/base2.js +3 -1
- package/bundle/node_modules/multiformats/dist/src/bases/base256emoji.js +3 -1
- package/bundle/node_modules/multiformats/dist/src/bases/base32.js +11 -9
- package/bundle/node_modules/multiformats/dist/src/bases/base36.js +4 -2
- package/bundle/node_modules/multiformats/dist/src/bases/base58.js +4 -2
- package/bundle/node_modules/multiformats/dist/src/bases/base64.js +6 -4
- package/bundle/node_modules/multiformats/dist/src/bases/base8.js +3 -1
- package/bundle/node_modules/multiformats/dist/src/bases/identity.js +3 -1
- package/bundle/node_modules/multiformats/dist/src/basics.js +15 -0
- package/bundle/node_modules/multiformats/dist/src/bytes.js +15 -1
- package/bundle/node_modules/multiformats/dist/src/cid.js +371 -0
- package/bundle/node_modules/multiformats/dist/src/hashes/digest.js +62 -0
- package/bundle/node_modules/multiformats/dist/src/varint.js +15 -0
- package/bundle/node_modules/multiformats/dist/src/vendor/varint.js +78 -0
- package/bundle/node_modules/protons-runtime/dist/src/codec.js +20 -0
- package/bundle/node_modules/protons-runtime/dist/src/codecs/enum.js +24 -0
- package/bundle/node_modules/protons-runtime/dist/src/codecs/message.js +7 -0
- package/bundle/node_modules/protons-runtime/dist/src/decode.js +8 -0
- package/bundle/node_modules/protons-runtime/dist/src/encode.js +11 -0
- package/bundle/node_modules/protons-runtime/dist/src/index.js +30 -0
- package/bundle/node_modules/protons-runtime/dist/src/utils/float.js +54 -0
- package/bundle/node_modules/protons-runtime/dist/src/utils/longbits.js +175 -0
- package/bundle/node_modules/protons-runtime/dist/src/utils/pool.js +28 -0
- package/bundle/node_modules/protons-runtime/dist/src/utils/reader.js +367 -0
- package/bundle/node_modules/protons-runtime/dist/src/utils/utf8.js +99 -0
- package/bundle/node_modules/protons-runtime/dist/src/utils/writer.js +438 -0
- package/bundle/node_modules/uint8-varint/dist/src/index.js +124 -0
- package/bundle/node_modules/uint8arrays/dist/src/alloc.js +17 -0
- package/bundle/node_modules/uint8arrays/dist/src/concat.js +20 -0
- package/bundle/node_modules/uint8arrays/dist/src/from-string.js +19 -0
- package/bundle/node_modules/uint8arrays/dist/src/to-string.js +19 -0
- package/bundle/node_modules/uint8arrays/dist/src/util/as-uint8array.js +9 -0
- package/bundle/node_modules/uint8arrays/dist/src/util/bases.js +49 -0
- package/bundle/packages/core/dist/lib/connection_manager/connection_limiter.js +18 -0
- package/bundle/packages/core/dist/lib/connection_manager/connection_manager.js +24 -0
- package/bundle/packages/core/dist/lib/connection_manager/dialer.js +14 -0
- package/bundle/packages/core/dist/lib/connection_manager/discovery_dialer.js +14 -0
- package/bundle/packages/core/dist/lib/connection_manager/keep_alive_manager.js +15 -0
- package/bundle/packages/core/dist/lib/connection_manager/shard_reader.js +14 -0
- package/bundle/packages/core/dist/lib/filter/filter.js +28 -0
- package/bundle/packages/core/dist/lib/light_push/light_push.js +28 -0
- package/bundle/packages/core/dist/lib/message/version_0.js +172 -0
- package/bundle/packages/core/dist/lib/metadata/metadata.js +28 -0
- package/bundle/packages/core/dist/lib/store/store.js +24 -0
- package/bundle/packages/interfaces/dist/connection_manager.js +9 -0
- package/bundle/packages/interfaces/dist/health_status.js +17 -0
- package/bundle/packages/interfaces/dist/protocols.js +92 -0
- package/bundle/packages/interfaces/dist/waku.js +7 -0
- package/bundle/packages/proto/dist/generated/filter.js +447 -0
- package/bundle/packages/proto/dist/generated/filter_v2.js +426 -0
- package/bundle/packages/proto/dist/generated/light_push.js +550 -0
- package/bundle/packages/proto/dist/generated/message.js +215 -0
- package/bundle/packages/proto/dist/generated/metadata.js +132 -0
- package/bundle/packages/proto/dist/generated/peer_exchange.js +211 -0
- package/bundle/packages/proto/dist/generated/sds_message.js +172 -0
- package/bundle/packages/proto/dist/generated/store_v3.js +492 -0
- package/bundle/packages/proto/dist/generated/topic_only_message.js +63 -0
- package/bundle/packages/rln/dist/codec.js +92 -0
- package/bundle/packages/rln/dist/contract/constants.js +14 -7
- package/bundle/packages/rln/dist/contract/rln_base_contract.js +2 -1
- package/bundle/packages/rln/dist/contract/rln_contract.js +109 -0
- package/bundle/packages/rln/dist/credentials_manager.js +45 -4
- package/bundle/packages/rln/dist/identity.js +2 -1
- package/bundle/packages/rln/dist/keystore/keystore.js +30 -9
- package/bundle/packages/rln/dist/message.js +59 -0
- package/bundle/packages/rln/dist/proof.js +54 -0
- package/bundle/packages/rln/dist/resources/verification_key.js +112 -0
- package/bundle/packages/rln/dist/resources/witness_calculator.js +1 -1
- package/bundle/packages/rln/dist/rln.js +36 -4
- package/bundle/packages/rln/dist/root_tracker.js +76 -0
- package/bundle/packages/rln/dist/utils/bytes.js +70 -31
- package/bundle/packages/rln/dist/utils/epoch.js +23 -1
- package/bundle/packages/rln/dist/utils/hash.js +10 -0
- package/bundle/packages/rln/dist/zerokit.js +99 -2
- package/bundle/packages/utils/dist/bytes/index.js +31 -0
- package/bundle/resources/rln.wasm +0 -0
- package/bundle/resources/rln_final.zkey +0 -0
- package/bundle/resources/verification_key.d.ts +13 -0
- package/bundle/resources/verification_key.js +112 -0
- package/bundle/resources/witness_calculator.d.ts +7 -21
- package/bundle/resources/witness_calculator.js +1 -1
- package/dist/.tsbuildinfo +1 -1
- package/dist/codec.d.ts +40 -0
- package/dist/codec.js +79 -0
- package/dist/codec.js.map +1 -0
- package/dist/codec.test-utils.d.ts +37 -0
- package/dist/codec.test-utils.js +61 -0
- package/dist/codec.test-utils.js.map +1 -0
- package/dist/contract/constants.d.ts +10 -3
- package/dist/contract/constants.js +13 -6
- package/dist/contract/constants.js.map +1 -1
- package/dist/contract/index.d.ts +1 -0
- package/dist/contract/index.js +1 -0
- package/dist/contract/index.js.map +1 -1
- package/dist/contract/rln_base_contract.js +2 -1
- package/dist/contract/rln_base_contract.js.map +1 -1
- package/dist/contract/rln_contract.d.ts +17 -0
- package/dist/contract/rln_contract.js +107 -0
- package/dist/contract/rln_contract.js.map +1 -0
- package/dist/contract/test_setup.d.ts +26 -0
- package/dist/contract/test_setup.js +56 -0
- package/dist/contract/test_setup.js.map +1 -0
- package/dist/contract/test_utils.d.ts +39 -0
- package/dist/contract/test_utils.js +118 -0
- package/dist/contract/test_utils.js.map +1 -0
- package/dist/credentials_manager.d.ts +14 -2
- package/dist/credentials_manager.js +45 -4
- package/dist/credentials_manager.js.map +1 -1
- package/dist/identity.js +2 -1
- package/dist/identity.js.map +1 -1
- package/dist/index.d.ts +6 -2
- package/dist/index.js +6 -2
- package/dist/index.js.map +1 -1
- package/dist/keystore/keystore.js +30 -9
- package/dist/keystore/keystore.js.map +1 -1
- package/dist/message.d.ts +19 -0
- package/dist/message.js +51 -0
- package/dist/message.js.map +1 -0
- package/dist/proof.d.ts +21 -0
- package/dist/proof.js +50 -0
- package/dist/proof.js.map +1 -0
- package/dist/resources/rln.wasm +0 -0
- package/dist/resources/rln_final.zkey +0 -0
- package/dist/resources/verification_key.d.ts +13 -0
- package/dist/resources/verification_key.js +112 -0
- package/dist/resources/witness_calculator.d.ts +7 -21
- package/dist/resources/witness_calculator.js +1 -1
- package/dist/rln.d.ts +9 -0
- package/dist/rln.js +32 -4
- package/dist/rln.js.map +1 -1
- package/dist/root_tracker.d.ts +10 -0
- package/dist/root_tracker.js +75 -0
- package/dist/root_tracker.js.map +1 -0
- package/dist/utils/bytes.d.ts +31 -9
- package/dist/utils/bytes.js +70 -31
- package/dist/utils/bytes.js.map +1 -1
- package/dist/zerokit.d.ts +11 -0
- package/dist/zerokit.js +97 -1
- package/dist/zerokit.js.map +1 -1
- package/package.json +1 -1
- package/src/codec.test-utils.ts +88 -0
- package/src/codec.ts +138 -0
- package/src/contract/constants.ts +16 -6
- package/src/contract/index.ts +1 -0
- package/src/contract/rln_base_contract.ts +2 -1
- package/src/contract/rln_contract.ts +147 -0
- package/src/contract/test_setup.ts +86 -0
- package/src/contract/test_utils.ts +179 -0
- package/src/credentials_manager.ts +72 -8
- package/src/identity.ts +2 -1
- package/src/index.ts +11 -1
- package/src/keystore/keystore.ts +32 -9
- package/src/message.ts +73 -0
- package/src/proof.ts +69 -0
- package/src/resources/verification_key.d.ts +13 -0
- package/src/resources/witness_calculator.d.ts +7 -21
- package/src/rln.ts +65 -5
- package/src/root_tracker.ts +92 -0
- package/src/utils/bytes.ts +73 -36
- package/src/zerokit.ts +217 -1
package/src/rln.ts
CHANGED
|
@@ -1,14 +1,37 @@
|
|
|
1
|
+
import { createDecoder, createEncoder } from "@waku/core";
|
|
2
|
+
import type {
|
|
3
|
+
ContentTopic,
|
|
4
|
+
IDecodedMessage,
|
|
5
|
+
IRoutingInfo,
|
|
6
|
+
EncoderOptions as WakuEncoderOptions
|
|
7
|
+
} from "@waku/interfaces";
|
|
1
8
|
import { Logger } from "@waku/utils";
|
|
2
|
-
import init
|
|
9
|
+
import init from "@waku/zerokit-rln-wasm";
|
|
10
|
+
import * as zerokitRLN from "@waku/zerokit-rln-wasm";
|
|
3
11
|
|
|
12
|
+
import {
|
|
13
|
+
createRLNDecoder,
|
|
14
|
+
createRLNEncoder,
|
|
15
|
+
type RLNDecoder,
|
|
16
|
+
type RLNEncoder
|
|
17
|
+
} from "./codec.js";
|
|
4
18
|
import { DEFAULT_RATE_LIMIT } from "./contract/constants.js";
|
|
5
19
|
import { RLNCredentialsManager } from "./credentials_manager.js";
|
|
20
|
+
import type {
|
|
21
|
+
DecryptedCredentials,
|
|
22
|
+
EncryptedCredentials
|
|
23
|
+
} from "./keystore/index.js";
|
|
24
|
+
import verificationKey from "./resources/verification_key";
|
|
6
25
|
import * as wc from "./resources/witness_calculator";
|
|
7
26
|
import { WitnessCalculator } from "./resources/witness_calculator";
|
|
8
27
|
import { Zerokit } from "./zerokit.js";
|
|
9
28
|
|
|
10
29
|
const log = new Logger("waku:rln");
|
|
11
30
|
|
|
31
|
+
type WakuRLNEncoderOptions = WakuEncoderOptions & {
|
|
32
|
+
credentials: EncryptedCredentials | DecryptedCredentials;
|
|
33
|
+
};
|
|
34
|
+
|
|
12
35
|
export class RLNInstance extends RLNCredentialsManager {
|
|
13
36
|
/**
|
|
14
37
|
* Create an instance of RLN
|
|
@@ -16,14 +39,18 @@ export class RLNInstance extends RLNCredentialsManager {
|
|
|
16
39
|
*/
|
|
17
40
|
public static async create(): Promise<RLNInstance> {
|
|
18
41
|
try {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
zerokitRLN.
|
|
42
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
43
|
+
await (init as any)?.();
|
|
44
|
+
zerokitRLN.init_panic_hook();
|
|
22
45
|
|
|
23
46
|
const witnessCalculator = await RLNInstance.loadWitnessCalculator();
|
|
24
47
|
const zkey = await RLNInstance.loadZkey();
|
|
25
48
|
|
|
26
|
-
const
|
|
49
|
+
const stringEncoder = new TextEncoder();
|
|
50
|
+
const vkey = stringEncoder.encode(JSON.stringify(verificationKey));
|
|
51
|
+
|
|
52
|
+
const DEPTH = 20;
|
|
53
|
+
const zkRLN = zerokitRLN.newRLN(DEPTH, zkey, vkey);
|
|
27
54
|
const zerokit = new Zerokit(zkRLN, witnessCalculator, DEFAULT_RATE_LIMIT);
|
|
28
55
|
|
|
29
56
|
return new RLNInstance(zerokit);
|
|
@@ -37,6 +64,39 @@ export class RLNInstance extends RLNCredentialsManager {
|
|
|
37
64
|
super(zerokit);
|
|
38
65
|
}
|
|
39
66
|
|
|
67
|
+
public async createEncoder(
|
|
68
|
+
options: WakuRLNEncoderOptions
|
|
69
|
+
): Promise<RLNEncoder> {
|
|
70
|
+
const { credentials: decryptedCredentials } =
|
|
71
|
+
await RLNInstance.decryptCredentialsIfNeeded(options.credentials);
|
|
72
|
+
const credentials = decryptedCredentials || this.credentials;
|
|
73
|
+
|
|
74
|
+
if (!credentials) {
|
|
75
|
+
throw Error(
|
|
76
|
+
"Failed to create Encoder: missing RLN credentials. Use createRLNEncoder directly."
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
await this.verifyCredentialsAgainstContract(credentials);
|
|
81
|
+
|
|
82
|
+
return createRLNEncoder({
|
|
83
|
+
encoder: createEncoder(options),
|
|
84
|
+
rlnInstance: this,
|
|
85
|
+
index: credentials.membership.treeIndex,
|
|
86
|
+
credential: credentials.identity
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
public createDecoder(
|
|
91
|
+
contentTopic: ContentTopic,
|
|
92
|
+
routingInfo: IRoutingInfo
|
|
93
|
+
): RLNDecoder<IDecodedMessage> {
|
|
94
|
+
return createRLNDecoder({
|
|
95
|
+
rlnInstance: this,
|
|
96
|
+
decoder: createDecoder(contentTopic, routingInfo)
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
40
100
|
public static async loadWitnessCalculator(): Promise<WitnessCalculator> {
|
|
41
101
|
try {
|
|
42
102
|
const url = new URL("./resources/rln.wasm", import.meta.url);
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
class RootPerBlock {
|
|
2
|
+
public constructor(
|
|
3
|
+
public root: Uint8Array,
|
|
4
|
+
public blockNumber: number
|
|
5
|
+
) {}
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
const maxBufferSize = 20;
|
|
9
|
+
|
|
10
|
+
export class MerkleRootTracker {
|
|
11
|
+
private validMerkleRoots: Array<RootPerBlock> = new Array<RootPerBlock>();
|
|
12
|
+
private merkleRootBuffer: Array<RootPerBlock> = new Array<RootPerBlock>();
|
|
13
|
+
|
|
14
|
+
public constructor(
|
|
15
|
+
private acceptableRootWindowSize: number,
|
|
16
|
+
initialRoot: Uint8Array
|
|
17
|
+
) {
|
|
18
|
+
this.pushRoot(0, initialRoot);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
public backFill(fromBlockNumber: number): void {
|
|
22
|
+
if (this.validMerkleRoots.length == 0) return;
|
|
23
|
+
|
|
24
|
+
let numBlocks = 0;
|
|
25
|
+
for (let i = this.validMerkleRoots.length - 1; i >= 0; i--) {
|
|
26
|
+
if (this.validMerkleRoots[i].blockNumber >= fromBlockNumber) {
|
|
27
|
+
numBlocks++;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (numBlocks == 0) return;
|
|
32
|
+
|
|
33
|
+
const olderBlock = fromBlockNumber < this.validMerkleRoots[0].blockNumber;
|
|
34
|
+
|
|
35
|
+
// Remove last roots
|
|
36
|
+
let rootsToPop = numBlocks;
|
|
37
|
+
if (this.validMerkleRoots.length < rootsToPop) {
|
|
38
|
+
rootsToPop = this.validMerkleRoots.length;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
this.validMerkleRoots = this.validMerkleRoots.slice(
|
|
42
|
+
0,
|
|
43
|
+
this.validMerkleRoots.length - rootsToPop
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
if (this.merkleRootBuffer.length == 0) return;
|
|
47
|
+
|
|
48
|
+
if (olderBlock) {
|
|
49
|
+
const idx = this.merkleRootBuffer.findIndex(
|
|
50
|
+
(x) => x.blockNumber == fromBlockNumber
|
|
51
|
+
);
|
|
52
|
+
if (idx > -1) {
|
|
53
|
+
this.merkleRootBuffer = this.merkleRootBuffer.slice(0, idx);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Backfill the tree's acceptable roots
|
|
58
|
+
let rootsToRestore =
|
|
59
|
+
this.acceptableRootWindowSize - this.validMerkleRoots.length;
|
|
60
|
+
if (this.merkleRootBuffer.length < rootsToRestore) {
|
|
61
|
+
rootsToRestore = this.merkleRootBuffer.length;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
for (let i = 0; i < rootsToRestore; i++) {
|
|
65
|
+
const x = this.merkleRootBuffer.pop();
|
|
66
|
+
if (x) this.validMerkleRoots.unshift(x);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
public pushRoot(blockNumber: number, root: Uint8Array): void {
|
|
71
|
+
this.validMerkleRoots.push(new RootPerBlock(root, blockNumber));
|
|
72
|
+
|
|
73
|
+
// Maintain valid merkle root window
|
|
74
|
+
if (this.validMerkleRoots.length > this.acceptableRootWindowSize) {
|
|
75
|
+
const x = this.validMerkleRoots.shift();
|
|
76
|
+
if (x) this.merkleRootBuffer.push(x);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Maintain merkle root buffer
|
|
80
|
+
if (this.merkleRootBuffer.length > maxBufferSize) {
|
|
81
|
+
this.merkleRootBuffer.shift();
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
public roots(): Array<Uint8Array> {
|
|
86
|
+
return this.validMerkleRoots.map((x) => x.root);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
public buffer(): Array<Uint8Array> {
|
|
90
|
+
return this.merkleRootBuffer.map((x) => x.root);
|
|
91
|
+
}
|
|
92
|
+
}
|
package/src/utils/bytes.ts
CHANGED
|
@@ -1,52 +1,56 @@
|
|
|
1
1
|
export class BytesUtils {
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
* @param input
|
|
5
|
-
* @returns concatenation of all Uint8Array received as input
|
|
3
|
+
* Switches endianness of a byte array
|
|
6
4
|
*/
|
|
7
|
-
public static
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
5
|
+
public static switchEndianness(bytes: Uint8Array): Uint8Array {
|
|
6
|
+
return new Uint8Array([...bytes].reverse());
|
|
7
|
+
}
|
|
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]);
|
|
17
18
|
}
|
|
18
19
|
return result;
|
|
19
20
|
}
|
|
20
21
|
|
|
21
22
|
/**
|
|
22
|
-
*
|
|
23
|
-
* @param
|
|
24
|
-
* @
|
|
25
|
-
* @returns BigInt representation of the bytes
|
|
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
26
|
*/
|
|
27
|
-
public static
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
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;
|
|
33
34
|
}
|
|
34
35
|
|
|
35
|
-
//
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
workingBytes.reverse();
|
|
41
|
-
}
|
|
36
|
+
// Reverse bytes and convert back to bigint
|
|
37
|
+
return bytes
|
|
38
|
+
.reverse()
|
|
39
|
+
.reduce((acc, byte) => (acc << 8n) + BigInt(byte), 0n);
|
|
40
|
+
}
|
|
42
41
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
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;
|
|
47
52
|
}
|
|
48
|
-
|
|
49
|
-
return result;
|
|
53
|
+
return bytes;
|
|
50
54
|
}
|
|
51
55
|
|
|
52
56
|
/**
|
|
@@ -77,6 +81,20 @@ export class BytesUtils {
|
|
|
77
81
|
return buf;
|
|
78
82
|
}
|
|
79
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
|
+
|
|
80
98
|
// Adapted from https://github.com/feross/buffer
|
|
81
99
|
public static checkInt(
|
|
82
100
|
buf: Uint8Array,
|
|
@@ -90,4 +108,23 @@ export class BytesUtils {
|
|
|
90
108
|
throw new RangeError('"value" argument is out of bounds');
|
|
91
109
|
if (offset + ext > buf.length) throw new RangeError("Index out of range");
|
|
92
110
|
}
|
|
111
|
+
|
|
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;
|
|
129
|
+
}
|
|
93
130
|
}
|
package/src/zerokit.ts
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
|
+
import type { IRateLimitProof } from "@waku/interfaces";
|
|
1
2
|
import * as zerokitRLN from "@waku/zerokit-rln-wasm";
|
|
2
3
|
|
|
3
|
-
import { DEFAULT_RATE_LIMIT } from "./contract/constants.js";
|
|
4
|
+
import { DEFAULT_RATE_LIMIT, RATE_LIMIT_PARAMS } from "./contract/constants.js";
|
|
4
5
|
import { IdentityCredential } from "./identity.js";
|
|
6
|
+
import { Proof, proofToBytes } from "./proof.js";
|
|
5
7
|
import { WitnessCalculator } from "./resources/witness_calculator";
|
|
8
|
+
import { BytesUtils, dateToEpoch, epochIntToBytes } from "./utils/index.js";
|
|
6
9
|
|
|
7
10
|
export class Zerokit {
|
|
8
11
|
public constructor(
|
|
@@ -23,13 +26,226 @@ export class Zerokit {
|
|
|
23
26
|
return this._rateLimit;
|
|
24
27
|
}
|
|
25
28
|
|
|
29
|
+
public generateIdentityCredentials(): IdentityCredential {
|
|
30
|
+
const memKeys = zerokitRLN.generateExtendedMembershipKey(this.zkRLN); // TODO: rename this function in zerokit rln-wasm
|
|
31
|
+
return IdentityCredential.fromBytes(memKeys);
|
|
32
|
+
}
|
|
33
|
+
|
|
26
34
|
public generateSeededIdentityCredential(seed: string): IdentityCredential {
|
|
27
35
|
const stringEncoder = new TextEncoder();
|
|
28
36
|
const seedBytes = stringEncoder.encode(seed);
|
|
37
|
+
// TODO: rename this function in zerokit rln-wasm
|
|
29
38
|
const memKeys = zerokitRLN.generateSeededExtendedMembershipKey(
|
|
30
39
|
this.zkRLN,
|
|
31
40
|
seedBytes
|
|
32
41
|
);
|
|
33
42
|
return IdentityCredential.fromBytes(memKeys);
|
|
34
43
|
}
|
|
44
|
+
|
|
45
|
+
public insertMember(idCommitment: Uint8Array): void {
|
|
46
|
+
zerokitRLN.insertMember(this.zkRLN, idCommitment);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
public insertMembers(
|
|
50
|
+
index: number,
|
|
51
|
+
...idCommitments: Array<Uint8Array>
|
|
52
|
+
): void {
|
|
53
|
+
// serializes a seq of IDCommitments to a byte seq
|
|
54
|
+
// the order of serialization is |id_commitment_len<8>|id_commitment<var>|
|
|
55
|
+
const idCommitmentLen = BytesUtils.writeUIntLE(
|
|
56
|
+
new Uint8Array(8),
|
|
57
|
+
idCommitments.length,
|
|
58
|
+
0,
|
|
59
|
+
8
|
|
60
|
+
);
|
|
61
|
+
const idCommitmentBytes = BytesUtils.concatenate(
|
|
62
|
+
idCommitmentLen,
|
|
63
|
+
...idCommitments
|
|
64
|
+
);
|
|
65
|
+
zerokitRLN.setLeavesFrom(this.zkRLN, index, idCommitmentBytes);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
public deleteMember(index: number): void {
|
|
69
|
+
zerokitRLN.deleteLeaf(this.zkRLN, index);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
public getMerkleRoot(): Uint8Array {
|
|
73
|
+
return zerokitRLN.getRoot(this.zkRLN);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
public serializeMessage(
|
|
77
|
+
uint8Msg: Uint8Array,
|
|
78
|
+
memIndex: number,
|
|
79
|
+
epoch: Uint8Array,
|
|
80
|
+
idKey: Uint8Array,
|
|
81
|
+
rateLimit?: number
|
|
82
|
+
): Uint8Array {
|
|
83
|
+
// calculate message length
|
|
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(
|
|
97
|
+
new Uint8Array(8),
|
|
98
|
+
rateLimit ?? this.rateLimit,
|
|
99
|
+
0,
|
|
100
|
+
8
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
// [ id_key<32> | id_index<8> | epoch<32> | signal_len<8> | signal<var> | rate_limit<8> ]
|
|
104
|
+
return BytesUtils.concatenate(
|
|
105
|
+
idKey,
|
|
106
|
+
memIndexBytes,
|
|
107
|
+
epoch,
|
|
108
|
+
msgLen,
|
|
109
|
+
uint8Msg,
|
|
110
|
+
rateLimitBytes
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
public async generateRLNProof(
|
|
115
|
+
msg: Uint8Array,
|
|
116
|
+
index: number,
|
|
117
|
+
epoch: Uint8Array | Date | undefined,
|
|
118
|
+
idSecretHash: Uint8Array,
|
|
119
|
+
rateLimit?: number
|
|
120
|
+
): Promise<IRateLimitProof> {
|
|
121
|
+
if (epoch === undefined) {
|
|
122
|
+
epoch = epochIntToBytes(dateToEpoch(new Date()));
|
|
123
|
+
} else if (epoch instanceof Date) {
|
|
124
|
+
epoch = epochIntToBytes(dateToEpoch(epoch));
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const effectiveRateLimit = rateLimit ?? this.rateLimit;
|
|
128
|
+
|
|
129
|
+
if (epoch.length !== 32) throw new Error("invalid epoch");
|
|
130
|
+
if (idSecretHash.length !== 32) throw new Error("invalid id secret hash");
|
|
131
|
+
if (index < 0) throw new Error("index must be >= 0");
|
|
132
|
+
if (
|
|
133
|
+
effectiveRateLimit < RATE_LIMIT_PARAMS.MIN_RATE ||
|
|
134
|
+
effectiveRateLimit > RATE_LIMIT_PARAMS.MAX_RATE
|
|
135
|
+
) {
|
|
136
|
+
throw new Error(
|
|
137
|
+
`Rate limit must be between ${RATE_LIMIT_PARAMS.MIN_RATE} and ${RATE_LIMIT_PARAMS.MAX_RATE}`
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const serialized_msg = this.serializeMessage(
|
|
142
|
+
msg,
|
|
143
|
+
index,
|
|
144
|
+
epoch,
|
|
145
|
+
idSecretHash,
|
|
146
|
+
effectiveRateLimit
|
|
147
|
+
);
|
|
148
|
+
const rlnWitness = zerokitRLN.getSerializedRLNWitness(
|
|
149
|
+
this.zkRLN,
|
|
150
|
+
serialized_msg
|
|
151
|
+
);
|
|
152
|
+
const inputs = zerokitRLN.RLNWitnessToJson(this.zkRLN, rlnWitness);
|
|
153
|
+
const calculatedWitness = await this.witnessCalculator.calculateWitness(
|
|
154
|
+
inputs,
|
|
155
|
+
false
|
|
156
|
+
);
|
|
157
|
+
|
|
158
|
+
const proofBytes = zerokitRLN.generate_rln_proof_with_witness(
|
|
159
|
+
this.zkRLN,
|
|
160
|
+
calculatedWitness,
|
|
161
|
+
rlnWitness
|
|
162
|
+
);
|
|
163
|
+
|
|
164
|
+
return new Proof(proofBytes);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
public verifyRLNProof(
|
|
168
|
+
proof: IRateLimitProof | Uint8Array,
|
|
169
|
+
msg: Uint8Array,
|
|
170
|
+
rateLimit?: number
|
|
171
|
+
): boolean {
|
|
172
|
+
let pBytes: Uint8Array;
|
|
173
|
+
if (proof instanceof Uint8Array) {
|
|
174
|
+
pBytes = proof;
|
|
175
|
+
} else {
|
|
176
|
+
pBytes = proofToBytes(proof);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// calculate message length
|
|
180
|
+
const msgLen = BytesUtils.writeUIntLE(new Uint8Array(8), msg.length, 0, 8);
|
|
181
|
+
const rateLimitBytes = BytesUtils.writeUIntLE(
|
|
182
|
+
new Uint8Array(8),
|
|
183
|
+
rateLimit ?? this.rateLimit,
|
|
184
|
+
0,
|
|
185
|
+
8
|
|
186
|
+
);
|
|
187
|
+
|
|
188
|
+
return zerokitRLN.verifyRLNProof(
|
|
189
|
+
this.zkRLN,
|
|
190
|
+
BytesUtils.concatenate(pBytes, msgLen, msg, rateLimitBytes)
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
public verifyWithRoots(
|
|
195
|
+
proof: IRateLimitProof | Uint8Array,
|
|
196
|
+
msg: Uint8Array,
|
|
197
|
+
roots: Array<Uint8Array>,
|
|
198
|
+
rateLimit?: number
|
|
199
|
+
): boolean {
|
|
200
|
+
let pBytes: Uint8Array;
|
|
201
|
+
if (proof instanceof Uint8Array) {
|
|
202
|
+
pBytes = proof;
|
|
203
|
+
} else {
|
|
204
|
+
pBytes = proofToBytes(proof);
|
|
205
|
+
}
|
|
206
|
+
// calculate message length
|
|
207
|
+
const msgLen = BytesUtils.writeUIntLE(new Uint8Array(8), msg.length, 0, 8);
|
|
208
|
+
const rateLimitBytes = BytesUtils.writeUIntLE(
|
|
209
|
+
new Uint8Array(8),
|
|
210
|
+
rateLimit ?? this.rateLimit,
|
|
211
|
+
0,
|
|
212
|
+
8
|
|
213
|
+
);
|
|
214
|
+
|
|
215
|
+
const rootsBytes = BytesUtils.concatenate(...roots);
|
|
216
|
+
|
|
217
|
+
return zerokitRLN.verifyWithRoots(
|
|
218
|
+
this.zkRLN,
|
|
219
|
+
BytesUtils.concatenate(pBytes, msgLen, msg, rateLimitBytes),
|
|
220
|
+
rootsBytes
|
|
221
|
+
);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
public verifyWithNoRoot(
|
|
225
|
+
proof: IRateLimitProof | Uint8Array,
|
|
226
|
+
msg: Uint8Array,
|
|
227
|
+
rateLimit?: number
|
|
228
|
+
): boolean {
|
|
229
|
+
let pBytes: Uint8Array;
|
|
230
|
+
if (proof instanceof Uint8Array) {
|
|
231
|
+
pBytes = proof;
|
|
232
|
+
} else {
|
|
233
|
+
pBytes = proofToBytes(proof);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// calculate message length
|
|
237
|
+
const msgLen = BytesUtils.writeUIntLE(new Uint8Array(8), msg.length, 0, 8);
|
|
238
|
+
const rateLimitBytes = BytesUtils.writeUIntLE(
|
|
239
|
+
new Uint8Array(8),
|
|
240
|
+
rateLimit ?? this.rateLimit,
|
|
241
|
+
0,
|
|
242
|
+
8
|
|
243
|
+
);
|
|
244
|
+
|
|
245
|
+
return zerokitRLN.verifyWithRoots(
|
|
246
|
+
this.zkRLN,
|
|
247
|
+
BytesUtils.concatenate(pBytes, msgLen, msg, rateLimitBytes),
|
|
248
|
+
new Uint8Array()
|
|
249
|
+
);
|
|
250
|
+
}
|
|
35
251
|
}
|