Home

Awesome

@waku/rln

This browser library enables the usage of RLN with Waku, as specified in the Waku v2 RLN Relay RFC.

Purpose

RLN Cryptography

The RLN cryptographic function are provided by zerokit. This is imported via the @waku/zerokit-rln-wasm dependencies which contains a WASM extract of zerokit's RLN functions.

Note that RLN Credentials generated with zerokit, and hence @waku/rln, are compatible with semaphore credentials.

Note that the WASM blob uses browser APIs, NodeJS is not supported.

Waku Interfaces

This library implements the IEncoder and IDecoder interfaces of js-waku.

This enables a seamless usage with js-waku applications, as demonstrated in the rln-js example.

Comparison to Existing Work

Rate-Limiting-Nullifier/rlnjs is an existing JavaScript / TypeScript library that already provides RLN cryptographic functionalities for the browser.

The core difference is that @waku/rln uses zerokit for cryptography and provide opinionated interfaces to use RLN specifically in the context of Waku.

Install

npm install @waku/rln

# or with yarn

yarn add @waku/rln

Or to use ESM import directly from a <script> tag:

<script type="module">
  import * as rln from "https://unpkg.com/@waku/rln@0.0.13/bundle/index.js";
</script>

Running example app

git clone https://github.com/waku-org/js-rln

cd js-rln/

npm install

cd example/

npm install  # or yarn

npm start

Browse http://localhost:8080 and open the dev tools console to see the proof being generated and its verification

Usage

Initializing the Library

import * as rln from "@waku/rln";

const rlnInstance = await rln.createRLN();

Starting RLN to listen to a contract

import * as rln from "@waku/rln";

const rlnInstance = await rln.createRLN();
await rlnInstance.start(); // will use default Sepolia contract

Generating RLN Membership Credentials

let credentials = rlnInstance.generateIdentityCredentials();

Generating RLN Membership Keypair Using a Seed

This can be used to generate credentials from a signature hash (e.g. signed by an Ethereum account).

let credentials = rlnInstance.generateSeededIdentityCredentials(seed);

Adding Membership Keys Into Merkle Tree

rlnInstance.insertMember(credentials.IDCommitment);

Registering Membership on a contract

import * as rln from "@waku/rln";

const rlnInstance = await rln.createRLN();
await rlnInstance.start(); // will use default Sepolia contract

const membershipInfo = await rlnInstance.contract.registerWithKey(credentials);

Generating a Proof

// prepare the message
const uint8Msg = Uint8Array.from(
  "Hello World".split("").map((x) => x.charCodeAt())
);

// setting up the epoch (With 0s for the test)
const epoch = new Uint8Array(32);

// generating a proof
const proof = await rlnInstance.generateProof(
  uint8Msg,
  index,
  epoch,
  credentials.IDSecretHash
);

Verifying a Proof

try {
  // verify the proof
  const verificationResult = rlnInstance.verifyProof(proof, uint8Msg);
  console.log("Is proof verified?", verificationResult ? "yes" : "no");
} catch (err) {
  console.log("Invalid proof");
}

Updating Circuit, Verification Key and Zkey

The RLN specs defines the defaults. These values are fixed and should not change. Currently, these resources are being used. If they change, this file needs to be updated in resources.ts which contains these values encoded in base64 in this format:

const verification_key = "...";
const circuit = "..."; // wasm file generated by circom
const zkey = "...";
export {verification_key, circuit, zkey};

A tool like GNU's base64 could be used to encode this data.

Updating Zerokit

  1. Make sure you have NodeJS installed and a C compiler
  2. Install wasm-pack
curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
  1. Compile RLN for wasm
git clone https://github.com/vacp2p/zerokit
cd zerokit/rln-wasm
wasm-pack build --release
  1. Copy pkg/rln* into src/zerokit

Bugs, Questions & Features

If you encounter any bug or would like to propose new features, feel free to open an issue.

For more general discussion, help and latest news, join Vac Discord or Telegram.

License

Licensed and distributed under either of

or

at your option. These files may not be copied, modified, or distributed except according to those terms.