mirror of
https://github.com/logos-messaging/specs.git
synced 2026-01-03 22:53:11 +00:00
Merge pull request #78 from waku-org/keystore-update
WAKU-RLN-KEYSTORE: Update
This commit is contained in:
commit
ef6a766519
@ -8,25 +8,33 @@ contributors:
|
|||||||
---
|
---
|
||||||
|
|
||||||
## Abstract
|
## Abstract
|
||||||
This specification describes how RLN, Rate Limit Nullifier,
|
|
||||||
|
This specification describes how the RLN, Rate Limit Nullifier,
|
||||||
credentials are securely stored in a JSON schema.
|
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
|
## Background
|
||||||
|
|
||||||
|
A keystore is a construct to store a user’s cryptographic keys.
|
||||||
|
The keys are encrypted and decrypted based on the methods specified in this specification.
|
||||||
|
A [17/WAKU2-RLN-RELAY](https://github.com/vacp2p/rfc-index/blob/main/waku/standards/core/17/rln-relay.md)
|
||||||
|
keystore stores a node's credentials locally and
|
||||||
|
[32/RLN-V1](https://github.com/vacp2p/rfc-index/blob/main/vac/32/rln-v1.md) is used as a spam-prevention mechanism with the help of zero-knowledge proofs.
|
||||||
|
|
||||||
The secure storage of keys is important in peer-to-peer messaging applications.
|
The secure storage of keys is important in peer-to-peer messaging applications.
|
||||||
A `WAKU-RLN-KEYSTORE` uses zero-knowledge proofs for anonymous rate-limiting for messaging frameworks.
|
Zero-knowledge proofs are used to have anonymous rate-limiting for messaging frameworks.
|
||||||
Generated credentials by a user are encrypted and stored in the keystore to be retrieved over a network.
|
Node's Credentials are encrypted and
|
||||||
With [32/RLN-V1](/spec/32/), sending and receiving
|
stored in the keystore to be retrieved at any time over the Waku network.
|
||||||
messages will ensure a message rate for a network is being followed while preserving the anonymity of the message owner.
|
With [32/RLN-V1](https://github.com/vacp2p/rfc-index/blob/main/vac/32/rln-v1.md), sending and receiving
|
||||||
|
messages will ensure a message rate for the network is being followed while preserving the anonymity of the message owner.
|
||||||
|
|
||||||
|
## 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).
|
||||||
|
|
||||||
### Waku RLN Keystore Format:
|
### Waku RLN Keystore Format:
|
||||||
|
|
||||||
A format example of a keystore used by a [17/WAKU2-RLN-Relay](/spec/17/).
|
A format example of a keystore used by a [17/WAKU2-RLN-Relay](https://github.com/vacp2p/rfc-index/blob/main/waku/standards/core/17/rln-relay.md).
|
||||||
|
|
||||||
```js
|
```js
|
||||||
const Keystore {
|
const Keystore {
|
||||||
@ -56,18 +64,14 @@ const Keystore {
|
|||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Specification
|
The keystore MUST be generated using a cryptographic construction that supports password verification and decryption.
|
||||||
The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”,
|
Keystore modules MUST include metadata, a key derivation function, a checksum, a cipher, and a membership hash.
|
||||||
“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:
|
### Metadata:
|
||||||
|
|
||||||
Information about the keystore SHOULD be stored in the metadata.
|
Information about the keystore SHOULD be stored in the metadata.
|
||||||
|
|
||||||
The declaration of `application`, `version`, and `appIdentifier` COULD occur in the metadata.
|
The declaration of `application`, `version`, and `appIdentifier` MAY occur in the metadata.
|
||||||
|
|
||||||
- `application` : current application, MUST be a string
|
- `application` : current application, MUST be a string
|
||||||
- `version` : application version, MUST be a string, SHOULD follow semantic versioning
|
- `version` : application version, MUST be a string, SHOULD follow semantic versioning
|
||||||
@ -75,90 +79,107 @@ The declaration of `application`, `version`, and `appIdentifier` COULD occur in
|
|||||||
|
|
||||||
### Credentials:
|
### Credentials:
|
||||||
|
|
||||||
After RLN credentials are generated, it MUST be stored in a JSON schema.
|
After the RLN credentials are generated, it MUST be stored in a JSON schema.
|
||||||
The Waku RLN credentials MUST consist of a `membershipHash` and `WakuCredential`.
|
The credentials MUST consist of a `membershipHash` and `WakuCredential`.
|
||||||
The `membershipHash` will be an identity hash of the user.
|
The `membershipHash` will be an identity hash of the user.
|
||||||
The `WakuCredential` will store to encryption portion of the keystore.
|
The `WakuCredential` will store the encryption portion of the keystore.
|
||||||
There COULD be multiple credentials stored in a keystore, categorized by the `membershipHash`.
|
There MAY be multiple credentials stored in a keystore,
|
||||||
|
categorized by the `membershipHash`.
|
||||||
|
|
||||||
Each contruct MUST include the keypair:
|
Each contruct MUST include the keypair:
|
||||||
> key: [`membershipHash`]: pair: [`WakuCredential`]
|
> key: [`membershipHash`]: pair: [`WakuCredential`]
|
||||||
|
|
||||||
#### membershipHash
|
#### membershipHash
|
||||||
|
|
||||||
The `membershipHash` SHOULD be generated by user's participating in a membership group,
|
The `membershipHash` SHOULD be generated by nodes participating in a membership group,
|
||||||
as decribed in [32/RLN-V1](/spec/32/).
|
as decribed in [32/RLN-V1](https://github.com/vacp2p/rfc-index/blob/main/vac/32/rln-v1.md).
|
||||||
Each user SHOULD register to the group with an `identity_commitment` stored in a Merkle tree.
|
Each node SHOULD register to the group using 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 RECOMMENDED cryptographic hash function used to generate the `membershipHash` is [SHA256](https://www.rfc-editor.org/rfc/rfc4634.txt),
|
||||||
other hash functions MAY be used.
|
other hash functions MAY be used.
|
||||||
The hash function that is used,
|
The hash function SHOULD be defined in the `verison` attribute.
|
||||||
SHOULD be mentioned in the `verison` attribute.
|
A `membershipHash` MUST NOT already exist in the keystore.
|
||||||
|
|
||||||
To generate the `membershipHash`,
|
To generate the `membershipHash` the following attributes SHOULD be used to create a hexadecimal string:
|
||||||
the `treeIndex`, `membershipContract`, `chainId` and `identityCredential` attributes SHOULD be used to create a hexadecimal string.
|
|
||||||
- it MUST NOT already exist in the keystore.
|
- `treeIndex` :
|
||||||
|
- `membershipContract`
|
||||||
|
- `chainId`,
|
||||||
|
- `identityCredential`
|
||||||
|
- `rateLimit`
|
||||||
|
|
||||||
##### `treeIndex`
|
##### `treeIndex`
|
||||||
|
|
||||||
After a user registers to a group,
|
After a node registers to a group,
|
||||||
a `treeIndex` value of the position in the Merkle tree SHOULD be returned.
|
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
|
- it MUST be a Merkle tree data structure filled with the `identity_commitment` from node registrations.
|
||||||
|
- it SHOULD be a hexadecimal string
|
||||||
|
|
||||||
##### `membershipContract`
|
##### `membershipContract`
|
||||||
|
|
||||||
For decentralized membership registrations,
|
For decentralized membership registrations,
|
||||||
the `membershipContract` SHOULD be a `contractAddress` from a public blockchain using smart contracts.
|
the `membershipContract` value SHOULD be a `contractAddress` of a smart contract deployed on a blockchain.
|
||||||
- it MUST be a string.
|
|
||||||
|
- it SHOULD be a string.
|
||||||
|
|
||||||
##### `chainId`
|
##### `chainId`
|
||||||
|
|
||||||
It uniquely defines the chain upon which the registration has occurred.
|
It uniquely defines the chain upon which the registration has occurred.
|
||||||
The `chainId` SHOULD be the blockchain identifier used for `membershipcontract`,
|
The `chainId` value SHOULD be the blockchain identifier used for `membershipContract`,
|
||||||
as described in [EIP155](https://eips.ethereum.org/EIPS/eip-155).
|
as described in [EIP155](https://eips.ethereum.org/EIPS/eip-155).
|
||||||
|
|
||||||
- it MUST be a string
|
- it MUST be a string
|
||||||
|
|
||||||
##### `identityCredential`
|
##### `identityCredential`
|
||||||
|
|
||||||
The `identityCredential` MUST be derived after a succussful decryption of the keystore.
|
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.
|
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 hash of `identity_commitment` stored in a Merkle tree.
|
||||||
- it MUST be a string.
|
- it MUST be a string.
|
||||||
|
|
||||||
###### `identity_secret`
|
###### `identity_secret`
|
||||||
|
|
||||||
The `identity_secret` MUST be constructed with `identity_nullifier` + `identity_trapdoor` values.
|
The `identity_secret` MUST be constructed with `identity_nullifier` + `identity_trapdoor` values.
|
||||||
|
|
||||||
- `identity_nullifier` : Random 32 byte value
|
- `identity_nullifier` : Random 32 byte value
|
||||||
- `identity_trapdoor` : Random 32 byte value
|
- `identity_trapdoor` : Random 32 byte value
|
||||||
|
|
||||||
###### `identity_secret_hash`
|
###### `identity_secret_hash`
|
||||||
|
|
||||||
Used to derive the `identity_commitment` of the user, and
|
Used to derive the `identity_commitment` of the node, and
|
||||||
as a private input for zero-knowledge proof generation.
|
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` as a parameter for the hash function.
|
||||||
|
- This secret hash SHOULD be kept private by the node.
|
||||||
|
|
||||||
|
###### `identity_commitment`
|
||||||
|
|
||||||
- it SHOULD be created with `identity_secret_hash` by using the hash function Poseidon,
|
- it SHOULD be created with `identity_secret_hash` by using the hash function Poseidon,
|
||||||
as described in [Poseidon Paper](https://eprint.iacr.org/2019/458.pdf).
|
as described in [Poseidon Paper](https://eprint.iacr.org/2019/458.pdf).
|
||||||
- it MUST be used by a user for group registering.
|
- it MUST be used by a node for group registering.
|
||||||
|
|
||||||
|
##### `rateLimit`
|
||||||
|
|
||||||
|
- it SHOULD be the node's membership rate limit
|
||||||
|
|
||||||
#### WakuCredential
|
#### WakuCredential
|
||||||
|
|
||||||
The `WakuCredential` will store values used for encrypting and decrypting user's keystores.
|
The `WakuCredential` will store values used for encrypting and decrypting a node's keystore.
|
||||||
|
|
||||||
- it MUST be used for password verification.
|
- it MUST be used for password verification.
|
||||||
- it MUST follow [EIP-2335](https://eips.ethereum.org/EIPS/eip-2335)
|
- it MUST follow [EIP-2335](https://eips.ethereum.org/EIPS/eip-2335)
|
||||||
- it SHOULD use [SHA256](https://www.rfc-editor.org/rfc/rfc4634.txt) as the hash function
|
- it SHOULD use [SHA256](https://www.rfc-editor.org/rfc/rfc4634.txt) as the hash function
|
||||||
|
|
||||||
|
|
||||||
#### KDF
|
#### KDF
|
||||||
|
|
||||||
The password-based encryption used SHOULD be KDF, key derivation function,
|
The password-based encryption used SHOULD be KDF, key derivation function,
|
||||||
to produce a derived key from a password and other parameters.
|
to produce a derived key from a password and other parameters.
|
||||||
The keystore COULD use PBKDF2 password-based encryption,
|
The keystore MAY use PBKDF2 password-based encryption,
|
||||||
as described in [RFC 2898](https://www.ietf.org/rfc/rfc2898.txt).
|
as described in [RFC 2898](https://www.ietf.org/rfc/rfc2898.txt).
|
||||||
|
|
||||||
A `WakuCredential` object MUST include:
|
A `WakuCredential` object MUST include:
|
||||||
|
|
||||||
| Name | Description |
|
| Name | Description |
|
||||||
|----|-----|
|
|----|-----|
|
||||||
| password | used to encrypt keystore and decryption key |
|
| password | used to encrypt keystore and decryption key |
|
||||||
@ -191,9 +212,11 @@ crypto: {
|
|||||||
```
|
```
|
||||||
|
|
||||||
#### Decryption
|
#### Decryption
|
||||||
The keystore SHOULD decrypt a user's credentials using a password and the `membershipHash`,
|
|
||||||
|
The keystore SHOULD decrypt a node's credentials using a password and the `membershipHash`,
|
||||||
using PBKDF2 that returns the `decryptionKey` key.
|
using PBKDF2 that returns the `decryptionKey` key.
|
||||||
The decryption key is used to verify the keystore is correct.
|
The `decryptionKey` is used to verify that the keystore has the correct credentials.
|
||||||
|
|
||||||
- To generate the `decryptionKey`, it MUST be constructed from a password and KDF,
|
- 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).
|
as desrcibed in [ERC-2335: BLS12-381 Keystore](https://eips.ethereum.org/EIPS/eip-2335).
|
||||||
- The `decryptionKey`, is derived from the cipher function and
|
- The `decryptionKey`, is derived from the cipher function and
|
||||||
@ -274,14 +297,16 @@ version: "0.2",
|
|||||||
```
|
```
|
||||||
|
|
||||||
## Security Considerations
|
## Security Considerations
|
||||||
|
|
||||||
### 1.) Add a Password
|
### 1.) Add a Password
|
||||||
|
|
||||||
An attacker can identify which credential belongs to a combination of `chainId` and
|
An attacker can identify which credential belongs to a node with a combination of `chainId` and
|
||||||
`contractAddress` pair by brute forcing the `treeIndex` iteratively to find a hash match.
|
`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 solution is to add a password to the construction of `membershipHash` to prevent this attack.
|
||||||
|
|
||||||
The RECOMMENDED `membershipHash` Construction:
|
The RECOMMENDED `membershipHash` Construction:
|
||||||
- `membershipHash` SHOULD be constructed with `treeIndex`, `membershipContract`, `identityCredential`, `membershipPassword`
|
- The `membershipHash` RECOMMENDED to be constructed with `treeIndex`, `membershipContract`,
|
||||||
|
`identityCredential`, `rateLimit`, and `membershipPassword`
|
||||||
- `membershipPassword` : a new password created to private attacks compromising keystore credentials.
|
- `membershipPassword` : a new password created to private attacks compromising keystore credentials.
|
||||||
- The user MUST store the `membershipPassword` privately.
|
- The user MUST store the `membershipPassword` privately.
|
||||||
|
|
||||||
@ -289,8 +314,8 @@ The RECOMMENDED `membershipHash` Construction:
|
|||||||
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
|
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
|
||||||
|
|
||||||
## References
|
## References
|
||||||
1. [32/RLN-V1](/spec/32/)
|
1. [32/RLN-V1](https://github.com/vacp2p/rfc-index/blob/main/vac/32/rln-v1.md)
|
||||||
2. [17/WAKU2-RLN-RELAY](/spec/17/)
|
2. [17/WAKU2-RLN-RELAY](https://github.com/vacp2p/rfc-index/blob/main/waku/standards/core/17/rln-relay.md)
|
||||||
3. [SHA256](https://www.rfc-editor.org/rfc/rfc4634.txt)
|
3. [SHA256](https://www.rfc-editor.org/rfc/rfc4634.txt)
|
||||||
4. [EIP155](https://eips.ethereum.org/EIPS/eip-155)
|
4. [EIP155](https://eips.ethereum.org/EIPS/eip-155)
|
||||||
5. [Poseidon Paper](https://eprint.iacr.org/2019/458.pdf)
|
5. [Poseidon Paper](https://eprint.iacr.org/2019/458.pdf)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user