diff --git a/standards/application/rln-keystore.md b/standards/application/rln-keystore.md index e79fbf5..bc0838e 100644 --- a/standards/application/rln-keystore.md +++ b/standards/application/rln-keystore.md @@ -91,13 +91,14 @@ Each contruct MUST include the keypair: #### membershipHash -The `membershipHash` SHOULD be generated by users participating in a membership group, +The `membershipHash` SHOULD be generated by nodes participating in a membership group, 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. -A cryptographic hash function that SHOULD be used to generate the `membershipHash` is [SHA256](https://www.rfc-editor.org/rfc/rfc4634.txt), +Each node SHOULD register to the group using an `identity_commitment` stored in a Merkle tree. +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. -The hash function used SHOULD be defined in the `verison` attribute. -It MUST NOT already exist in the keystore. +The hash function SHOULD be defined in the `verison` attribute. +A `membershipHash` MUST NOT already exist in the keystore. + To generate the `membershipHash` the following attributes SHOULD be used to create a hexadecimal string: - `treeIndex` : @@ -106,26 +107,25 @@ To generate the `membershipHash` the following attributes SHOULD be used to crea - `identityCredential` - `rateLimit` - ##### `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. -- it MUST be a Merkle tree data structure filled with the `identity_commitment` from user registrations. +- it MUST be a Merkle tree data structure filled with the `identity_commitment` from node registrations. - it SHOULD be a hexadecimal string ##### `membershipContract` For decentralized membership registrations, -the `membershipContract` SHOULD be a `contractAddress` of a smart contract deployed on a blockchain. +the `membershipContract` value SHOULD be a `contractAddress` of a smart contract deployed on a blockchain. - it SHOULD be a string. ##### `chainId` 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). - it MUST be a string @@ -147,24 +147,25 @@ The `identity_secret` MUST be constructed with `identity_nullifier` + `identity_ ###### `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. + - it MUST be created with `identity_secret` as a parameter for the hash function. -- This secret hash SHOULD be kept private by the user. +- 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, 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 user's membership rate limit +- it SHOULD be the node's membership rate limit #### WakuCredential -The `WakuCredential` will store values used for encrypting and decrypting a user's keystore. +The `WakuCredential` will store values used for encrypting and decrypting a node's keystore. - it MUST be used for password verification. - it MUST follow [EIP-2335](https://eips.ethereum.org/EIPS/eip-2335) @@ -178,6 +179,7 @@ The keystore MAY 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 | @@ -211,9 +213,9 @@ crypto: { #### 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. -The `decryptionKey` 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, as desrcibed in [ERC-2335: BLS12-381 Keystore](https://eips.ethereum.org/EIPS/eip-2335). @@ -295,14 +297,16 @@ version: "0.2", ``` ## Security Considerations + ### 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. 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` +- The `membershipHash` RECOMMENDED to be constructed with `treeIndex`, `membershipContract`, +`identityCredential`, `rateLimit`, and `membershipPassword` - `membershipPassword` : a new password created to private attacks compromising keystore credentials. - The user MUST store the `membershipPassword` privately.