Skip to content
This repository has been archived by the owner on Jun 14, 2024. It is now read-only.

72/WAKU-RLN-KEYSTORE: add new RFC #631

Closed
wants to merge 68 commits into from
Closed
Show file tree
Hide file tree
Changes from 59 commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
05774a2
Create pushNotification.md
jimstir Oct 9, 2023
8482057
Update pushNotification.md
jimstir Oct 9, 2023
789da9f
Update pushNotification.md
jimstir Oct 9, 2023
7d6e110
Update pushNotification.md
jimstir Oct 9, 2023
d480749
Update pushNotification.md
jimstir Oct 10, 2023
54d00f4
Update pushNotification.md
jimstir Oct 10, 2023
3f98728
Update and rename content/docs/rfcs/pushNotification.md to content/do…
jimstir Oct 31, 2023
56f529b
Update README.md
jimstir Nov 1, 2023
91bf1f9
Update README.md
jimstir Nov 1, 2023
e261d70
Update README.md
jimstir Nov 1, 2023
a59cbc0
Update README.md
jimstir Nov 1, 2023
ff67c9c
Update content/docs/rfcs/71/README.md
jimstir Nov 1, 2023
5bc2998
Update content/docs/rfcs/71/README.md
jimstir Nov 1, 2023
d9369aa
Update content/docs/rfcs/71/README.md
jimstir Nov 1, 2023
0f6b38d
Update content/docs/rfcs/71/README.md
jimstir Nov 1, 2023
7651f85
Update content/docs/rfcs/71/README.md
jimstir Nov 1, 2023
5ee2f79
Update content/docs/rfcs/71/README.md
jimstir Nov 1, 2023
07d8d3c
Update README.md
jimstir Nov 1, 2023
f2537fd
Add Status spec link
jimstir Nov 1, 2023
7ca9747
Removed mailserver, added some references
jimstir Nov 7, 2023
0ea85b8
Update README.md
jimstir Nov 7, 2023
21c606a
Create waku-keystore.md
jimstir Nov 10, 2023
2b5003f
Update waku-keystore.md
jimstir Nov 10, 2023
a4ce749
Update and rename
jimstir Nov 10, 2023
5838105
Delete content/docs/rfcs/71 directory
jimstir Nov 10, 2023
3780b73
Update README.md
jimstir Nov 10, 2023
44fdac5
Update README.md
jimstir Nov 17, 2023
1c2cb23
Update README.md
jimstir Nov 17, 2023
7d92cf1
Update README.md
jimstir Nov 17, 2023
34dffbd
Update README.md
jimstir Nov 17, 2023
20dc741
Update README.md
jimstir Nov 17, 2023
7bb67dc
Update README.md
jimstir Nov 17, 2023
ebabff9
Update README.md
jimstir Nov 17, 2023
ec4f919
Update README.md
jimstir Nov 17, 2023
9dd5b8e
Update README.md
jimstir Nov 18, 2023
f3131fe
Update README.md
jimstir Nov 18, 2023
ab283d8
Update README.md
jimstir Nov 18, 2023
afe76c5
Update README.md
jimstir Nov 18, 2023
c07ed83
Update README.md
jimstir Nov 18, 2023
d6a28e4
Update README.md
jimstir Nov 18, 2023
85482b6
Update README.md
jimstir Nov 19, 2023
20b1d74
Update README.md
jimstir Nov 23, 2023
cb1b36a
Update README.md
jimstir Nov 23, 2023
486f29b
Update README.md
jimstir Nov 23, 2023
6d4c4e2
Update index.md
jimstir Nov 23, 2023
69e7e4f
Update README.md
jimstir Nov 26, 2023
107e597
Update README.md
jimstir Dec 8, 2023
0d9031f
Merge branch 'master' into jimstir-waku-keystore-1
jimstir Dec 19, 2023
db2f25c
Update README.md
jimstir Dec 20, 2023
77ea5e4
Update README.md
jimstir Dec 20, 2023
e52467e
Update README.md
jimstir Dec 21, 2023
203db41
Update README.md
jimstir Dec 21, 2023
d2c59d1
Update README.md
jimstir Dec 21, 2023
b47509e
Update README.md
jimstir Dec 30, 2023
fc6e517
Update README.md
jimstir Dec 31, 2023
570fd0d
Update README.md
jimstir Jan 8, 2024
b55d7dd
Update README.md
jimstir Jan 9, 2024
521967f
Update README.md
jimstir Jan 9, 2024
c130e26
Update README.md
jimstir Jan 9, 2024
956289f
Update README.md
jimstir Jan 12, 2024
e4aba48
Update README.md
jimstir Jan 12, 2024
8af8f71
Update README.md
jimstir Jan 12, 2024
6636245
Update README.md
jimstir Jan 13, 2024
056d87b
Update README.md
jimstir Jan 17, 2024
67cc9dd
Update README.md
jimstir Jan 17, 2024
12bc8d3
Update README.md
jimstir Jan 21, 2024
905260f
Update README.md
jimstir Jan 22, 2024
dc64cc5
Update README.md
jimstir Feb 9, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
301 changes: 301 additions & 0 deletions content/docs/rfcs/72/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,301 @@
---
slug: 72
title: 72/WAKU-RLN-KEYSTORE
name: Waku RLN Keystore
status: raw
category: Standards Track
editor: Jimmy Debe <jimmy@status.im>
contributors:
- Aaryamann Challani <aaryamann@status.im>
---

# Abstract
This specification describes how RLN, Rate Limit Nullifier,
credentials are securely stored in a JSON schema.

# Summary
A keystore is a construct to store a user’s keys.
The keys will be encrypted and decrypted based on methods specified in this specification.
The keystore stores a user's credentials locally and
uses [32/RLN-V1](/spec/32/) as a spam-prevention mechanism by generating zero-knowledge proofs.

# Background
The secure storage of keys is important in peer-to-peer messaging applications.
A `72/WAKU-RLN-KEYSTORE` uses zero-knowledge proofs for anonymous rate-limiting for messaging frameworks.
Generated credentials by a user are encrypted and stored in the keystore to be retrieved over a network.
With [32/RLN-V1](/spec/32/), sending and receiving
messages will ensure a message rate for a network is being followed while preserving the anonymity of the message owner.

## Waku RLN Keystore Format:

A format example of a keystore used by a [17/WAKU2-RLN-Relay](/spec/17/).

```js
const Keystore {
application: "waku-rln-relay" ,
appIdentifier: "string",
version: "string",
credentials: {
"membershipHash": {
crypto: {
cipher: "string",
cipherparams: {
iv: "string",
},
ciphertext: "string",
kdf: "string",
kdfparams: {
dklen: integer,
c: integer,
prf: "string",
salt: "string",
},
mac: "string",
}
}
}
}

```

# Specification
The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”,
“NOT RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in [RFC 2119](https://www.ietf.org/rfc/rfc2119.txt).

The keystore MUST be generated by a cryptographic construction with password verification and decryption.

Keystore modules MUST include metadata, key derivation function, checksum, cipher, and a membership hash.

## Metadata:
Information about the keystore SHOULD be stored in the metadata.

The declaration of `application`, `version`, and `appIdentifier` COULD occur in the metadata.

- `application` : current application, MUST be a string
- `version` : application version, MUST be a string
jimstir marked this conversation as resolved.
Show resolved Hide resolved
- `appIdentifier`: application identifier, MUST be a string

## Credentials:

After RLN credentials are generated, it MUST be stored in a JSON schema.
The Waku RLN credentials MUST consist of a `membershipHash` and `WakuCredential`.
The `membershipHash` will be an identity hash of the user.
The `WakuCredential` will store to encryption portion of the keystore.
There COULD be multiple credentials stored in a keystore, categorized by the `membershipHash`.

Each contruct MUST include the keypair:
> key: [`membershipHash`]: pair: [`WakuCredential`]

### membershipHash

The `membershipHash` SHOULD be generated by user's participating in a membership group.
Each user SHOULD register to the group with an `identity_commitment` stored in a Merkle tree.
A cryptographic hash function that SHOULD be used to generate the `membershipHash` is [SHA256](https://www.rfc-editor.org/rfc/rfc4634.txt).
The hash function that is used,
SHOULD be mentioned in the `verison` attribute.
To generate the `membershipHash`,
the `treeIndex`, `membershipContract`, `contractId` and `identityCredential` attributes SHOULD be used to create a hexadecimal string.
- it MUST NOT already exist in the keystore.

#### treeIndex

After a user registers to a group,
a `treeIndex` value of the position in the Merkle tree SHOULD be returned.
- it MUST be a Merkle tree data structure filled with `identity_commitment` from user registrations.
- it MUST be a hexadecimal string

#### membershipContract

For decentralized membership registrations,
the `membershipContract` SHOULD be derived from a public blockchain using smart contracts.
- it MUST be a hash of a `contractAddress`
jimstir marked this conversation as resolved.
Show resolved Hide resolved
- `contractAddess` MUST be a string.

#### contractId

The `contractId` SHOULD be the blockchain identifier used for `membershipcontract`.
- it MUST be a string
jimstir marked this conversation as resolved.
Show resolved Hide resolved
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


#### identityCredential

The `identityCredential` MUST be derived after a succussful decryption of the keystore.

The `identityCredential` MUST be constructed with the `identity_secret`, `identity_secret_hash`, `identity_commitment` values.
- it MUST be a hash of `identity_commitment` stored in a Merkle tree.
- it MUST be a string.

##### `identity_secret`

The `identity_secret` MUST be constructed with `identity_nullifier` + `identity_trapdoor` values.
- `identity_nullifier` : Random 32 byte value
- `identity_trapdoor` : Random 32 byte value

##### `identity_secret_hash`

Used to derive the `identity_commitment` of the user, and
as a private input for zero-knowledge proof generation.
- it MUST be created with `identity_secret` as a parameter for the hash function.
- This secret hash SHOULD be kept private by the user.

##### `identity_commitment`
- it MUST be created with `identity_secret_hash` by using hashing function as described in [Poseidon Paper](https://eprint.iacr.org/2019/458.pdf).
- it MUST be used by a user for group registering.

### `WakuCredential`

The `WakuCredential` will store values used for encrytion and decrypting user's credentials.
- it MUST be used for password verification.
- it MUST follow [EIP-2335](https://eips.ethereum.org/EIPS/eip-2335)

### KDF

The password-based encryption used SHOULD be KDF, key derivation function,
to produce a derived key from a password and other parameters.
The keystore COULD use PBKDF2 password-based encryption,
as described in [RFC 2898](https://www.ietf.org/rfc/rfc2898.txt).

A `WakuCredential` object MUST include:
| Name | Description |
|----|-----|
| password | used to encrypt keystore and decryption key |
| secret | key to be encrypted |
| pubKey | public key |
| path | HD, hardened derivation, path used to generate the secret |
| checksum | hashing function |
| cipher | cipher function |

```js

crypto: {

cipher: "string" // The cipher function
cipherparams: {
iv: "string" // The cipher parameters
},
ciphertext: "string" // The cipher message,
kdf: "string" // KDF Function,
kdfparams: {
param: integer // Salt value and iteration count,
dklen: integer // Length in octets of derived key, MUST be positive integer,
c: "string" // Iteration count, MUST be positive integer,
prf: "string" // Underlying pseudorandom function,
salt: "string" // Produces a large set of keys based on the password
},
mac: "string" // Checksum
}

```

### Decryption
The keystore SHOULD decrypt a user's credentials using a password and
a Merkle proof, the `membershipHASh`, using PBKDF2 that returns the `decryptionKey` key.
jimstir marked this conversation as resolved.
Show resolved Hide resolved
jimstir marked this conversation as resolved.
Show resolved Hide resolved
The decryption key is used to verify the keystore is correct.
- To generate the `decryptionKey`, it MUST be constructed from a password and KDF,
as desrcibed in [ERC-2335: BLS12-381 Keystore](https://eips.ethereum.org/EIPS/eip-2335).
- The `decryptionKey`, is derived from the cipher function and
cipher parameters described in the KDF used in the keystore.

## Test Vectors
### Input:
Hashing function used: Poseidon Hash, as described in [Poseidon Paper](https://eprint.iacr.org/2019/458.pdf)

`application`: "waku-rln-relay"

`appIdentifier`: "01234567890abcdef"

`version`: "0.2"

`hashFunction`: "poseidonHash"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does this hashFunction refer to the hash function used by the rln protocol, or by the keystore? it is necessary to differentiate between the two because we use sha256 to generate the keys for the multiple credentials in the keystore, and poseidon in the protocol which will not change anytime soon. if we do decide to move from poseidon to a different hash function, that will be reflected in the keystore version field, which we will update and ensure the rfc has the reference to it for other implementers as well.

Copy link
Contributor Author

@jimstir jimstir Jan 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rymnc clarified where poseidon is being used in the test vector section. Also clarified for identity_commitment here.


`password`: "sup3rsecure"



```js

identityCredential = {
IDTrapdoor: [
211, 23, 66, 42, 179, 130, 131, 111, 201, 205, 244, 34, 27, 238, 244,
216, 131, 240, 188, 45, 193, 172, 4, 168, 225, 225, 43, 197, 114, 176,
126, 9,
],
IDNullifier: [
238, 168, 239, 65, 73, 63, 105, 19, 132, 62, 213, 205, 191, 255, 209, 9,
178, 155, 239, 201, 131, 125, 233, 136, 246, 217, 9, 237, 55, 89, 81,
42,
],
IDSecretHash: [
150, 54, 194, 28, 18, 216, 138, 253, 95, 139, 120, 109, 98, 129, 146,
101, 41, 194, 36, 36, 96, 152, 152, 89, 151, 160, 118, 15, 222, 124,
187, 4,
],
IDCommitment: [
112, 216, 27, 89, 188, 135, 203, 19, 168, 211, 117, 13, 231, 135, 229,
58, 94, 20, 246, 8, 33, 65, 238, 37, 112, 97, 65, 241, 255, 93, 171, 15,
],

}

membership = {
chainId: "0xAA36A7",
treeIndex: 8,
address: "0x8e1F3742B987d8BA376c0CBbD7357fE1F003ED71",
}

```

### Output:

```js
application: "waku-rln-relay",
appIdentifier: "01234567890abcdef",
version: "0.2",
credentials: {
"9DB2B4718A97485B9F70F68D1CC19F4E10F0B4CE943418838E94956CB8E57548": {
crypto: {
cipher: "aes-128-ctr",
cipherparams: {
iv: "fd6b39eb71d44c59f6bf5ff3d8945c80",
},
ciphertext: "9c72f47ce95de03ed34502d0288e7576b66b51b9e7d5ae882c27bd89f94e6a03c2c44c2ddf0c982e72003d67212105f1b64614f57cabb0ceadab7e07be165eee1121ad6b81951368a9f3be2dd99ea294515f6013d5f2bd4702a40e36cfde2ea298b23b31e5ce719d8040c3331f73d6bf44f88bca39bac0e917d8bf545500e4f40d321c235426a80f315ac70666acbd3bdf803fbc1e7e7103fed466525ed332b25d72b2dbedf6fa383b2305987c1fe276b029570519b3e79930edf08c1029868d05c2c08ab61d7c64f63c054b4f6a5a12d43cdc79751b6fe58d3ed26b69443eb7c9f7efce27912340129c91b6b813ac94efd5776a40b1dda896d61357de208c7c47a14af911cc231355c8093ee6626e89c07e1037f9e0b22c690e3e049014399ca0212c509cb04c71c7860d1b17a0c47711c490c27bad2825926148a1f15a507f36ba2cdaa04897fce2914e53caed0beaf1bebd2a83af76511cc15bff2165ff0860ad6eca1f30022d7739b2a6b6a72f2feeef0f5941183cda015b4631469e1f4cf27003cab9a90920301cb30d95e4554686922dc5a05c13dfb575cdf113c700d607896011970e6ee7d6edb61210ab28ac8f0c84c606c097e3e300f0a5f5341edfd15432bef6225a498726b62a98283829ad51023b2987f30686cfb4ea3951f3957654035ec291f9b0964a3a8665d81b16cec20fb40f944d5f9bf03ac1e444ad45bae3fa85e7465ce620c0966d8148d6e2856f676c4fbbe3ebe470453efb4bbda1866680037917e37765f680e3da96ef3991f3fe5cda80c523996c2234758bf5f7b6d052dc6942f5a92c8b8eec5d2d8940203bbb6b1cba7b7ebc1334334ca69cdb509a5ea58ec6b2ebaea52307589eaae9430eb15ad234c0c39c83accdf3b77e52a616e345209c5bc9b442f9f0fa96836d9342f983a7",
kdf: "pbkdf2",
kdfparams: {
dklen: 32,
c: 1000000,
prf: "hmac-sha256",
salt: "60f0aa92fbf63a8356dfdbed2ab18058",
},
mac: "51a227ac6db7f2797c63925880b3db664e034231a4c68daa919ab42d8df38bc6",
},
}


```

# Security Considerations
### 1.) Add a Password

An attacker can identify which credential belongs to a combination of `chainId` and
`contractAddress` pair by brute forcing the `treeIndex` iteratively to find a hash match.
The RECOMMENDED solution is to add a password to the construction of `membershipHash` to prevent this attack.

The RECOMMENDED `membershipHash` Construction:
- `membershipHash` SHOULD be constructed with `treeIndex`, `membershipContract`, `identityCredential`, `membershipPassword`
- `membershipPassword` : a new password created to private attacks compromising keystore credentials.
- The user MUST store the `membershipPassword` privately.

# Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).

# References
1. [32/RLN-V1](/spec/32/)
2. [17/WAKU2-RLN-RELAY](/spec/17/)
3. [RFC 2119](https://datatracker.ietf.org/doc/html/rfc2119)
4. [RFC 8174](https://datatracker.ietf.org/doc/html/rfc8174)
5. [EIP-2335](https://eips.ethereum.org/EIPS/eip-2335)
6. [RFC 2898](https://www.ietf.org/rfc/rfc2898.txt)
7. [ERC-2335: BLS12-381 Keystore](https://eips.ethereum.org/EIPS/eip-2335)
8. [Poseidon Paper](https://eprint.iacr.org/2019/458.pdf)



1 change: 1 addition & 0 deletions content/menu/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ bookMenuLevels: 1
- [66/WAKU2-METADATA]({{< relref "/docs/rfcs/66/README.md" >}})
- [70/ETH-SECPM]({{< relref "/docs/rfcs/70/README.md" >}})
- [71/STATUS-PUSH-NOTIFICATION-SERVER]({{< relref "/docs/rfcs/71/README.md" >}})
- [72/WAKU-RLN-KEYSTORE]({{< relref "/docs/rfcs/72/README.md" >}})
- Draft
- [1/COSS]({{< relref "/docs/rfcs/1/README.md" >}})
- [3/REMOTE-LOG]({{< relref "/docs/rfcs/3/README.md" >}})
Expand Down