Merge pull request #41 from waku-org/danisharora/seeded-membershipkey-generation

This commit is contained in:
Danish Arora 2022-12-09 08:49:05 +05:30 committed by GitHub
commit f312f3d0e9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 122 additions and 24 deletions

View File

@ -4,6 +4,7 @@ Browser library providing the cryptographic functions for Waku RLN Relay
https://rfc.vac.dev/spec/17/ https://rfc.vac.dev/spec/17/
### Install ### Install
``` ```
npm install @waku/rln npm install @waku/rln
@ -13,6 +14,7 @@ yarn add @waku/rln
``` ```
### Running example app ### Running example app
``` ```
git clone https://github.com/waku-org/js-rln git clone https://github.com/waku-org/js-rln
@ -26,10 +28,10 @@ npm start
Browse http://localhost:8080 and open the dev tools console to see the proof being generated and its verification Browse http://localhost:8080 and open the dev tools console to see the proof being generated and its verification
### Usage ### Usage
#### Initializing the library #### Initializing the library
```js ```js
import * as rln from "@waku/rln"; import * as rln from "@waku/rln";
@ -37,45 +39,60 @@ const rlnInstance = wait rln.create();
``` ```
#### Generating RLN membership keypair #### Generating RLN membership keypair
```js ```js
let memKeys = rlnInstance.generateMembershipKey(); let memKeys = rlnInstance.generateMembershipKey();
``` ```
#### Generating RLN membership keypair using a seed
```js
let memKeys = rlnInstance.generateSeededMembershipKey(seed);
```
#### Adding membership keys into merkle tree #### Adding membership keys into merkle tree
```js ```js
rlnInstance.insertMember(memKeys.IDCommitment); rlnInstance.insertMember(memKeys.IDCommitment);
``` ```
#### Generating a proof #### Generating a proof
```js ```js
// prepare the message // prepare the message
const uint8Msg = Uint8Array.from("Hello World".split("").map(x => x.charCodeAt())); const uint8Msg = Uint8Array.from(
"Hello World".split("").map((x) => x.charCodeAt())
);
// setting up the epoch (With 0s for the test) // setting up the epoch (With 0s for the test)
const epoch = new Uint8Array(32); const epoch = new Uint8Array(32);
// generating a proof // generating a proof
const proof = await rlnInstance.generateProof(uint8Msg, index, epoch, memKeys.IDKey) const proof = await rlnInstance.generateProof(
uint8Msg,
index,
epoch,
memKeys.IDKey
);
``` ```
#### Verifying a proof #### Verifying a proof
```js ```js
try { try {
// verify the proof // verify the proof
const verificationResult = rlnInstance.verifyProof(proof); const verificationResult = rlnInstance.verifyProof(proof);
console.log("Is proof verified?", verificationResult ? "yes" : "no"); console.log("Is proof verified?", verificationResult ? "yes" : "no");
} catch (err) { } catch (err) {
console.log("Invalid proof") console.log("Invalid proof");
} }
``` ```
### Updating circuit, verification key and zkey ### Updating circuit, verification key and zkey
The RLN specs defines the defaults. These values are fixed and should not The RLN specs defines the defaults. These values are fixed and should not
change. Currently, these [resources](https://github.com/vacp2p/zerokit/tree/master/rln/resources/tree_height_20) are being used. change. Currently, these [resources](https://github.com/vacp2p/zerokit/tree/master/rln/resources/tree_height_20) are being used.
If they change, this file needs to be updated in `resources.ts` which If they change, this file needs to be updated in `resources.ts` which
contains these values encoded in base64 in this format: contains these values encoded in base64 in this format:
``` ```
@ -85,37 +102,41 @@ const zkey = "...";
export {verification_key, circuit, zkey}; export {verification_key, circuit, zkey};
``` ```
A tool like GNU's `base64` could be used to encode this data. A tool like GNU's `base64` could be used to encode this data.
### Updating zerokit ### Updating zerokit
1. Make sure you have nodejs installed and a C compiler 1. Make sure you have nodejs installed and a C compiler
2. Install wasm-pack 2. Install wasm-pack
``` ```
curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
``` ```
3. Compile RLN for wasm 3. Compile RLN for wasm
``` ```
git clone https://github.com/vacp2p/zerokit git clone https://github.com/vacp2p/zerokit
cd zerokit/rln-wasm cd zerokit/rln-wasm
wasm-pack build --release wasm-pack build --release
``` ```
4. Copy `pkg/rln*` into `src/zerokit`
4. Copy `pkg/rln*` into `src/zerokit`
## Bugs, Questions & Features ## Bugs, Questions & Features
If you encounter any bug or would like to propose new features, feel free to [open an issue](https://github.com/waku-org/js-rln/issues/new/). If you encounter any bug or would like to propose new features, feel free to [open an issue](https://github.com/waku-org/js-rln/issues/new/).
For more general discussion, help and latest news, join [Vac Discord](https://discord.gg/PQFdubGt6d) or [Telegram](https://t.me/vacp2p). For more general discussion, help and latest news, join [Vac Discord](https://discord.gg/PQFdubGt6d) or [Telegram](https://t.me/vacp2p).
## License ## License
Licensed and distributed under either of Licensed and distributed under either of
* MIT license: [LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT - MIT license: [LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT
or or
* Apache License, Version 2.0, ([LICENSE-APACHEv2](LICENSE-APACHEv2) or http://www.apache.org/licenses/LICENSE-2.0) - Apache License, Version 2.0, ([LICENSE-APACHEv2](LICENSE-APACHEv2) or http://www.apache.org/licenses/LICENSE-2.0)
at your option. These files may not be copied, modified, or distributed except according to those terms. at your option. These files may not be copied, modified, or distributed except according to those terms.

14
package-lock.json generated
View File

@ -9,7 +9,7 @@
"version": "0.0.12", "version": "0.0.12",
"license": "MIT OR Apache-2.0", "license": "MIT OR Apache-2.0",
"dependencies": { "dependencies": {
"@waku/zerokit-rln-wasm": "^0.0.4" "@waku/zerokit-rln-wasm": "^0.0.5"
}, },
"devDependencies": { "devDependencies": {
"@rollup/plugin-commonjs": "^22.0.2", "@rollup/plugin-commonjs": "^22.0.2",
@ -2549,9 +2549,9 @@
"dev": true "dev": true
}, },
"node_modules/@waku/zerokit-rln-wasm": { "node_modules/@waku/zerokit-rln-wasm": {
"version": "0.0.4", "version": "0.0.5",
"resolved": "https://registry.npmjs.org/@waku/zerokit-rln-wasm/-/zerokit-rln-wasm-0.0.4.tgz", "resolved": "https://registry.npmjs.org/@waku/zerokit-rln-wasm/-/zerokit-rln-wasm-0.0.5.tgz",
"integrity": "sha512-J5Dh3CQAvSk1cn6Pv61wbTwuB0Sc1gR53ljVFqAovvTQSmMxY3I8vjE2vml5dLlhVCIlSAfBfnOr/OaBD3b0Mg==" "integrity": "sha512-uZHZRk06WrnqJJOVwIIKtsjWf2d6g2JpK8FtC0lHg4JJkOxhJy0pgEIuBCPw8Je4MpF9FCtIO/ww7xicdlC2GA=="
}, },
"node_modules/@web/rollup-plugin-import-meta-assets": { "node_modules/@web/rollup-plugin-import-meta-assets": {
"version": "1.0.7", "version": "1.0.7",
@ -12981,9 +12981,9 @@
"dev": true "dev": true
}, },
"@waku/zerokit-rln-wasm": { "@waku/zerokit-rln-wasm": {
"version": "0.0.4", "version": "0.0.5",
"resolved": "https://registry.npmjs.org/@waku/zerokit-rln-wasm/-/zerokit-rln-wasm-0.0.4.tgz", "resolved": "https://registry.npmjs.org/@waku/zerokit-rln-wasm/-/zerokit-rln-wasm-0.0.5.tgz",
"integrity": "sha512-J5Dh3CQAvSk1cn6Pv61wbTwuB0Sc1gR53ljVFqAovvTQSmMxY3I8vjE2vml5dLlhVCIlSAfBfnOr/OaBD3b0Mg==" "integrity": "sha512-uZHZRk06WrnqJJOVwIIKtsjWf2d6g2JpK8FtC0lHg4JJkOxhJy0pgEIuBCPw8Je4MpF9FCtIO/ww7xicdlC2GA=="
}, },
"@web/rollup-plugin-import-meta-assets": { "@web/rollup-plugin-import-meta-assets": {
"version": "1.0.7", "version": "1.0.7",

View File

@ -125,6 +125,6 @@
] ]
}, },
"dependencies": { "dependencies": {
"@waku/zerokit-rln-wasm": "^0.0.4" "@waku/zerokit-rln-wasm": "^0.0.5"
} }
} }

View File

@ -58,4 +58,72 @@ describe("js-rln", () => {
console.log(err); console.log(err);
} }
}); });
it("should verify a proof with a seeded membership key generation", async function () {
const rlnInstance = await rln.create();
const seed = "This is a test seed";
const memKeys = rlnInstance.generateSeededMembershipKey(seed);
//peer's index in the Merkle Tree
const index = 5;
// Create a Merkle tree with random members
for (let i = 0; i < 10; i++) {
if (i == index) {
// insert the current peer's pk
rlnInstance.insertMember(memKeys.IDCommitment);
} else {
// create a new key pair
rlnInstance.insertMember(
rlnInstance.generateMembershipKey().IDCommitment
);
}
}
// prepare the message
const uint8Msg = Uint8Array.from(
"Hello World".split("").map((x) => x.charCodeAt(0))
);
// setting up the epoch
const epoch = new Date();
// generating proof
const proof = await rlnInstance.generateRLNProof(
uint8Msg,
index,
epoch,
memKeys.IDKey
);
try {
// verify the proof
const verifResult = rlnInstance.verifyRLNProof(proof, uint8Msg);
expect(verifResult).to.be.true;
} catch (err) {
assert.fail(0, 1, "should not have failed proof verification");
}
try {
// Modifying the signal so it's invalid
uint8Msg[4] = 4;
// verify the proof
const verifResult = rlnInstance.verifyRLNProof(proof, uint8Msg);
expect(verifResult).to.be.false;
} catch (err) {
console.log(err);
}
});
it("should generate the same membership key if the same seed is provided", async function () {
const rlnInstance = await rln.create();
const seed = "This is a test seed";
const memKeys1 = rlnInstance.generateSeededMembershipKey(seed);
const memKeys2 = rlnInstance.generateSeededMembershipKey(seed);
memKeys1.IDCommitment.forEach((element, index) => {
expect(element).to.equal(memKeys2.IDCommitment[index]);
});
memKeys1.IDKey.forEach((element, index) => {
expect(element).to.equal(memKeys2.IDKey[index]);
});
});
}); });

View File

@ -125,6 +125,15 @@ export class RLNInstance {
return MembershipKey.fromBytes(memKeys); return MembershipKey.fromBytes(memKeys);
} }
generateSeededMembershipKey(seed: string): MembershipKey {
const seedBytes = stringEncoder.encode(seed);
const memKeys = zerokitRLN.generateSeededMembershipKey(
this.zkRLN,
seedBytes
);
return MembershipKey.fromBytes(memKeys);
}
insertMember(idCommitment: Uint8Array): void { insertMember(idCommitment: Uint8Array): void {
zerokitRLN.insertMember(this.zkRLN, idCommitment); zerokitRLN.insertMember(this.zkRLN, idCommitment);
} }