@waku/rln 0.1.6-f7c290d.0 → 0.1.6
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/CHANGELOG.md +29 -0
- package/bundle/_virtual/utils.js +2 -2
- package/bundle/_virtual/utils2.js +2 -2
- package/bundle/index.js +1 -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/@ethersproject/bignumber/lib.esm/bignumber.js +1 -1
- 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/debug/src/browser.js +1 -1
- package/bundle/node_modules/debug/src/common.js +1 -1
- package/bundle/node_modules/lodash/lodash.js +5 -5
- package/bundle/node_modules/multiformats/dist/src/bases/base.js +12 -9
- package/bundle/node_modules/multiformats/dist/src/bytes.js +19 -3
- 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/uint8arrays/dist/src/concat.js +20 -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/packages/core/dist/lib/connection_manager/connection_manager.js +1 -3
- package/bundle/packages/proto/dist/generated/filter.js +2 -0
- package/bundle/packages/proto/dist/generated/filter_v2.js +2 -0
- package/bundle/packages/proto/dist/generated/light_push.js +2 -0
- package/bundle/packages/proto/dist/generated/message.js +2 -0
- package/bundle/packages/proto/dist/generated/metadata.js +2 -0
- package/bundle/packages/proto/dist/generated/peer_exchange.js +2 -0
- package/bundle/packages/proto/dist/generated/sds_message.js +2 -0
- package/bundle/packages/proto/dist/generated/store_v3.js +2 -0
- package/bundle/packages/proto/dist/generated/topic_only_message.js +2 -0
- package/bundle/packages/rln/dist/contract/constants.js +1 -7
- package/bundle/packages/rln/dist/contract/rln_base_contract.js +2 -5
- package/bundle/packages/rln/dist/contract/rln_contract.js +2 -2
- package/bundle/packages/rln/dist/credentials_manager.js +16 -24
- package/bundle/packages/rln/dist/identity.js +6 -8
- package/bundle/packages/rln/dist/keystore/keystore.js +10 -21
- package/bundle/packages/rln/dist/proof.js +2 -2
- package/bundle/packages/rln/dist/utils/bytes.js +58 -103
- 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/codec.test-utils.d.ts +1 -1
- package/dist/contract/constants.d.ts +0 -6
- package/dist/contract/constants.js +0 -6
- package/dist/contract/constants.js.map +1 -1
- package/dist/contract/rln_base_contract.js +2 -5
- 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 +1 -1
- 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 +0 -4
- package/dist/credentials_manager.js +16 -25
- package/dist/credentials_manager.js.map +1 -1
- package/dist/identity.d.ts +2 -5
- package/dist/identity.js +5 -8
- package/dist/identity.js.map +1 -1
- package/dist/keystore/credential_validation_generated.d.ts +0 -2
- package/dist/keystore/keystore.js +10 -21
- package/dist/keystore/keystore.js.map +1 -1
- package/dist/keystore/keystore_validation_generated.d.ts +0 -2
- package/dist/proof.js +2 -2
- package/dist/proof.js.map +1 -1
- package/dist/utils/bytes.d.ts +20 -42
- package/dist/utils/bytes.js +57 -102
- 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 +93 -1
- package/src/contract/constants.ts +0 -9
- package/src/contract/rln_base_contract.ts +3 -5
- package/src/contract/rln_contract.ts +2 -5
- package/src/contract/test-utils.ts +179 -0
- package/src/credentials_manager.ts +24 -46
- package/src/identity.ts +7 -11
- package/src/keystore/keystore.ts +22 -38
- package/src/proof.ts +2 -2
- package/src/utils/bytes.ts +72 -118
- package/src/utils/hash.ts +5 -15
- package/src/utils/index.ts +6 -1
- package/src/zerokit.ts +22 -30
- package/bundle/node_modules/@multiformats/multiaddr/dist/src/convert.js +0 -15
- package/bundle/node_modules/@multiformats/multiaddr/dist/src/multiaddr.js +0 -21
- package/bundle/node_modules/@multiformats/multiaddr/dist/src/protocols-table.js +0 -92
@@ -22,12 +22,6 @@ const RATE_LIMIT_PARAMS = {
|
|
22
22
|
MAX_TOTAL_RATE: 160_000, // Maximum total rate limit across all memberships
|
23
23
|
EPOCH_LENGTH: 600 // Epoch length in seconds (10 minutes)
|
24
24
|
};
|
25
|
-
/**
|
26
|
-
* Default Q value for the RLN contract
|
27
|
-
* This is the upper bound for the ID commitment
|
28
|
-
* @see https://github.com/waku-org/specs/blob/master/standards/core/rln-contract.md#implementation-suggestions
|
29
|
-
*/
|
30
|
-
const DEFAULT_Q = BigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
|
31
25
|
const DEFAULT_RATE_LIMIT = RATE_LIMIT_PARAMS.MAX_RATE;
|
32
26
|
|
33
|
-
export {
|
27
|
+
export { DEFAULT_RATE_LIMIT, LINEA_CONTRACT, RATE_LIMIT_PARAMS, RATE_LIMIT_TIERS };
|
@@ -13,7 +13,6 @@ 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 { BytesUtils } from '../utils/bytes.js';
|
17
16
|
import { RLN_ABI } from './abi.js';
|
18
17
|
import { DEFAULT_RATE_LIMIT, RATE_LIMIT_PARAMS } from './constants.js';
|
19
18
|
import { MembershipState } from './types.js';
|
@@ -353,9 +352,7 @@ class RLNBaseContract {
|
|
353
352
|
}
|
354
353
|
const estimatedGas = await this.contract.estimateGas.register(identity.IDCommitmentBigInt, this.rateLimit, []);
|
355
354
|
const gasLimit = estimatedGas.add(10000);
|
356
|
-
const txRegisterResponse = await this.contract.register(identity.IDCommitmentBigInt, this.rateLimit, [], {
|
357
|
-
gasLimit
|
358
|
-
});
|
355
|
+
const txRegisterResponse = await this.contract.register(identity.IDCommitmentBigInt, this.rateLimit, [], { gasLimit });
|
359
356
|
const txRegisterReceipt = await txRegisterResponse.wait();
|
360
357
|
if (txRegisterReceipt.status === 0) {
|
361
358
|
throw new Error("Transaction failed on-chain");
|
@@ -417,7 +414,7 @@ class RLNBaseContract {
|
|
417
414
|
async registerWithPermitAndErase(identity, permit, idCommitmentsToErase) {
|
418
415
|
try {
|
419
416
|
log.info(`Registering identity with permit and rate limit: ${this.rateLimit} messages/epoch`);
|
420
|
-
const txRegisterResponse = await this.contract.registerWithPermit(permit.owner, permit.deadline, permit.v, permit.r, permit.s,
|
417
|
+
const txRegisterResponse = await this.contract.registerWithPermit(permit.owner, permit.deadline, permit.v, permit.r, permit.s, identity.IDCommitmentBigInt, this.rateLimit, idCommitmentsToErase.map((id) => BigNumber.from(id)));
|
421
418
|
const txRegisterReceipt = await txRegisterResponse.wait();
|
422
419
|
const memberRegistered = txRegisterReceipt.events?.find((event) => event.event === "MembershipRegistered");
|
423
420
|
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 { zeroPadLE } 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 =
|
86
|
+
const idCommitment = zeroPadLE(hexToBytes(_idCommitment), 32);
|
87
87
|
rlnInstance.zerokit.insertMember(idCommitment);
|
88
88
|
const numericIndex = index.toNumber();
|
89
89
|
this._members.set(numericIndex, {
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import { hmac } from '../../../node_modules/@noble/hashes/esm/hmac.js';
|
2
|
-
import { sha256 } from '../../../node_modules/@noble/hashes/esm/
|
2
|
+
import { sha256 } from '../../../node_modules/@noble/hashes/esm/sha256.js';
|
3
3
|
import '../../interfaces/dist/protocols.js';
|
4
4
|
import '../../interfaces/dist/connection_manager.js';
|
5
5
|
import '../../interfaces/dist/health_indicator.js';
|
@@ -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
|
18
|
+
import { LINEA_CONTRACT } 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';
|
23
22
|
import { extractMetaMaskSigner } from './utils/metamask.js';
|
23
|
+
import { buildBigIntFromUint8Array } from './utils/bytes.js';
|
24
24
|
import './utils/epoch.js';
|
25
25
|
|
26
26
|
const log = new Logger("waku:credentials");
|
@@ -95,7 +95,7 @@ class RLNCredentialsManager {
|
|
95
95
|
}
|
96
96
|
else {
|
97
97
|
log.info("Using local implementation to generate identity");
|
98
|
-
identity =
|
98
|
+
identity = this.generateSeededIdentityCredential(options.signature);
|
99
99
|
}
|
100
100
|
}
|
101
101
|
if (!identity) {
|
@@ -191,32 +191,24 @@ class RLNCredentialsManager {
|
|
191
191
|
* @param seed A string seed to generate the identity from
|
192
192
|
* @returns IdentityCredential
|
193
193
|
*/
|
194
|
-
|
194
|
+
generateSeededIdentityCredential(seed) {
|
195
195
|
log.info("Generating seeded identity credential");
|
196
196
|
// Convert the seed to bytes
|
197
197
|
const encoder = new TextEncoder();
|
198
198
|
const seedBytes = encoder.encode(seed);
|
199
199
|
// Generate deterministic values using HMAC-SHA256
|
200
200
|
// We use different context strings for each component to ensure they're different
|
201
|
-
const
|
202
|
-
const
|
203
|
-
|
204
|
-
const
|
205
|
-
const
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
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;
|
201
|
+
const idTrapdoor = hmac(sha256, seedBytes, encoder.encode("IDTrapdoor"));
|
202
|
+
const idNullifier = hmac(sha256, seedBytes, encoder.encode("IDNullifier"));
|
203
|
+
// Generate IDSecretHash as a hash of IDTrapdoor and IDNullifier
|
204
|
+
const combinedBytes = new Uint8Array([...idTrapdoor, ...idNullifier]);
|
205
|
+
const idSecretHash = sha256(combinedBytes);
|
206
|
+
// Generate IDCommitment as a hash of IDSecretHash
|
207
|
+
const idCommitment = sha256(idSecretHash);
|
208
|
+
// Convert IDCommitment to BigInt
|
209
|
+
const idCommitmentBigInt = buildBigIntFromUint8Array(idCommitment);
|
210
|
+
log.info("Successfully generated identity credential");
|
211
|
+
return new IdentityCredential(idTrapdoor, idNullifier, idSecretHash, idCommitment, idCommitmentBigInt);
|
220
212
|
}
|
221
213
|
}
|
222
214
|
|
@@ -1,4 +1,5 @@
|
|
1
|
-
import {
|
1
|
+
import { buildBigIntFromUint8Array } from './utils/bytes.js';
|
2
|
+
import './utils/epoch.js';
|
2
3
|
|
3
4
|
class IdentityCredential {
|
4
5
|
IDTrapdoor;
|
@@ -6,16 +7,12 @@ class IdentityCredential {
|
|
6
7
|
IDSecretHash;
|
7
8
|
IDCommitment;
|
8
9
|
IDCommitmentBigInt;
|
9
|
-
|
10
|
-
* All variables are in little-endian format
|
11
|
-
*/
|
12
|
-
constructor(IDTrapdoor, IDNullifier, IDSecretHash, IDCommitment) {
|
10
|
+
constructor(IDTrapdoor, IDNullifier, IDSecretHash, IDCommitment, IDCommitmentBigInt) {
|
13
11
|
this.IDTrapdoor = IDTrapdoor;
|
14
12
|
this.IDNullifier = IDNullifier;
|
15
13
|
this.IDSecretHash = IDSecretHash;
|
16
14
|
this.IDCommitment = IDCommitment;
|
17
|
-
this.IDCommitmentBigInt =
|
18
|
-
BytesUtils.buildBigIntFromUint8ArrayBE(IDCommitment);
|
15
|
+
this.IDCommitmentBigInt = IDCommitmentBigInt;
|
19
16
|
}
|
20
17
|
static fromBytes(memKeys) {
|
21
18
|
if (memKeys.length < 128) {
|
@@ -25,7 +22,8 @@ class IdentityCredential {
|
|
25
22
|
const idNullifier = memKeys.subarray(32, 64);
|
26
23
|
const idSecretHash = memKeys.subarray(64, 96);
|
27
24
|
const idCommitment = memKeys.subarray(96, 128);
|
28
|
-
|
25
|
+
const idCommitmentBigInt = buildBigIntFromUint8Array(idCommitment, 32);
|
26
|
+
return new IdentityCredential(idTrapdoor, idNullifier, idSecretHash, idCommitment, idCommitmentBigInt);
|
29
27
|
}
|
30
28
|
}
|
31
29
|
|
@@ -17,7 +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 {
|
20
|
+
import { buildBigIntFromUint8Array } from '../utils/bytes.js';
|
21
21
|
import { keccak256Checksum, decryptEipKeystore } from './cipher.js';
|
22
22
|
import { isKeystoreValid, isCredentialValid } from './schema_validator.js';
|
23
23
|
import { __exports as lib } from '../../../../_virtual/index.js';
|
@@ -164,24 +164,14 @@ class Keystore {
|
|
164
164
|
try {
|
165
165
|
const str = bytesToUtf8(bytes);
|
166
166
|
const obj = JSON.parse(str);
|
167
|
-
//
|
168
|
-
const idCommitmentLE = Keystore.fromArraylikeToBytes(_.get(obj, "identityCredential.idCommitment", []));
|
169
|
-
const idTrapdoorLE = Keystore.fromArraylikeToBytes(_.get(obj, "identityCredential.idTrapdoor", []));
|
170
|
-
const idNullifierLE = Keystore.fromArraylikeToBytes(_.get(obj, "identityCredential.idNullifier", []));
|
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);
|
167
|
+
// TODO: add runtime validation of nwaku credentials
|
178
168
|
return {
|
179
169
|
identity: {
|
180
|
-
IDCommitment:
|
181
|
-
IDTrapdoor:
|
182
|
-
IDNullifier:
|
183
|
-
|
184
|
-
|
170
|
+
IDCommitment: Keystore.fromArraylikeToBytes(_.get(obj, "identityCredential.idCommitment", [])),
|
171
|
+
IDTrapdoor: Keystore.fromArraylikeToBytes(_.get(obj, "identityCredential.idTrapdoor", [])),
|
172
|
+
IDNullifier: Keystore.fromArraylikeToBytes(_.get(obj, "identityCredential.idNullifier", [])),
|
173
|
+
IDCommitmentBigInt: buildBigIntFromUint8Array(Keystore.fromArraylikeToBytes(_.get(obj, "identityCredential.idCommitment", []))),
|
174
|
+
IDSecretHash: Keystore.fromArraylikeToBytes(_.get(obj, "identityCredential.idSecretHash", []))
|
185
175
|
},
|
186
176
|
membership: {
|
187
177
|
treeIndex: _.get(obj, "treeIndex"),
|
@@ -217,14 +207,13 @@ class Keystore {
|
|
217
207
|
}
|
218
208
|
// follows nwaku implementation
|
219
209
|
// 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
|
221
210
|
static fromIdentityToBytes(options) {
|
222
211
|
return utf8ToBytes(JSON.stringify({
|
223
212
|
treeIndex: options.membership.treeIndex,
|
224
213
|
identityCredential: {
|
225
|
-
idCommitment: Array.from(
|
226
|
-
idNullifier: Array.from(
|
227
|
-
idSecretHash: Array.from(
|
214
|
+
idCommitment: Array.from(options.identity.IDCommitment),
|
215
|
+
idNullifier: Array.from(options.identity.IDNullifier),
|
216
|
+
idSecretHash: Array.from(options.identity.IDSecretHash),
|
228
217
|
idTrapdoor: Array.from(options.identity.IDTrapdoor)
|
229
218
|
},
|
230
219
|
membershipContract: {
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import {
|
1
|
+
import { concatenate } 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
|
51
|
+
return 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,110 +1,65 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
1
|
+
/**
|
2
|
+
* Concatenate Uint8Arrays
|
3
|
+
* @param input
|
4
|
+
* @returns concatenation of all Uint8Array received as input
|
5
|
+
*/
|
6
|
+
function concatenate(...input) {
|
7
|
+
let totalLength = 0;
|
8
|
+
for (const arr of input) {
|
9
|
+
totalLength += arr.length;
|
7
10
|
}
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
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;
|
11
|
+
const result = new Uint8Array(totalLength);
|
12
|
+
let offset = 0;
|
13
|
+
for (const arr of input) {
|
14
|
+
result.set(arr, offset);
|
15
|
+
offset += arr.length;
|
19
16
|
}
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
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;
|
17
|
+
return result;
|
18
|
+
}
|
19
|
+
// Adapted from https://github.com/feross/buffer
|
20
|
+
function checkInt(buf, value, offset, ext, max, min) {
|
21
|
+
if (value > max || value < min)
|
22
|
+
throw new RangeError('"value" argument is out of bounds');
|
23
|
+
if (offset + ext > buf.length)
|
24
|
+
throw new RangeError("Index out of range");
|
25
|
+
}
|
26
|
+
function writeUIntLE(buf, value, offset, byteLength, noAssert) {
|
27
|
+
value = +value;
|
28
|
+
offset = offset >>> 0;
|
29
|
+
byteLength = byteLength >>> 0;
|
30
|
+
{
|
31
|
+
const maxBytes = Math.pow(2, 8 * byteLength) - 1;
|
32
|
+
checkInt(buf, value, offset, byteLength, maxBytes, 0);
|
82
33
|
}
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
throw new RangeError("Index out of range");
|
34
|
+
let mul = 1;
|
35
|
+
let i = 0;
|
36
|
+
buf[offset] = value & 0xff;
|
37
|
+
while (++i < byteLength && (mul *= 0x100)) {
|
38
|
+
buf[offset + i] = (value / mul) & 0xff;
|
89
39
|
}
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
40
|
+
return buf;
|
41
|
+
}
|
42
|
+
/**
|
43
|
+
* Transforms Uint8Array into BigInt
|
44
|
+
* @param array: Uint8Array
|
45
|
+
* @returns BigInt
|
46
|
+
*/
|
47
|
+
function buildBigIntFromUint8Array(array, byteOffset = 0) {
|
48
|
+
const dataView = new DataView(array.buffer);
|
49
|
+
return dataView.getBigUint64(byteOffset, true);
|
50
|
+
}
|
51
|
+
/**
|
52
|
+
* Fills with zeros to set length
|
53
|
+
* @param array little endian Uint8Array
|
54
|
+
* @param length amount to pad
|
55
|
+
* @returns little endian Uint8Array padded with zeros to set length
|
56
|
+
*/
|
57
|
+
function zeroPadLE(array, length) {
|
58
|
+
const result = new Uint8Array(length);
|
59
|
+
for (let i = 0; i < length; i++) {
|
60
|
+
result[i] = array[i] || 0;
|
107
61
|
}
|
62
|
+
return result;
|
108
63
|
}
|
109
64
|
|
110
|
-
export {
|
65
|
+
export { buildBigIntFromUint8Array, concatenate, writeUIntLE, zeroPadLE };
|
@@ -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 { writeUIntLE, concatenate } from './bytes.js';
|
3
3
|
|
4
4
|
function poseidonHash(...input) {
|
5
|
-
const inputLen =
|
6
|
-
const lenPrefixedData =
|
5
|
+
const inputLen = writeUIntLE(new Uint8Array(8), input.length, 0, 8);
|
6
|
+
const lenPrefixedData = 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 { writeUIntLE, concatenate } 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 =
|
44
|
-
const idCommitmentBytes =
|
43
|
+
const idCommitmentLen = writeUIntLE(new Uint8Array(8), idCommitments.length, 0, 8);
|
44
|
+
const idCommitmentBytes = 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 =
|
56
|
-
const memIndexBytes =
|
57
|
-
const rateLimitBytes =
|
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);
|
58
58
|
// [ id_key<32> | id_index<8> | epoch<32> | signal_len<8> | signal<var> | rate_limit<8> ]
|
59
|
-
return
|
59
|
+
return 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 =
|
96
|
-
const rateLimitBytes =
|
97
|
-
return verifyRLNProof(this.zkRLN,
|
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));
|
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 =
|
109
|
-
const rateLimitBytes =
|
110
|
-
const rootsBytes =
|
111
|
-
return verifyWithRoots(this.zkRLN,
|
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);
|
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 =
|
123
|
-
const rateLimitBytes =
|
124
|
-
return verifyWithRoots(this.zkRLN,
|
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());
|
125
125
|
}
|
126
126
|
}
|
127
127
|
|