From 05774a2ba9bc35522aefc298d977ef450a4327c6 Mon Sep 17 00:00:00 2001
From: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Date: Mon, 9 Oct 2023 12:33:55 -0400
Subject: [PATCH 01/67] Create pushNotification.md
---
content/docs/rfcs/pushNotification.md | 70 +++++++++++++++++++++++++++
1 file changed, 70 insertions(+)
create mode 100644 content/docs/rfcs/pushNotification.md
diff --git a/content/docs/rfcs/pushNotification.md b/content/docs/rfcs/pushNotification.md
new file mode 100644
index 000000000..180111862
--- /dev/null
+++ b/content/docs/rfcs/pushNotification.md
@@ -0,0 +1,70 @@
+---
+slug: XX
+title:
+name: Status Push Notification Server
+status: raw
+category: Standards Track
+editor: Jimmy Debe
+---
+
+
+# Abstract
+Push notification server implementation for IOS devices and Android devices. This implementation is a set of functions that will allow clients to have push notification services in restricting mobile environments.
+
+# Background
+
+Mobile devices using iOS and some android devices have restrictions for applications that want to use push notifications. Apple devices can use the APN service, Apple Push Notifications, or Firebase for Android devices. For some Android devices, foreground services are restricted, require a user to grant the foreground notifications, seen as dangerous. Apple iOS devices, restrict notifications to some internal functions, that not every application can use. Applications request to use background but does not schedule background resources if the application was forced quit and is not background services are not responsive envoy for push notification systems.
+
+# Specification
+The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.
+
+### Definitions:
+client = A node that implements the Status specification.
+User = The owner of a device that runs a client
+topic =
+server = A service that performs push notifications
+Token? =
+Mailserver = A Waku node that decides to provide functionality to store messages permanently and deliver the messages to requesting clients.
+
+### Components:
+gorush Instance =
+Only used by push notification servers and MUST be publicly available.
+
+Push Notification Server =
+Used by clients to register for receiving and sending notifications.
+
+Registering Client =
+A client that want to receive push notifications.
+
+Sending Client =
+A client that want to send push notifications.
+
+Requirements = The party releasing the app MUST possess a certificate for the Apple Push Notification service and its has to run a [gorush](https://github.com/appleboy/gorush) publicly accessible server for sending the actual notification. The party releasing the app, Status in this case, needs to run its own [gorush](https://github.com/appleboy/gorush).
+
+
+
+## Push Notification Server Flow
+### Registration Process:
+
+![image](https://github.com/jimstir/rfc/assets/91767824/00cae4bf-6eb5-4e7b-9377-3a5d01b041a1)
+
+### Sending and Receiving Notification Process:
+
+![image](https://github.com/jimstir/rfc/assets/91767824/cd33c21d-26f1-4137-834c-d0e1a536600e)
+
+## Registering Client
+
+Registering a client with a push notification service.
+
+- A client MAY register with one or more push notification services in order to increase availability.
+- A client SHOULD make sure that all the notification services they registered with have the same information about their tokens.
+- A `PNR message` (Push Notification Registration) MUST be sent to the [partitioned topic](https://specs.status.im/spec/10#partitioned-topic) for the public key of the node, encrypted with this key.
+- The message MUST be wrapped in a `ApplicationMetadataMessage` with type set to `PUSH_NOTIFICATION_REGISTRATION`.
+- The marshaled protobuf payload MUST also be encrypted with AES-GCM using the Diffie–Hellman key generated from the client and server identity. This is done in order to ensure that the extracted key from the signature will be considered invalid if it can’t decrypt the payload.
+
+The content of the message MUST contain the following [protobuf record](https://developers.google.com/protocol-buffers/):
+
+
+
+
+
From 84820573f9236e17cd615be4beff123e18c6342e Mon Sep 17 00:00:00 2001
From: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Date: Mon, 9 Oct 2023 14:06:34 -0400
Subject: [PATCH 02/67] Update pushNotification.md
---
content/docs/rfcs/pushNotification.md | 396 ++++++++++++++++++++++++--
1 file changed, 380 insertions(+), 16 deletions(-)
diff --git a/content/docs/rfcs/pushNotification.md b/content/docs/rfcs/pushNotification.md
index 180111862..317001b85 100644
--- a/content/docs/rfcs/pushNotification.md
+++ b/content/docs/rfcs/pushNotification.md
@@ -19,27 +19,41 @@ Mobile devices using iOS and some android devices have restrictions for applicat
The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.
### Definitions:
-client = A node that implements the Status specification.
-User = The owner of a device that runs a client
-topic =
-server = A service that performs push notifications
-Token? =
-Mailserver = A Waku node that decides to provide functionality to store messages permanently and deliver the messages to requesting clients.
+
+client
+> A node that implements the Status specification.
+
+user
+> The owner of a device that runs a client
+
+topic
+> Resource in
+
+server
+> A service that performs push notifications
+
+Token
+> Resource
+
+Mailserver
+> A Waku node that decides to provide functionality to store messages permanently and deliver the messages to requesting clients.
### Components:
-gorush Instance =
-Only used by push notification servers and MUST be publicly available.
-Push Notification Server =
-Used by clients to register for receiving and sending notifications.
+gorush Instance
+> Only used by push notification servers and MUST be publicly available.
+
+Push Notification Server
+> Used by clients to register for receiving and sending notifications.
-Registering Client =
-A client that want to receive push notifications.
+Registering Client
+> A client that want to receive push notifications.
-Sending Client =
-A client that want to send push notifications.
+Sending Client
+> A client that want to send push notifications.
-Requirements = The party releasing the app MUST possess a certificate for the Apple Push Notification service and its has to run a [gorush](https://github.com/appleboy/gorush) publicly accessible server for sending the actual notification. The party releasing the app, Status in this case, needs to run its own [gorush](https://github.com/appleboy/gorush).
+Requirements:
+The party releasing the app MUST possess a certificate for the Apple Push Notification service and its has to run a [gorush](https://github.com/appleboy/gorush) publicly accessible server for sending the actual notification. The party releasing the app, Status in this case, needs to run its own [gorush](https://github.com/appleboy/gorush).
@@ -50,7 +64,8 @@ Requirements = The party releasing the app MUST possess a certificate for the Ap
### Sending and Receiving Notification Process:
-![image](https://github.com/jimstir/rfc/assets/91767824/cd33c21d-26f1-4137-834c-d0e1a536600e)
+![image](https://github.com/jimstir/rfc/assets/91767824/c999d10c-7f3a-4ab4-8471-a005c0969f40)
+
## Registering Client
@@ -64,6 +79,355 @@ Registering a client with a push notification service.
The content of the message MUST contain the following [protobuf record](https://developers.google.com/protocol-buffers/):
+```protobuf
+message PushNotificationRegistration {
+ enum TokenType {
+ UNKNOWN_TOKEN_TYPE = 0;
+ APN_TOKEN = 1;
+ FIREBASE_TOKEN = 2;
+ }
+ TokenType token_type = 1;
+ string device_token = 2;
+ string installation_id = 3;
+ string access_token = 4;
+ bool enabled = 5;
+ uint64 version = 6;
+ repeated bytes allowed_key_list = 7;
+ repeated bytes blocked_chat_list = 8;
+ bool unregister = 9;
+ bytes grant = 10;
+ bool allow_from_contacts_only = 11;
+ string apn_topic = 12;
+ bool block_mentions = 13;
+ repeated bytes allowed_mentions_chat_list = 14;
+}
+```
+
+A push notification server will handle the message according to the following rules:
+- it MUST extract the public key of the sender from the signature and verify that the payload can be decrypted successfully.
+- it MUST verify that `token_type` is supported.
+- it MUST verify that `device_token` is non empty.
+- it MUST verify that `installation_id` is non empty.
+- it MUST verify that `version` is non-zero and greater than the currently stored version for the public key and installation id of the sender, if any.
+- it MUST verify that `grant` is non empty and according to the Grant Server specs.
+- it MUST verify that `access_token` is a valid uuid.
+- it MUST verify that `apn_topic` is set if token_type is APN_TOKEN.
+- The message MUST be wrapped in a `ApplicationMetadataMessage` with type set to `PUSH_NOTIFICATION_REGISTRATION_RESPONSE`.
+
+The payload of the response is:
+
+```protobuf
+message PushNotificationRegistrationResponse {
+ bool success = 1;
+ ErrorType error = 2;
+ bytes request_id = 3;
+
+ enum ErrorType {
+ UNKNOWN_ERROR_TYPE = 0;
+ MALFORMED_MESSAGE = 1;
+ VERSION_MISMATCH = 2;
+ UNSUPPORTED_TOKEN_TYPE = 3;
+ INTERNAL_ERROR = 4;
+ }
+}
+
+```
+A client SHOULD listen for a response sent on the [partitioned topic](https://specs.status.im/spec/10#partitioned-topic) that the key used to register. If success is true the client has registered successfully.
+
+If `success` is `false`:
+ > If `MALFORMED_MESSAGE` is returned, the request SHOULD NOT be retried without ensuring that it is correctly formed.
+ > If `INTERNAL_ERROR` is returned, the request MAY be retried, but the client MUST backoff exponentially.
+
+### Handle Errors:
+- If the message can’t be decrypted, the message MUST be discarded.
+- If `token_type` is not supported, a response MUST be sent with `error` set to `UNSUPPORTED_TOKEN_TYPE`.
+-If `token`, `installation_id`, `device_tokens`, `version` are empty, a response MUST be sent with `error` set to `MALFORMED_MESSAGE`.
+- If the `version` is equal or less than the currently stored `version`, a response MUST be sent with `error` set to `VERSION_MISMATCH`.
+- If any other error occurs the `error` should be set to `INTERNAL_ERROR`.
+- If the response is successful `success` MUST be set to `true` otherwise a response MUST be sent with `success` set to `false`.
+- `request_id` should be set to the `SHAKE-256` of the encrypted payload.
+- The response MUST be sent on the [partitioned topic][./10-waku-usage.md#partitioned-topic] of the sender and MUST not be encrypted using the secure transport to facilitate the usage of ephemeral keys.
+- If no response is returned, the request SHOULD be considered failed and MAY be retried with the same server or a different one, but clients MUST exponentially backoff after each trial.
+
+## Push Notification Server
+A node that handles receiving and sending push notifications for clients.
+
+### Query Topic
+On successful registration the server MUST be listening to the topic derived from:
+ > `0XHexEncode(Shake256(CompressedClientPublicKey))`
+
+Using the topic derivation algorithm described here and listen for client queries.
+### Server Grant
+A client needs to authorize a push notification server to send them push notifications. This is done by building a grant which is specific to a given client-server pair. When receiving a grant, the server MUST validate that the signature matches the registering client.
+
+The grant is built as:
+ > `Signature(Keccak256(CompressedPublicKeyOfClient . CompressedPublicKeyOfServer . AccessToken), PrivateKeyOfClient)`
+
+
+### Unregistering with a Server
+- To unregister a client MUST send a `PushNotificationRegistration` request as described above with `unregister` set to `true`, or removing their device information.
+- The server MUST remove all data about this user if `unregistering` is `true`, apart from the `hash` of the public key and the `version` of the last options, in order to make sure that old messages are not processed.
+- A client MAY unregister from a server on explicit logout if multiple chat keys are used on a single device.
+
+### Re-registering with a Server
+- A client SHOULD re-register with the node if the APN or FIREBASE token changes.
+- When re-registering a client SHOULD ensure that it has the most up-to-date `PushNotificationRegistration` and increment `version` if necessary.
+- Once re-registered, a client SHOULD advertise the changes.
+Changing options is handled the same as re-registering.
+
+### Advertising a Server
+Each user registered with one or more push notification servers SHOULD advertise periodically the push notification services that they have registered with for each device they own.
+
+```protobuf
+message PushNotificationQueryInfo {
+ string access_token = 1;
+ string installation_id = 2;
+ bytes public_key = 3;
+ repeated bytes allowed_user_list = 4;
+ bytes grant = 5;
+ uint64 version = 6;
+ bytes server_public_key = 7;
+}
+
+message ContactCodeAdvertisement {
+ repeated PushNotificationQueryInfo push_notification_info = 1;
+}
+
+```
+
+### Handle Advertisment Message:
+- The message MUST be wrapped in a `ApplicationMetadataMessage` with type set to `PUSH_NOTIFICATION_QUERY_INFO`.
+- If no filtering is done based on public keys, the access token SHOULD be included in the advertisement. Otherwise it SHOULD be left empty.
+- This SHOULD be advertised on the contact code topic and SHOULD be coupled with normal contact-code advertisement.
+- Every time a user register or re-register with a push notification service, their contact-code SHOULD be re-advertised.
+- Multiple servers MAY be advertised for the same installation_id for redundancy reasons.
+
+### Discovering a Server
+To discover a push notification service for a given user, their contact code topic SHOULD be listened to. A mailserver can be queried for the specific topic to retrieve the most up-to-date contact code.
+
+### Querying a Server:
+If a token is not present in the latest advertisement for a user, the server SHOULD be queried directly.
+
+To query a server a message:
+
+```protobuf
+message PushNotificationQuery {
+ repeated bytes public_keys = 1;
+}
+
+```
+
+### Handle Query Message
+- The message MUST be wrapped in a ApplicationMetadataMessage with type set to PUSH_NOTIFICATION_QUERY.
+- MUST be sent to the server on the topic derived from the hashed public key of the key we are querying, as described above.
+- An ephemeral key SHOULD be used and SHOULD NOT be encrypted using the secure transport.
+
+If the server has information about the client a response MUST be sent:
+
+```protobuf
+message PushNotificationQueryInfo {
+ string access_token = 1;
+ string installation_id = 2;
+ bytes public_key = 3;
+ repeated bytes allowed_user_list = 4;
+ bytes grant = 5;
+ uint64 version = 6;
+ bytes server_public_key = 7;
+}
+
+message PushNotificationQueryResponse {
+ repeated PushNotificationQueryInfo info = 1;
+ bytes message_id = 2;
+ bool success = 3;
+}
+
+```
+
+### Handle Query Response
+- A `PushNotificationQueryResponse` message MUST be wrapped in a `ApplicationMetadataMessage` with type set to `PUSH_NOTIFICATION_QUERY_RESPONSE`.
+Otherwise a response MUST NOT be sent.
+- If `allowed_key_list` is not set `access_token` MUST be set and `allowed_key_list` MUST NOT be set.
+- If `allowed_key_list` is set `allowed_key_list` MUST be set and `access_token` MUST NOT be set.
+- If `access_token` is returned, the `access_token` SHOULD be used to send push notifications.
+- If `allowed_key_list` are returned, the client SHOULD decrypt each token by generating an `AES-GCM` symmetric key from the Diffie–Hellman between the target client and itself If AES decryption succeeds it will return a valid `uuid` which is what is used for access_token. The token SHOULD be used to send push notifications.
+- The response MUST be sent on the [partitioned topic](https://specs.status.im/spec/10#partitioned-topic) of the sender and MUST not be encrypted using the [secure transport](https://specs.status.im/spec/5) to facilitate the usage of ephemeral keys.
+- On receiving a response a client MUST verify `grant` to ensure that the server has been authorized to send push notification to a given client.
+
+## Sending Client
+Sending a push notification
+- When sending a push notification, only the installation_id for the devices targeted by the message SHOULD be used.
+- If a message is for all the user devices, all the installation_id known to the client MAY be used.
+- The number of devices MAY be capped in order to reduce resource consumption.
+- At least 3 devices SHOULD be targeted, ordered by last activity.
+- For any device that a token is available, or that a token is successfully queried, a push notification message SHOULD be sent to the corresponding push notification server.
+
+```protobuf
+message PushNotification {
+ string access_token = 1;
+ string chat_id = 2;
+ bytes public_key = 3;
+ string installation_id = 4;
+ bytes message = 5;
+ PushNotificationType type = 6;
+ enum PushNotificationType {
+ UNKNOWN_PUSH_NOTIFICATION_TYPE = 0;
+ MESSAGE = 1;
+ MENTION = 2;
+ }
+ bytes author = 7;
+}
+
+message PushNotificationRequest {
+ repeated PushNotification requests = 1;
+ bytes message_id = 2;
+}
+
+```
+### Handle Notification Request
+- A `PushNotificationRequest` message MUST be wrapped in a `ApplicationMetadataMessage` with type set to `PUSH_NOTIFICATION_REQUEST`.
+- Where message is the encrypted payload of the message and `chat_id` is the `SHAKE-256` of the `chat_id`. `message_id` is the id of the message author is the `SHAKE-256` of the public key of the sender.
+- If multiple server are available for a given push notification, only one notification MUST be sent.
+- If no response is received a client SHOULD wait at least 3 seconds, after which the request MAY be retried against a different server.
+- This message SHOULD be sent using an ephemeral key.
+
+On receiving the message, the push notification server MUST validate the access token. If the access token is valid, a notification MUST be sent to the gorush instance with the following data:
+
+```yaml
+{
+ "notifications": [
+ {
+ "tokens": ["token_a", "token_b"],
+ "platform": 1,
+ "message": "You have a new message",
+ "data": {
+ "chat_id": chat_id,
+ "message": message,
+ "installation_ids": [installation_id_1, installation_id_2]
+ }
+ }
+ ]
+}
+
+```
+
+Where platform is 1 for IOS and 2 for Firebase, according to the [gorush](https://github.com/appleboy/gorush) documentation.
+
+A server MUST return a response message:
+
+```protobuf
+message PushNotificationReport {
+ bool success = 1;
+ ErrorType error = 2;
+ enum ErrorType {
+ UNKNOWN_ERROR_TYPE = 0;
+ WRONG_TOKEN = 1;
+ INTERNAL_ERROR = 2;
+ NOT_REGISTERED = 3;
+ }
+ bytes public_key = 3;
+ string installation_id = 4;
+}
+
+```
+
+```protobuf
+message PushNotificationResponse {
+ bytes message_id = 1;
+ repeated PushNotificationReport reports = 2;
+}
+
+```
+### Handle Notification Response
+- A PushNotificationResponse message MUST be wrapped in a ApplicationMetadataMessage with type set to PUSH_NOTIFICATION_RESPONSE.
+- Where `message_id` is the `message_id` sent by the client.
+-The response MUST be sent on the [partitioned topic][./10-waku-usage.md#partitioned-topic] of the sender and MUST not be encrypted using the secure transport to facilitate the usage of ephemeral keys.
+- If the request is accepted success MUST be set to `true`. Otherwise `success` MUST be set to `false`.
+- If error is `BAD_TOKEN` the client MAY query again the server for the token and retry the request.
+- If error is `INTERNAL_ERROR` the client MAY retry the request.
+
+## Protobuf Description
+
+### PushNotificationRegistration
+`token_type`: the type of token. Currently supported is `APN_TOKEN` for Apple Push `device_token`: the actual push notification token sent by `Firebase` or `APN` and `FIREBASE_TOKEN` for firebase. `installation_id`: the `installation_id` of the device `access_token`: the access token that will be given to clients to send push notifications `enabled`: whether the device wants to be sent push notifications `version`: a monotonically increasing number identifying the current `PushNotificationRegistration`. Any time anything is changed in the record it MUST be increased by the client, otherwise the request will not be accepted. `allowed_key_list`: a list of `access_token` encrypted with the AES key generated by Diffie–Hellman between the publisher and the allowed contact. `blocked_chat_list`: a list of `SHA2-256` hashes of chat ids. Any chat id in this list will not trigger a notification. `unregister`: whether the account should be unregistered `grant`: the grant for this specific server `allow_from_contacts_only`: whether the client only wants push notifications from contacts `apn_topic`: the APN topic for the push notification `block_mentions`: whether the client does not want to be notified on mentions `allowed_mentions_chat_list`: a list of SHA2-256 hashes of chat ids where we want to receive mentions
+
+DATA DISCLOSED
+- Type of device owned by a given user.
+- The `FIREBASE` or `APN` push notification token,
+- Hash of the chat_id a user is not interested in for notifications,
+- The times a push notification record has been modified by the user,
+- The number of contacts a client has, in case `allowed_key_list` is set.
+
+### PushNotificationRegistrationResponse
+`success`: whether the registration was successful `error`: the error type, if any `request_id`: the `SHAKE-256` hash of the signature of the `request preferences`: the server stored preferences in case of an error.
+
+### ContactCodeAdvertisement
+`push_notification_info`: the information for each device advertised
+
+DATA DISCLOSED
+- The chat key of the sender
+
+### PushNotificationQuery
+`public_keys`: the `SHAKE-256` of the public keys the client is interested in
+
+DATA DISCLOSED
+- The hash of the public keys the client is interested in
+
+### PushNotificationQueryInfo
+`access_token`: the access token used to send a push notification `installation_id`: the `installation_id` of the device associated with the access_token `public_key`: the `SHAKE-256` of the public key associated with this `access_token` and `installation_id`. `allowed_key_list`: a list of encrypted access tokens to be returned to the client in case there’s any filtering on public keys in place. `grant`: the grant used to register with this server. `version`: the version of the registration on the server. `server_public_key`: the compressed public key of the server.
+
+### PushNotificationQueryResponse
+`info`: a list of PushNotificationQueryInfo. `message_id`: the message id of the `PushNotificationQueryInfo` the server is replying to. `success`: whether the query was successful.
+
+### PushNotification
+`access_token`: the access token used to send a push notification. chat_id: the `SHAKE-256` of the chat_id. `public_key`: the `SHAKE-25`6 of the compressed public key of the receiving client. `installation_id`: the installation id of the receiving client. `message`: the encrypted message that is being notified on. `type`: the type of the push notification, either MESSAGE or MENTION `author`: the `SHAKE-256` of the public key of the sender
+
+Data disclosed
+- The SHAKE-256 of the `chat_id` the notification is to be sent for
+- The cypher text of the message
+- The `SHAKE-256` of the public key of the sender
+- The type of notification
+
+### PushNotificationRequest
+`requests`: a list of PushNotification `message_id`: the status message id
+
+Data disclosed
+- The status message id for which the notification is for
+
+### PushNotificationResponse
+`message_id`: the `message_id` being notified on. `reports`: a list of PushNotificationReport
+
+### PushNotificationReport
+`success`: whether the push notification was successful. `error`: the type of the error in case of failure. `public_key`: the public key of the user being notified. `installation_id`: the installation id of the user being notified.
+
+## Anonymous Mode:
+In order to preserve privacy, the client MAY provide anonymous mode of operations to propagate information about the user. A client in anonymous mode can register with the server using a key that is different from their chat key. This will hide their real chat key. This public key is effectively a secret and SHOULD only be disclosed to clients approved to notify a user.
+
+- A client MAY advertise the access token on the contact-code topic of the key generated.
+- A client MAY share their public key contact updates in the protobuf record.
+- A client receiving a push notification public key SHOULD listen to the contact code topic of the push notification public key for updates.
+
+The method described above effectively does not share the identity of the sender nor the receiver to the server, but MAY result in missing push notifications as the propagation of the secret is left to the client. This can be mitigated by device syncing, but not completely addressed.
+
+# Security/Privacy Considerations:
+If no anonymous mode is used, when registering with a push notification service a client disclose:
+- The devices that will receive notifications.
+- The chat key.
+
+A client MAY disclose:
+- The hash of the chat_ids they want to filter out.
+
+When running in anonymous mode, the client’s chat key is not disclosed.
+
+When querying a push notification server a client will disclose:
+- That it is interested in sending push notification to another client, but querying client’s chat key is not disclosed.
+When sending a push notification a client disclose:
+- The `shake-256` of the chat-id.
+
+# Copyright
+
+Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
+
+# References
From 789da9f3959f19943e2ca74fc6d79f6c6474c4a1 Mon Sep 17 00:00:00 2001
From: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Date: Mon, 9 Oct 2023 15:12:39 -0400
Subject: [PATCH 03/67] Update pushNotification.md
---
content/docs/rfcs/pushNotification.md | 109 +++++++++++++-------------
1 file changed, 54 insertions(+), 55 deletions(-)
diff --git a/content/docs/rfcs/pushNotification.md b/content/docs/rfcs/pushNotification.md
index 317001b85..4c22e3e87 100644
--- a/content/docs/rfcs/pushNotification.md
+++ b/content/docs/rfcs/pushNotification.md
@@ -9,11 +9,15 @@ editor: Jimmy Debe
# Abstract
-Push notification server implementation for IOS devices and Android devices. This implementation is a set of functions that will allow clients to have push notification services in restricting mobile environments.
+Push notification server implementation for IOS devices and Android devices. This specification provide a is a set of methods that allow clients to use push notification services in mobile environments.
# Background
-Mobile devices using iOS and some android devices have restrictions for applications that want to use push notifications. Apple devices can use the APN service, Apple Push Notifications, or Firebase for Android devices. For some Android devices, foreground services are restricted, require a user to grant the foreground notifications, seen as dangerous. Apple iOS devices, restrict notifications to some internal functions, that not every application can use. Applications request to use background but does not schedule background resources if the application was forced quit and is not background services are not responsive envoy for push notification systems.
+Push notifications for iOS and Android devices can only be implemented by relying on [APN](https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/APNSOverview.html#//apple_ref/doc/uid/TP40008194-CH8-SW1), Apple Push Notification, service for iOS or [Firebase](https://firebase.google.com/) for Android.
+
+For some Android devices, foreground services are restricted, requiring a user to grant authorization to applications for foreground notifications. Apple iOS devices, restrict notifications to some internal functions, that not every application can use. Applications on iOS can request execution time when they are in the background. This has limited set of use cases for example, it will not schedule any time if the application was force quit. Requesting execution time is not reponsive enough to implement a push notification system. Status provides a set of push notification services
+
+Since this can not be safely implemented in a privacy preserving manner, clients need to be given an option to opt-in receiving and sending push notifications. They are disabled by default.
# Specification
The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.
@@ -24,19 +28,13 @@ client
> A node that implements the Status specification.
user
-> The owner of a device that runs a client
-
-topic
-> Resource in
+> The owner of a device that runs a client.
server
-> A service that performs push notifications
+> A service that performs push notifications.
-Token
-> Resource
-
-Mailserver
-> A Waku node that decides to provide functionality to store messages permanently and deliver the messages to requesting clients.
+mailserver
+> A Waku node that provides functionality to store messages permanently and deliver the messages to requesting clients.
### Components:
@@ -47,12 +45,12 @@ Push Notification Server
> Used by clients to register for receiving and sending notifications.
Registering Client
-> A client that want to receive push notifications.
+> A client that wants to receive push notifications.
Sending Client
-> A client that want to send push notifications.
+> A client that wants to send push notifications.
-Requirements:
+Requirements:
The party releasing the app MUST possess a certificate for the Apple Push Notification service and its has to run a [gorush](https://github.com/appleboy/gorush) publicly accessible server for sending the actual notification. The party releasing the app, Status in this case, needs to run its own [gorush](https://github.com/appleboy/gorush).
@@ -64,7 +62,7 @@ The party releasing the app MUST possess a certificate for the Apple Push Notifi
### Sending and Receiving Notification Process:
-![image](https://github.com/jimstir/rfc/assets/91767824/c999d10c-7f3a-4ab4-8471-a005c0969f40)
+![image](https://github.com/jimstir/rfc/assets/91767824/b2c66ddf-d13a-4373-9e24-8ad2b5955b86)
## Registering Client
@@ -74,7 +72,7 @@ Registering a client with a push notification service.
- A client MAY register with one or more push notification services in order to increase availability.
- A client SHOULD make sure that all the notification services they registered with have the same information about their tokens.
- A `PNR message` (Push Notification Registration) MUST be sent to the [partitioned topic](https://specs.status.im/spec/10#partitioned-topic) for the public key of the node, encrypted with this key.
-- The message MUST be wrapped in a `ApplicationMetadataMessage` with type set to `PUSH_NOTIFICATION_REGISTRATION`.
+- The message MUST be wrapped in a [`ApplicationMetadataMessage`](https://specs.status.im/spec/6) with type set to `PUSH_NOTIFICATION_REGISTRATION`.
- The marshaled protobuf payload MUST also be encrypted with AES-GCM using the Diffie–Hellman key generated from the client and server identity. This is done in order to ensure that the extracted key from the signature will be considered invalid if it can’t decrypt the payload.
The content of the message MUST contain the following [protobuf record](https://developers.google.com/protocol-buffers/):
@@ -108,11 +106,11 @@ A push notification server will handle the message according to the following ru
- it MUST verify that `token_type` is supported.
- it MUST verify that `device_token` is non empty.
- it MUST verify that `installation_id` is non empty.
-- it MUST verify that `version` is non-zero and greater than the currently stored version for the public key and installation id of the sender, if any.
+- it MUST verify that `version` is non-zero and greater than the currently stored version for the public key and `installation_id` of the sender, if any.
- it MUST verify that `grant` is non empty and according to the Grant Server specs.
- it MUST verify that `access_token` is a valid uuid.
- it MUST verify that `apn_topic` is set if token_type is APN_TOKEN.
-- The message MUST be wrapped in a `ApplicationMetadataMessage` with type set to `PUSH_NOTIFICATION_REGISTRATION_RESPONSE`.
+- The message MUST be wrapped in a [`ApplicationMetadataMessage`](https://specs.status.im/spec/6) with type set to `PUSH_NOTIFICATION_REGISTRATION_RESPONSE`.
The payload of the response is:
@@ -143,9 +141,9 @@ If `success` is `false`:
- If `token_type` is not supported, a response MUST be sent with `error` set to `UNSUPPORTED_TOKEN_TYPE`.
-If `token`, `installation_id`, `device_tokens`, `version` are empty, a response MUST be sent with `error` set to `MALFORMED_MESSAGE`.
- If the `version` is equal or less than the currently stored `version`, a response MUST be sent with `error` set to `VERSION_MISMATCH`.
-- If any other error occurs the `error` should be set to `INTERNAL_ERROR`.
+- If any other error occurs the `error` SHOULD be set to `INTERNAL_ERROR`.
- If the response is successful `success` MUST be set to `true` otherwise a response MUST be sent with `success` set to `false`.
-- `request_id` should be set to the `SHAKE-256` of the encrypted payload.
+- `request_id` SHOULD be set to the `SHAKE-256` of the encrypted payload.
- The response MUST be sent on the [partitioned topic][./10-waku-usage.md#partitioned-topic] of the sender and MUST not be encrypted using the secure transport to facilitate the usage of ephemeral keys.
- If no response is returned, the request SHOULD be considered failed and MAY be retried with the same server or a different one, but clients MUST exponentially backoff after each trial.
@@ -196,14 +194,14 @@ message ContactCodeAdvertisement {
```
### Handle Advertisment Message:
-- The message MUST be wrapped in a `ApplicationMetadataMessage` with type set to `PUSH_NOTIFICATION_QUERY_INFO`.
+- The message MUST be wrapped in a [`ApplicationMetadataMessage`](https://specs.status.im/spec/6) with type set to `PUSH_NOTIFICATION_QUERY_INFO`.
- If no filtering is done based on public keys, the access token SHOULD be included in the advertisement. Otherwise it SHOULD be left empty.
-- This SHOULD be advertised on the contact code topic and SHOULD be coupled with normal contact-code advertisement.
+- This SHOULD be advertised on the [contact code topic](https://specs.status.im/spec/10#contact-code-topic) and SHOULD be coupled with normal contact-code advertisement.
- Every time a user register or re-register with a push notification service, their contact-code SHOULD be re-advertised.
- Multiple servers MAY be advertised for the same installation_id for redundancy reasons.
### Discovering a Server
-To discover a push notification service for a given user, their contact code topic SHOULD be listened to. A mailserver can be queried for the specific topic to retrieve the most up-to-date contact code.
+To discover a push notification service for a given user, their [contact code topic](https://specs.status.im/spec/10#contact-code-topic) SHOULD be listened to. A mailserver can be queried for the specific topic to retrieve the most up-to-date contact code.
### Querying a Server:
If a token is not present in the latest advertisement for a user, the server SHOULD be queried directly.
@@ -218,9 +216,9 @@ message PushNotificationQuery {
```
### Handle Query Message
-- The message MUST be wrapped in a ApplicationMetadataMessage with type set to PUSH_NOTIFICATION_QUERY.
+- The message MUST be wrapped in a [`ApplicationMetadataMessage`](https://specs.status.im/spec/6) with type set to `PUSH_NOTIFICATION_QUERY`.
- MUST be sent to the server on the topic derived from the hashed public key of the key we are querying, as described above.
-- An ephemeral key SHOULD be used and SHOULD NOT be encrypted using the secure transport.
+- An ephemeral key SHOULD be used and SHOULD NOT be encrypted using the [secure transport](https://specs.status.im/spec/5).
If the server has information about the client a response MUST be sent:
@@ -244,19 +242,19 @@ message PushNotificationQueryResponse {
```
### Handle Query Response
-- A `PushNotificationQueryResponse` message MUST be wrapped in a `ApplicationMetadataMessage` with type set to `PUSH_NOTIFICATION_QUERY_RESPONSE`.
+- A `PushNotificationQueryResponse` message MUST be wrapped in a [`ApplicationMetadataMessage`](https://specs.status.im/spec/6) with type set to `PUSH_NOTIFICATION_QUERY_RESPONSE`.
Otherwise a response MUST NOT be sent.
- If `allowed_key_list` is not set `access_token` MUST be set and `allowed_key_list` MUST NOT be set.
- If `allowed_key_list` is set `allowed_key_list` MUST be set and `access_token` MUST NOT be set.
- If `access_token` is returned, the `access_token` SHOULD be used to send push notifications.
- If `allowed_key_list` are returned, the client SHOULD decrypt each token by generating an `AES-GCM` symmetric key from the Diffie–Hellman between the target client and itself If AES decryption succeeds it will return a valid `uuid` which is what is used for access_token. The token SHOULD be used to send push notifications.
-- The response MUST be sent on the [partitioned topic](https://specs.status.im/spec/10#partitioned-topic) of the sender and MUST not be encrypted using the [secure transport](https://specs.status.im/spec/5) to facilitate the usage of ephemeral keys.
+- The response MUST be sent on the [partitioned topic](https://specs.status.im/spec/10#partitioned-topic) of the sender and MUST NOT be encrypted using the [secure transport](https://specs.status.im/spec/5) to facilitate the usage of ephemeral keys.
- On receiving a response a client MUST verify `grant` to ensure that the server has been authorized to send push notification to a given client.
## Sending Client
Sending a push notification
-- When sending a push notification, only the installation_id for the devices targeted by the message SHOULD be used.
-- If a message is for all the user devices, all the installation_id known to the client MAY be used.
+- When sending a push notification, only the `installation_id` for the devices targeted by the message SHOULD be used.
+- If a message is for all the user devices, all the `installation_id` known to the client MAY be used.
- The number of devices MAY be capped in order to reduce resource consumption.
- At least 3 devices SHOULD be targeted, ordered by last activity.
- For any device that a token is available, or that a token is successfully queried, a push notification message SHOULD be sent to the corresponding push notification server.
@@ -284,13 +282,13 @@ message PushNotificationRequest {
```
### Handle Notification Request
-- A `PushNotificationRequest` message MUST be wrapped in a `ApplicationMetadataMessage` with type set to `PUSH_NOTIFICATION_REQUEST`.
-- Where message is the encrypted payload of the message and `chat_id` is the `SHAKE-256` of the `chat_id`. `message_id` is the id of the message author is the `SHAKE-256` of the public key of the sender.
+- A `PushNotificationRequest` message MUST be wrapped in a [`ApplicationMetadataMessage`](https://specs.status.im/spec/6) with type set to `PUSH_NOTIFICATION_REQUEST`.
+- Where `message` is the encrypted payload of the message and `chat_id` is the `SHAKE-256` of the `chat_id`. `message_id` is the id of the message `author` is the `SHAKE-256` of the public key of the sender.
- If multiple server are available for a given push notification, only one notification MUST be sent.
- If no response is received a client SHOULD wait at least 3 seconds, after which the request MAY be retried against a different server.
- This message SHOULD be sent using an ephemeral key.
-On receiving the message, the push notification server MUST validate the access token. If the access token is valid, a notification MUST be sent to the gorush instance with the following data:
+On receiving the message, the push notification server MUST validate the access token. If the access token is valid, a notification MUST be sent to the [gorush](https://github.com/appleboy/gorush) instance with the following data:
```yaml
{
@@ -310,7 +308,7 @@ On receiving the message, the push notification server MUST validate the access
```
-Where platform is 1 for IOS and 2 for Firebase, according to the [gorush](https://github.com/appleboy/gorush) documentation.
+Where platform is 1 for IOS and 2 for Firebase, according to the [gorush documentation](https://github.com/appleboy/gorush).
A server MUST return a response message:
@@ -337,13 +335,14 @@ message PushNotificationResponse {
}
```
+Where `message_id` is the `message_id` sent by the client.
+
### Handle Notification Response
-- A PushNotificationResponse message MUST be wrapped in a ApplicationMetadataMessage with type set to PUSH_NOTIFICATION_RESPONSE.
-- Where `message_id` is the `message_id` sent by the client.
--The response MUST be sent on the [partitioned topic][./10-waku-usage.md#partitioned-topic] of the sender and MUST not be encrypted using the secure transport to facilitate the usage of ephemeral keys.
-- If the request is accepted success MUST be set to `true`. Otherwise `success` MUST be set to `false`.
-- If error is `BAD_TOKEN` the client MAY query again the server for the token and retry the request.
-- If error is `INTERNAL_ERROR` the client MAY retry the request.
+- A `PushNotificationResponse` message MUST be wrapped in a [`ApplicationMetadataMessage`](https://specs.status.im/spec/6) with type set to `PUSH_NOTIFICATION_RESPONSE`.
+-The response MUST be sent on the [partitioned topic][./10-waku-usage.md#partitioned-topic] of the sender and MUST not be encrypted using the [secure transport](https://specs.status.im/spec/5) to facilitate the usage of ephemeral keys.
+- If the request is accepted `success` MUST be set to `true`. Otherwise `success` MUST be set to `false`.
+- If `error` is `BAD_TOKEN` the client MAY query again the server for the token and retry the request.
+- If `error` is `INTERNAL_ERROR` the client MAY retry the request.
## Protobuf Description
@@ -353,12 +352,12 @@ message PushNotificationResponse {
DATA DISCLOSED
- Type of device owned by a given user.
- The `FIREBASE` or `APN` push notification token,
-- Hash of the chat_id a user is not interested in for notifications,
+- Hash of the `chat_id` a user is not interested in for notifications,
- The times a push notification record has been modified by the user,
- The number of contacts a client has, in case `allowed_key_list` is set.
### PushNotificationRegistrationResponse
-`success`: whether the registration was successful `error`: the error type, if any `request_id`: the `SHAKE-256` hash of the signature of the `request preferences`: the server stored preferences in case of an error.
+`success`: whether the registration was successful `error`: the error type, if any `request_id`: the `SHAKE-256` hash of the `signature` of the request `preferences`: the server stored preferences in case of an error.
### ContactCodeAdvertisement
`push_notification_info`: the information for each device advertised
@@ -373,40 +372,40 @@ DATA DISCLOSED
- The hash of the public keys the client is interested in
### PushNotificationQueryInfo
-`access_token`: the access token used to send a push notification `installation_id`: the `installation_id` of the device associated with the access_token `public_key`: the `SHAKE-256` of the public key associated with this `access_token` and `installation_id`. `allowed_key_list`: a list of encrypted access tokens to be returned to the client in case there’s any filtering on public keys in place. `grant`: the grant used to register with this server. `version`: the version of the registration on the server. `server_public_key`: the compressed public key of the server.
+`access_token`: the access token used to send a push notification `installation_id`: the `installation_id` of the device associated with the `access_token` `public_key`: the `SHAKE-256` of the public key associated with this `access_token` and `installation_id`. `allowed_key_list`: a list of encrypted access tokens to be returned to the client in case there’s any filtering on public keys in place. `grant`: the grant used to register with this server. `version`: the version of the registration on the server. `server_public_key`: the compressed public key of the server.
### PushNotificationQueryResponse
-`info`: a list of PushNotificationQueryInfo. `message_id`: the message id of the `PushNotificationQueryInfo` the server is replying to. `success`: whether the query was successful.
+`info`: a list of `PushNotificationQueryInfo`. `message_id`: the message id of the `PushNotificationQueryInfo` the server is replying to. `success`: whether the query was successful.
### PushNotification
-`access_token`: the access token used to send a push notification. chat_id: the `SHAKE-256` of the chat_id. `public_key`: the `SHAKE-25`6 of the compressed public key of the receiving client. `installation_id`: the installation id of the receiving client. `message`: the encrypted message that is being notified on. `type`: the type of the push notification, either MESSAGE or MENTION `author`: the `SHAKE-256` of the public key of the sender
+`access_token`: the access token used to send a push notification. `chat_id`: the `SHAKE-256` of the `chat_id`. `public_key`: the `SHAKE-256` of the compressed public key of the receiving client. `installation_id`: the `installation_id` of the receiving client. `message`: the encrypted message that is being notified on. `type`: the type of the push notification, either `MESSAGE` or `MENTION` `author`: the `SHAKE-256` of the public key of the sender
Data disclosed
-- The SHAKE-256 of the `chat_id` the notification is to be sent for
+- The `SHAKE-256` of the `chat_id` the notification is to be sent for
- The cypher text of the message
- The `SHAKE-256` of the public key of the sender
- The type of notification
### PushNotificationRequest
-`requests`: a list of PushNotification `message_id`: the status message id
+`requests`: a list of PushNotification `message_id`: the [status message id](https://specs.status.im/spec/6)
Data disclosed
-- The status message id for which the notification is for
+- The status `message_id` for which the notification is for
### PushNotificationResponse
-`message_id`: the `message_id` being notified on. `reports`: a list of PushNotificationReport
+`message_id`: the `message_id` being notified on. `reports`: a list of `PushNotificationReport`.
### PushNotificationReport
-`success`: whether the push notification was successful. `error`: the type of the error in case of failure. `public_key`: the public key of the user being notified. `installation_id`: the installation id of the user being notified.
+`success`: whether the push notification was successful. `error`: the type of the error in case of failure. `public_key`: the public key of the user being notified. `installation_id`: the `installation_id` of the user being notified.
## Anonymous Mode:
In order to preserve privacy, the client MAY provide anonymous mode of operations to propagate information about the user. A client in anonymous mode can register with the server using a key that is different from their chat key. This will hide their real chat key. This public key is effectively a secret and SHOULD only be disclosed to clients approved to notify a user.
-- A client MAY advertise the access token on the contact-code topic of the key generated.
-- A client MAY share their public key contact updates in the protobuf record.
+- A client MAY advertise the access token on the [contact-code topic](https://specs.status.im/spec/6) of the key generated.
+- A client MAY share their public key contact updates in the [protobuf record]().
- A client receiving a push notification public key SHOULD listen to the contact code topic of the push notification public key for updates.
-The method described above effectively does not share the identity of the sender nor the receiver to the server, but MAY result in missing push notifications as the propagation of the secret is left to the client. This can be mitigated by device syncing, but not completely addressed.
+The method described above effectively does not share the identity of the sender nor the receiver to the server, but MAY result in missing push notifications as the propagation of the secret is left to the client. This can be mitigated by [device syncing](https://specs.status.im/spec/6), but not completely addressed.
# Security/Privacy Considerations:
If no anonymous mode is used, when registering with a push notification service a client disclose:
@@ -414,14 +413,14 @@ If no anonymous mode is used, when registering with a push notification service
- The chat key.
A client MAY disclose:
-- The hash of the chat_ids they want to filter out.
+- The hash of the `chat_id` they want to filter out.
When running in anonymous mode, the client’s chat key is not disclosed.
When querying a push notification server a client will disclose:
- That it is interested in sending push notification to another client, but querying client’s chat key is not disclosed.
When sending a push notification a client disclose:
-- The `shake-256` of the chat-id.
+- The `shake-256` of the `chat_id`.
# Copyright
From 7d6e110d579fd1e0c288423abba26ef7c1775c00 Mon Sep 17 00:00:00 2001
From: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Date: Mon, 9 Oct 2023 15:18:50 -0400
Subject: [PATCH 04/67] Update pushNotification.md
---
content/docs/rfcs/pushNotification.md | 47 ++++++++++++++-------------
1 file changed, 24 insertions(+), 23 deletions(-)
diff --git a/content/docs/rfcs/pushNotification.md b/content/docs/rfcs/pushNotification.md
index 4c22e3e87..0b84e4b50 100644
--- a/content/docs/rfcs/pushNotification.md
+++ b/content/docs/rfcs/pushNotification.md
@@ -150,30 +150,31 @@ If `success` is `false`:
## Push Notification Server
A node that handles receiving and sending push notifications for clients.
-### Query Topic
+### Query Topic:
On successful registration the server MUST be listening to the topic derived from:
> `0XHexEncode(Shake256(CompressedClientPublicKey))`
Using the topic derivation algorithm described here and listen for client queries.
-### Server Grant
+
+### Server Grant:
A client needs to authorize a push notification server to send them push notifications. This is done by building a grant which is specific to a given client-server pair. When receiving a grant, the server MUST validate that the signature matches the registering client.
The grant is built as:
> `Signature(Keccak256(CompressedPublicKeyOfClient . CompressedPublicKeyOfServer . AccessToken), PrivateKeyOfClient)`
-### Unregistering with a Server
+### Unregistering with a Server:
- To unregister a client MUST send a `PushNotificationRegistration` request as described above with `unregister` set to `true`, or removing their device information.
- The server MUST remove all data about this user if `unregistering` is `true`, apart from the `hash` of the public key and the `version` of the last options, in order to make sure that old messages are not processed.
- A client MAY unregister from a server on explicit logout if multiple chat keys are used on a single device.
-### Re-registering with a Server
+### Re-registering with a Server:
- A client SHOULD re-register with the node if the APN or FIREBASE token changes.
- When re-registering a client SHOULD ensure that it has the most up-to-date `PushNotificationRegistration` and increment `version` if necessary.
- Once re-registered, a client SHOULD advertise the changes.
Changing options is handled the same as re-registering.
-### Advertising a Server
+### Advertising a Server:
Each user registered with one or more push notification servers SHOULD advertise periodically the push notification services that they have registered with for each device they own.
```protobuf
@@ -200,7 +201,7 @@ message ContactCodeAdvertisement {
- Every time a user register or re-register with a push notification service, their contact-code SHOULD be re-advertised.
- Multiple servers MAY be advertised for the same installation_id for redundancy reasons.
-### Discovering a Server
+### Discovering a Server:
To discover a push notification service for a given user, their [contact code topic](https://specs.status.im/spec/10#contact-code-topic) SHOULD be listened to. A mailserver can be queried for the specific topic to retrieve the most up-to-date contact code.
### Querying a Server:
@@ -215,7 +216,7 @@ message PushNotificationQuery {
```
-### Handle Query Message
+### Handle Query Message:
- The message MUST be wrapped in a [`ApplicationMetadataMessage`](https://specs.status.im/spec/6) with type set to `PUSH_NOTIFICATION_QUERY`.
- MUST be sent to the server on the topic derived from the hashed public key of the key we are querying, as described above.
- An ephemeral key SHOULD be used and SHOULD NOT be encrypted using the [secure transport](https://specs.status.im/spec/5).
@@ -241,7 +242,7 @@ message PushNotificationQueryResponse {
```
-### Handle Query Response
+### Handle Query Response:
- A `PushNotificationQueryResponse` message MUST be wrapped in a [`ApplicationMetadataMessage`](https://specs.status.im/spec/6) with type set to `PUSH_NOTIFICATION_QUERY_RESPONSE`.
Otherwise a response MUST NOT be sent.
- If `allowed_key_list` is not set `access_token` MUST be set and `allowed_key_list` MUST NOT be set.
@@ -281,7 +282,7 @@ message PushNotificationRequest {
}
```
-### Handle Notification Request
+### Handle Notification Request:
- A `PushNotificationRequest` message MUST be wrapped in a [`ApplicationMetadataMessage`](https://specs.status.im/spec/6) with type set to `PUSH_NOTIFICATION_REQUEST`.
- Where `message` is the encrypted payload of the message and `chat_id` is the `SHAKE-256` of the `chat_id`. `message_id` is the id of the message `author` is the `SHAKE-256` of the public key of the sender.
- If multiple server are available for a given push notification, only one notification MUST be sent.
@@ -337,7 +338,7 @@ message PushNotificationResponse {
```
Where `message_id` is the `message_id` sent by the client.
-### Handle Notification Response
+### Handle Notification Response:
- A `PushNotificationResponse` message MUST be wrapped in a [`ApplicationMetadataMessage`](https://specs.status.im/spec/6) with type set to `PUSH_NOTIFICATION_RESPONSE`.
-The response MUST be sent on the [partitioned topic][./10-waku-usage.md#partitioned-topic] of the sender and MUST not be encrypted using the [secure transport](https://specs.status.im/spec/5) to facilitate the usage of ephemeral keys.
- If the request is accepted `success` MUST be set to `true`. Otherwise `success` MUST be set to `false`.
@@ -346,38 +347,38 @@ Where `message_id` is the `message_id` sent by the client.
## Protobuf Description
-### PushNotificationRegistration
+### PushNotificationRegistration:
`token_type`: the type of token. Currently supported is `APN_TOKEN` for Apple Push `device_token`: the actual push notification token sent by `Firebase` or `APN` and `FIREBASE_TOKEN` for firebase. `installation_id`: the `installation_id` of the device `access_token`: the access token that will be given to clients to send push notifications `enabled`: whether the device wants to be sent push notifications `version`: a monotonically increasing number identifying the current `PushNotificationRegistration`. Any time anything is changed in the record it MUST be increased by the client, otherwise the request will not be accepted. `allowed_key_list`: a list of `access_token` encrypted with the AES key generated by Diffie–Hellman between the publisher and the allowed contact. `blocked_chat_list`: a list of `SHA2-256` hashes of chat ids. Any chat id in this list will not trigger a notification. `unregister`: whether the account should be unregistered `grant`: the grant for this specific server `allow_from_contacts_only`: whether the client only wants push notifications from contacts `apn_topic`: the APN topic for the push notification `block_mentions`: whether the client does not want to be notified on mentions `allowed_mentions_chat_list`: a list of SHA2-256 hashes of chat ids where we want to receive mentions
DATA DISCLOSED
- Type of device owned by a given user.
- The `FIREBASE` or `APN` push notification token,
- Hash of the `chat_id` a user is not interested in for notifications,
-- The times a push notification record has been modified by the user,
+- The number of times a push notification record has been modified by the user,
- The number of contacts a client has, in case `allowed_key_list` is set.
-### PushNotificationRegistrationResponse
+### PushNotificationRegistrationResponse:
`success`: whether the registration was successful `error`: the error type, if any `request_id`: the `SHAKE-256` hash of the `signature` of the request `preferences`: the server stored preferences in case of an error.
-### ContactCodeAdvertisement
+### ContactCodeAdvertisement:
`push_notification_info`: the information for each device advertised
DATA DISCLOSED
- The chat key of the sender
-### PushNotificationQuery
+### PushNotificationQuery:
`public_keys`: the `SHAKE-256` of the public keys the client is interested in
DATA DISCLOSED
- The hash of the public keys the client is interested in
-### PushNotificationQueryInfo
+### PushNotificationQueryInfo:
`access_token`: the access token used to send a push notification `installation_id`: the `installation_id` of the device associated with the `access_token` `public_key`: the `SHAKE-256` of the public key associated with this `access_token` and `installation_id`. `allowed_key_list`: a list of encrypted access tokens to be returned to the client in case there’s any filtering on public keys in place. `grant`: the grant used to register with this server. `version`: the version of the registration on the server. `server_public_key`: the compressed public key of the server.
-### PushNotificationQueryResponse
+### PushNotificationQueryResponse:
`info`: a list of `PushNotificationQueryInfo`. `message_id`: the message id of the `PushNotificationQueryInfo` the server is replying to. `success`: whether the query was successful.
-### PushNotification
+### PushNotification:
`access_token`: the access token used to send a push notification. `chat_id`: the `SHAKE-256` of the `chat_id`. `public_key`: the `SHAKE-256` of the compressed public key of the receiving client. `installation_id`: the `installation_id` of the receiving client. `message`: the encrypted message that is being notified on. `type`: the type of the push notification, either `MESSAGE` or `MENTION` `author`: the `SHAKE-256` of the public key of the sender
Data disclosed
@@ -386,19 +387,19 @@ Data disclosed
- The `SHAKE-256` of the public key of the sender
- The type of notification
-### PushNotificationRequest
+### PushNotificationRequest:
`requests`: a list of PushNotification `message_id`: the [status message id](https://specs.status.im/spec/6)
Data disclosed
- The status `message_id` for which the notification is for
-### PushNotificationResponse
+### PushNotificationResponse:
`message_id`: the `message_id` being notified on. `reports`: a list of `PushNotificationReport`.
-### PushNotificationReport
+### PushNotificationReport:
`success`: whether the push notification was successful. `error`: the type of the error in case of failure. `public_key`: the public key of the user being notified. `installation_id`: the `installation_id` of the user being notified.
-## Anonymous Mode:
+## Anonymous Mode
In order to preserve privacy, the client MAY provide anonymous mode of operations to propagate information about the user. A client in anonymous mode can register with the server using a key that is different from their chat key. This will hide their real chat key. This public key is effectively a secret and SHOULD only be disclosed to clients approved to notify a user.
- A client MAY advertise the access token on the [contact-code topic](https://specs.status.im/spec/6) of the key generated.
@@ -407,7 +408,7 @@ In order to preserve privacy, the client MAY provide anonymous mode of operation
The method described above effectively does not share the identity of the sender nor the receiver to the server, but MAY result in missing push notifications as the propagation of the secret is left to the client. This can be mitigated by [device syncing](https://specs.status.im/spec/6), but not completely addressed.
-# Security/Privacy Considerations:
+# Security/Privacy Considerations
If no anonymous mode is used, when registering with a push notification service a client disclose:
- The devices that will receive notifications.
- The chat key.
From d4807496ae94d3c7322ae02c2e5e77ab84cdf48c Mon Sep 17 00:00:00 2001
From: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Date: Mon, 9 Oct 2023 20:54:07 -0400
Subject: [PATCH 05/67] Update pushNotification.md
---
content/docs/rfcs/pushNotification.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/content/docs/rfcs/pushNotification.md b/content/docs/rfcs/pushNotification.md
index 0b84e4b50..fbfc04c57 100644
--- a/content/docs/rfcs/pushNotification.md
+++ b/content/docs/rfcs/pushNotification.md
@@ -9,7 +9,7 @@ editor: Jimmy Debe
# Abstract
-Push notification server implementation for IOS devices and Android devices. This specification provide a is a set of methods that allow clients to use push notification services in mobile environments.
+Push notification server implementation for IOS devices and Android devices. This specification provide a set of methods that allow clients to use push notification services in mobile environments.
# Background
From 54d00f4f607a6eda1ae15378fbbfeb0ffee01548 Mon Sep 17 00:00:00 2001
From: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Date: Mon, 9 Oct 2023 20:55:46 -0400
Subject: [PATCH 06/67] Update pushNotification.md
---
content/docs/rfcs/pushNotification.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/content/docs/rfcs/pushNotification.md b/content/docs/rfcs/pushNotification.md
index fbfc04c57..481b6126f 100644
--- a/content/docs/rfcs/pushNotification.md
+++ b/content/docs/rfcs/pushNotification.md
@@ -194,7 +194,7 @@ message ContactCodeAdvertisement {
```
-### Handle Advertisment Message:
+### Handle Advertisement Message:
- The message MUST be wrapped in a [`ApplicationMetadataMessage`](https://specs.status.im/spec/6) with type set to `PUSH_NOTIFICATION_QUERY_INFO`.
- If no filtering is done based on public keys, the access token SHOULD be included in the advertisement. Otherwise it SHOULD be left empty.
- This SHOULD be advertised on the [contact code topic](https://specs.status.im/spec/10#contact-code-topic) and SHOULD be coupled with normal contact-code advertisement.
From 3f98728acbea9612999f9549b41aba710b414912 Mon Sep 17 00:00:00 2001
From: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Date: Tue, 31 Oct 2023 15:53:32 -0400
Subject: [PATCH 07/67] Update and rename content/docs/rfcs/pushNotification.md
to content/docs/rfcs/71/README.md
---
content/docs/rfcs/{pushNotification.md => 71/README.md} | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
rename content/docs/rfcs/{pushNotification.md => 71/README.md} (99%)
diff --git a/content/docs/rfcs/pushNotification.md b/content/docs/rfcs/71/README.md
similarity index 99%
rename from content/docs/rfcs/pushNotification.md
rename to content/docs/rfcs/71/README.md
index 481b6126f..a0866e0c4 100644
--- a/content/docs/rfcs/pushNotification.md
+++ b/content/docs/rfcs/71/README.md
@@ -1,10 +1,11 @@
---
-slug: XX
-title:
-name: Status Push Notification Server
+slug: 71
+title: 71/STATUS-PUSH-NOTIFICATION-SERVER
+name: Push Notification Server
status: raw
category: Standards Track
-editor: Jimmy Debe
+editor: Jimmy Debe
+contributors: Andrea Maria Piana
---
From 56f529b05cde4c6b057a031ffc4408401ca4d213 Mon Sep 17 00:00:00 2001
From: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Date: Tue, 31 Oct 2023 23:13:12 -0400
Subject: [PATCH 08/67] Update README.md
---
content/docs/rfcs/71/README.md | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/content/docs/rfcs/71/README.md b/content/docs/rfcs/71/README.md
index a0866e0c4..d15e0dacf 100644
--- a/content/docs/rfcs/71/README.md
+++ b/content/docs/rfcs/71/README.md
@@ -10,15 +10,16 @@ contributors: Andrea Maria Piana
# Abstract
-Push notification server implementation for IOS devices and Android devices. This specification provide a set of methods that allow clients to use push notification services in mobile environments.
+Push notification server implementation for Android and iOS devices. This specification provides a set of methods that allow clients to use push notification services in mobile environments.
# Background
-Push notifications for iOS and Android devices can only be implemented by relying on [APN](https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/APNSOverview.html#//apple_ref/doc/uid/TP40008194-CH8-SW1), Apple Push Notification, service for iOS or [Firebase](https://firebase.google.com/) for Android.
+Push notification for iOS and Android devices can only be implemented by relying on [APN](https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/APNSOverview.html#//apple_ref/doc/uid/TP40008194-CH8-SW1), Apple Push Notification, service for iOS or [Firebase](https://firebase.google.com/) for Android.
-For some Android devices, foreground services are restricted, requiring a user to grant authorization to applications for foreground notifications. Apple iOS devices, restrict notifications to some internal functions, that not every application can use. Applications on iOS can request execution time when they are in the background. This has limited set of use cases for example, it will not schedule any time if the application was force quit. Requesting execution time is not reponsive enough to implement a push notification system. Status provides a set of push notification services
+For some Android devices, foreground services are restricted, requiring a user to grant authorization to applications to use foreground notifications. Apple iOS devices restrict notifications to a few internal functions that every application can not use. Applications on iOS can request execution time when they are in the background. This has a limited set of use cases for example, it will not schedule any time if the application was force quit. Requesting execution time is not responsive enough to implement a push notification system. Status provides a set of methods to acheive push notification services.
+
+Since this can not be safely implemented in a privacy-preserving manner, clients need to be given an option to opt-in to receive and send push notifications. They are disabled by default.
-Since this can not be safely implemented in a privacy preserving manner, clients need to be given an option to opt-in receiving and sending push notifications. They are disabled by default.
# Specification
The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.
From 91bf1f913948105523fd97a03e73fb48197b4876 Mon Sep 17 00:00:00 2001
From: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Date: Tue, 31 Oct 2023 23:22:00 -0400
Subject: [PATCH 09/67] Update README.md
---
content/docs/rfcs/71/README.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/content/docs/rfcs/71/README.md b/content/docs/rfcs/71/README.md
index d15e0dacf..3a3fb60bd 100644
--- a/content/docs/rfcs/71/README.md
+++ b/content/docs/rfcs/71/README.md
@@ -16,7 +16,7 @@ Push notification server implementation for Android and iOS devices. This specif
Push notification for iOS and Android devices can only be implemented by relying on [APN](https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/APNSOverview.html#//apple_ref/doc/uid/TP40008194-CH8-SW1), Apple Push Notification, service for iOS or [Firebase](https://firebase.google.com/) for Android.
-For some Android devices, foreground services are restricted, requiring a user to grant authorization to applications to use foreground notifications. Apple iOS devices restrict notifications to a few internal functions that every application can not use. Applications on iOS can request execution time when they are in the background. This has a limited set of use cases for example, it will not schedule any time if the application was force quit. Requesting execution time is not responsive enough to implement a push notification system. Status provides a set of methods to acheive push notification services.
+For some Android devices, foreground services are restricted, requiring a user to grant authorization to applications to use foreground notifications. Apple iOS devices restrict notifications to a few internal functions that every application can not use. Applications on iOS can request execution time when they are in the background. This has a limited set of use cases for example, it will not schedule any time if the application was closed with force quit. Requesting execution time is not responsive enough to implement a push notification system. Status provides a set of methods to acheive push notification services.
Since this can not be safely implemented in a privacy-preserving manner, clients need to be given an option to opt-in to receive and send push notifications. They are disabled by default.
@@ -53,7 +53,7 @@ Sending Client
> A client that wants to send push notifications.
Requirements:
-The party releasing the app MUST possess a certificate for the Apple Push Notification service and its has to run a [gorush](https://github.com/appleboy/gorush) publicly accessible server for sending the actual notification. The party releasing the app, Status in this case, needs to run its own [gorush](https://github.com/appleboy/gorush).
+The party releasing the app MUST possess a certificate for the Apple Push Notification service and it MUST run a [gorush](https://github.com/appleboy/gorush) publicly accessible server for sending the actual notification. The party releasing the app MUST run its own [gorush](https://github.com/appleboy/gorush).
From e261d70b23faee9bd45c15b112019086945c6c13 Mon Sep 17 00:00:00 2001
From: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Date: Wed, 1 Nov 2023 01:24:26 -0400
Subject: [PATCH 10/67] Update README.md
---
content/docs/rfcs/71/README.md | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/content/docs/rfcs/71/README.md b/content/docs/rfcs/71/README.md
index 3a3fb60bd..89e51cce5 100644
--- a/content/docs/rfcs/71/README.md
+++ b/content/docs/rfcs/71/README.md
@@ -159,7 +159,7 @@ On successful registration the server MUST be listening to the topic derived fro
Using the topic derivation algorithm described here and listen for client queries.
### Server Grant:
-A client needs to authorize a push notification server to send them push notifications. This is done by building a grant which is specific to a given client-server pair. When receiving a grant, the server MUST validate that the signature matches the registering client.
+A client MUST authorize a push notification server to send them push notifications. This is done by building a grant which is specific to a given client-server pair. When receiving a grant, the server MUST validate that the signature matches the registering client.
The grant is built as:
> `Signature(Keccak256(CompressedPublicKeyOfClient . CompressedPublicKeyOfServer . AccessToken), PrivateKeyOfClient)`
@@ -200,7 +200,7 @@ message ContactCodeAdvertisement {
- The message MUST be wrapped in a [`ApplicationMetadataMessage`](https://specs.status.im/spec/6) with type set to `PUSH_NOTIFICATION_QUERY_INFO`.
- If no filtering is done based on public keys, the access token SHOULD be included in the advertisement. Otherwise it SHOULD be left empty.
- This SHOULD be advertised on the [contact code topic](https://specs.status.im/spec/10#contact-code-topic) and SHOULD be coupled with normal contact-code advertisement.
-- Every time a user register or re-register with a push notification service, their contact-code SHOULD be re-advertised.
+- When a user register or re-register with a push notification service, their contact-code SHOULD be re-advertised.
- Multiple servers MAY be advertised for the same installation_id for redundancy reasons.
### Discovering a Server:
@@ -220,7 +220,7 @@ message PushNotificationQuery {
### Handle Query Message:
- The message MUST be wrapped in a [`ApplicationMetadataMessage`](https://specs.status.im/spec/6) with type set to `PUSH_NOTIFICATION_QUERY`.
-- MUST be sent to the server on the topic derived from the hashed public key of the key we are querying, as described above.
+- it MUST be sent to the server on the topic derived from the hashed public key of the key we are querying, [as described above](###query-topic).
- An ephemeral key SHOULD be used and SHOULD NOT be encrypted using the [secure transport](https://specs.status.im/spec/5).
If the server has information about the client a response MUST be sent:
@@ -311,7 +311,7 @@ On receiving the message, the push notification server MUST validate the access
```
-Where platform is 1 for IOS and 2 for Firebase, according to the [gorush documentation](https://github.com/appleboy/gorush).
+Where platform is 1 for iOS and 2 for Firebase, according to the [gorush documentation](https://github.com/appleboy/gorush).
A server MUST return a response message:
From a59cbc01452aa3676dc7cb4412e684306c83e3fd Mon Sep 17 00:00:00 2001
From: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Date: Wed, 1 Nov 2023 01:31:11 -0400
Subject: [PATCH 11/67] Update README.md
---
content/docs/rfcs/71/README.md | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/content/docs/rfcs/71/README.md b/content/docs/rfcs/71/README.md
index 89e51cce5..d8bd6f40d 100644
--- a/content/docs/rfcs/71/README.md
+++ b/content/docs/rfcs/71/README.md
@@ -146,7 +146,7 @@ If `success` is `false`:
- If any other error occurs the `error` SHOULD be set to `INTERNAL_ERROR`.
- If the response is successful `success` MUST be set to `true` otherwise a response MUST be sent with `success` set to `false`.
- `request_id` SHOULD be set to the `SHAKE-256` of the encrypted payload.
-- The response MUST be sent on the [partitioned topic][./10-waku-usage.md#partitioned-topic] of the sender and MUST not be encrypted using the secure transport to facilitate the usage of ephemeral keys.
+- The response MUST be sent on the [partitioned topic](https://specs.status.im/spec/10#partitioned-topic) of the sender and MUST not be encrypted using the secure transport to facilitate the usage of ephemeral keys.
- If no response is returned, the request SHOULD be considered failed and MAY be retried with the same server or a different one, but clients MUST exponentially backoff after each trial.
## Push Notification Server
@@ -342,7 +342,7 @@ Where `message_id` is the `message_id` sent by the client.
### Handle Notification Response:
- A `PushNotificationResponse` message MUST be wrapped in a [`ApplicationMetadataMessage`](https://specs.status.im/spec/6) with type set to `PUSH_NOTIFICATION_RESPONSE`.
--The response MUST be sent on the [partitioned topic][./10-waku-usage.md#partitioned-topic] of the sender and MUST not be encrypted using the [secure transport](https://specs.status.im/spec/5) to facilitate the usage of ephemeral keys.
+-The response MUST be sent on the [partitioned topic](https://specs.status.im/spec/10#partitioned-topic) of the sender and MUST not be encrypted using the [secure transport](https://specs.status.im/spec/5) to facilitate the usage of ephemeral keys.
- If the request is accepted `success` MUST be set to `true`. Otherwise `success` MUST be set to `false`.
- If `error` is `BAD_TOKEN` the client MAY query again the server for the token and retry the request.
- If `error` is `INTERNAL_ERROR` the client MAY retry the request.
@@ -405,7 +405,7 @@ Data disclosed
In order to preserve privacy, the client MAY provide anonymous mode of operations to propagate information about the user. A client in anonymous mode can register with the server using a key that is different from their chat key. This will hide their real chat key. This public key is effectively a secret and SHOULD only be disclosed to clients approved to notify a user.
- A client MAY advertise the access token on the [contact-code topic](https://specs.status.im/spec/6) of the key generated.
-- A client MAY share their public key contact updates in the [protobuf record]().
+- A client MAY share their public key contact updates in the [protobuf record](https://developers.google.com/protocol-buffers/).
- A client receiving a push notification public key SHOULD listen to the contact code topic of the push notification public key for updates.
The method described above effectively does not share the identity of the sender nor the receiver to the server, but MAY result in missing push notifications as the propagation of the secret is left to the client. This can be mitigated by [device syncing](https://specs.status.im/spec/6), but not completely addressed.
From ff67c9c1e33e7872b0db08db7c53b7617248a2b5 Mon Sep 17 00:00:00 2001
From: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Date: Wed, 1 Nov 2023 13:39:15 -0400
Subject: [PATCH 12/67] Update content/docs/rfcs/71/README.md
Co-authored-by: Aaryamann Challani <43716372+rymnc@users.noreply.github.com>
---
content/docs/rfcs/71/README.md | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/content/docs/rfcs/71/README.md b/content/docs/rfcs/71/README.md
index d8bd6f40d..680395538 100644
--- a/content/docs/rfcs/71/README.md
+++ b/content/docs/rfcs/71/README.md
@@ -5,7 +5,8 @@ name: Push Notification Server
status: raw
category: Standards Track
editor: Jimmy Debe
-contributors: Andrea Maria Piana
+contributors:
+ - Andrea Maria Piana
---
From 5bc29981736fbf135d84b620fb0cf1bb7f30baef Mon Sep 17 00:00:00 2001
From: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Date: Wed, 1 Nov 2023 13:50:36 -0400
Subject: [PATCH 13/67] Update content/docs/rfcs/71/README.md
Co-authored-by: Aaryamann Challani <43716372+rymnc@users.noreply.github.com>
---
content/docs/rfcs/71/README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/content/docs/rfcs/71/README.md b/content/docs/rfcs/71/README.md
index 680395538..ae891a265 100644
--- a/content/docs/rfcs/71/README.md
+++ b/content/docs/rfcs/71/README.md
@@ -155,7 +155,7 @@ A node that handles receiving and sending push notifications for clients.
### Query Topic:
On successful registration the server MUST be listening to the topic derived from:
- > `0XHexEncode(Shake256(CompressedClientPublicKey))`
+ > `0x` + HexEncode(Shake256(CompressedClientPublicKey))
Using the topic derivation algorithm described here and listen for client queries.
From d9369aaed3c9123873680fcd7652be86cae735b5 Mon Sep 17 00:00:00 2001
From: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Date: Wed, 1 Nov 2023 13:50:53 -0400
Subject: [PATCH 14/67] Update content/docs/rfcs/71/README.md
Co-authored-by: Aaryamann Challani <43716372+rymnc@users.noreply.github.com>
---
content/docs/rfcs/71/README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/content/docs/rfcs/71/README.md b/content/docs/rfcs/71/README.md
index ae891a265..70b8bd073 100644
--- a/content/docs/rfcs/71/README.md
+++ b/content/docs/rfcs/71/README.md
@@ -385,7 +385,7 @@ DATA DISCLOSED
`access_token`: the access token used to send a push notification. `chat_id`: the `SHAKE-256` of the `chat_id`. `public_key`: the `SHAKE-256` of the compressed public key of the receiving client. `installation_id`: the `installation_id` of the receiving client. `message`: the encrypted message that is being notified on. `type`: the type of the push notification, either `MESSAGE` or `MENTION` `author`: the `SHAKE-256` of the public key of the sender
Data disclosed
-- The `SHAKE-256` of the `chat_id` the notification is to be sent for
+- The `SHAKE-256` hash of the `chat_id` the notification is to be sent for
- The cypher text of the message
- The `SHAKE-256` of the public key of the sender
- The type of notification
From 0f6b38d1ddfd782e536f06fa2292e6586e984306 Mon Sep 17 00:00:00 2001
From: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Date: Wed, 1 Nov 2023 13:51:07 -0400
Subject: [PATCH 15/67] Update content/docs/rfcs/71/README.md
Co-authored-by: Aaryamann Challani <43716372+rymnc@users.noreply.github.com>
---
content/docs/rfcs/71/README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/content/docs/rfcs/71/README.md b/content/docs/rfcs/71/README.md
index 70b8bd073..e03b8dd5b 100644
--- a/content/docs/rfcs/71/README.md
+++ b/content/docs/rfcs/71/README.md
@@ -391,7 +391,7 @@ Data disclosed
- The type of notification
### PushNotificationRequest:
-`requests`: a list of PushNotification `message_id`: the [status message id](https://specs.status.im/spec/6)
+`requests`: a list of PushNotification `message_id`: the [Status message id](https://specs.status.im/spec/6)
Data disclosed
- The status `message_id` for which the notification is for
From 7651f85e5e3d1c41afca7a3ef96faf877b2c7086 Mon Sep 17 00:00:00 2001
From: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Date: Wed, 1 Nov 2023 13:51:26 -0400
Subject: [PATCH 16/67] Update content/docs/rfcs/71/README.md
Co-authored-by: Aaryamann Challani <43716372+rymnc@users.noreply.github.com>
---
content/docs/rfcs/71/README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/content/docs/rfcs/71/README.md b/content/docs/rfcs/71/README.md
index e03b8dd5b..7f72b2b43 100644
--- a/content/docs/rfcs/71/README.md
+++ b/content/docs/rfcs/71/README.md
@@ -412,7 +412,7 @@ In order to preserve privacy, the client MAY provide anonymous mode of operation
The method described above effectively does not share the identity of the sender nor the receiver to the server, but MAY result in missing push notifications as the propagation of the secret is left to the client. This can be mitigated by [device syncing](https://specs.status.im/spec/6), but not completely addressed.
# Security/Privacy Considerations
-If no anonymous mode is used, when registering with a push notification service a client disclose:
+If anonymous mode is not used, when registering with a push notification service a client discloses:
- The devices that will receive notifications.
- The chat key.
From 5ee2f79eb123cbf3736a704a57f3eafaf16cc336 Mon Sep 17 00:00:00 2001
From: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Date: Wed, 1 Nov 2023 13:51:45 -0400
Subject: [PATCH 17/67] Update content/docs/rfcs/71/README.md
Co-authored-by: Aaryamann Challani <43716372+rymnc@users.noreply.github.com>
---
content/docs/rfcs/71/README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/content/docs/rfcs/71/README.md b/content/docs/rfcs/71/README.md
index 7f72b2b43..a47f86ae4 100644
--- a/content/docs/rfcs/71/README.md
+++ b/content/docs/rfcs/71/README.md
@@ -387,7 +387,7 @@ DATA DISCLOSED
Data disclosed
- The `SHAKE-256` hash of the `chat_id` the notification is to be sent for
- The cypher text of the message
-- The `SHAKE-256` of the public key of the sender
+- The `SHAKE-256` hash of the public key of the sender
- The type of notification
### PushNotificationRequest:
From 07d8d3c517ef4c96544c0ef07507470525751578 Mon Sep 17 00:00:00 2001
From: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Date: Wed, 1 Nov 2023 14:05:31 -0400
Subject: [PATCH 18/67] Update README.md
---
content/docs/rfcs/71/README.md | 10 +++-------
1 file changed, 3 insertions(+), 7 deletions(-)
diff --git a/content/docs/rfcs/71/README.md b/content/docs/rfcs/71/README.md
index a47f86ae4..f49a5ff68 100644
--- a/content/docs/rfcs/71/README.md
+++ b/content/docs/rfcs/71/README.md
@@ -9,19 +9,16 @@ contributors:
- Andrea Maria Piana
---
-
# Abstract
Push notification server implementation for Android and iOS devices. This specification provides a set of methods that allow clients to use push notification services in mobile environments.
# Background
-
Push notification for iOS and Android devices can only be implemented by relying on [APN](https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/APNSOverview.html#//apple_ref/doc/uid/TP40008194-CH8-SW1), Apple Push Notification, service for iOS or [Firebase](https://firebase.google.com/) for Android.
For some Android devices, foreground services are restricted, requiring a user to grant authorization to applications to use foreground notifications. Apple iOS devices restrict notifications to a few internal functions that every application can not use. Applications on iOS can request execution time when they are in the background. This has a limited set of use cases for example, it will not schedule any time if the application was closed with force quit. Requesting execution time is not responsive enough to implement a push notification system. Status provides a set of methods to acheive push notification services.
Since this can not be safely implemented in a privacy-preserving manner, clients need to be given an option to opt-in to receive and send push notifications. They are disabled by default.
-
# Specification
The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.
@@ -56,8 +53,6 @@ Sending Client
Requirements:
The party releasing the app MUST possess a certificate for the Apple Push Notification service and it MUST run a [gorush](https://github.com/appleboy/gorush) publicly accessible server for sending the actual notification. The party releasing the app MUST run its own [gorush](https://github.com/appleboy/gorush).
-
-
## Push Notification Server Flow
### Registration Process:
@@ -67,7 +62,6 @@ The party releasing the app MUST possess a certificate for the Apple Push Notifi
![image](https://github.com/jimstir/rfc/assets/91767824/b2c66ddf-d13a-4373-9e24-8ad2b5955b86)
-
## Registering Client
Registering a client with a push notification service.
@@ -133,6 +127,7 @@ message PushNotificationRegistrationResponse {
}
```
+
A client SHOULD listen for a response sent on the [partitioned topic](https://specs.status.im/spec/10#partitioned-topic) that the key used to register. If success is true the client has registered successfully.
If `success` is `false`:
@@ -165,7 +160,6 @@ A client MUST authorize a push notification server to send them push notificatio
The grant is built as:
> `Signature(Keccak256(CompressedPublicKeyOfClient . CompressedPublicKeyOfServer . AccessToken), PrivateKeyOfClient)`
-
### Unregistering with a Server:
- To unregister a client MUST send a `PushNotificationRegistration` request as described above with `unregister` set to `true`, or removing their device information.
- The server MUST remove all data about this user if `unregistering` is `true`, apart from the `hash` of the public key and the `version` of the last options, in order to make sure that old messages are not processed.
@@ -339,6 +333,7 @@ message PushNotificationResponse {
}
```
+
Where `message_id` is the `message_id` sent by the client.
### Handle Notification Response:
@@ -435,3 +430,4 @@ Copyright and related rights waived via [CC0](https://creativecommons.org/public
+
From f2537fd3b9e5bb4b9e63c11e0f1d106a1f493661 Mon Sep 17 00:00:00 2001
From: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Date: Wed, 1 Nov 2023 14:09:40 -0400
Subject: [PATCH 19/67] Add Status spec link
---
content/docs/rfcs/71/README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/content/docs/rfcs/71/README.md b/content/docs/rfcs/71/README.md
index f49a5ff68..2d76b27e2 100644
--- a/content/docs/rfcs/71/README.md
+++ b/content/docs/rfcs/71/README.md
@@ -25,7 +25,7 @@ The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL
### Definitions:
client
-> A node that implements the Status specification.
+> A node that implements the [Status specification](https://specs.status.im/spec/1).
user
> The owner of a device that runs a client.
From 7ca9747aef48c5835e1a8fa77640c6506dedb2ea Mon Sep 17 00:00:00 2001
From: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Date: Mon, 6 Nov 2023 19:35:06 -0500
Subject: [PATCH 20/67] Removed mailserver, added some references
---
content/docs/rfcs/71/README.md | 81 ++++++++++++++++++++++++++++++----
1 file changed, 73 insertions(+), 8 deletions(-)
diff --git a/content/docs/rfcs/71/README.md b/content/docs/rfcs/71/README.md
index 2d76b27e2..fabbff323 100644
--- a/content/docs/rfcs/71/README.md
+++ b/content/docs/rfcs/71/README.md
@@ -33,9 +33,6 @@ user
server
> A service that performs push notifications.
-mailserver
-> A Waku node that provides functionality to store messages permanently and deliver the messages to requesting clients.
-
### Components:
gorush Instance
@@ -63,13 +60,16 @@ The party releasing the app MUST possess a certificate for the Apple Push Notifi
![image](https://github.com/jimstir/rfc/assets/91767824/b2c66ddf-d13a-4373-9e24-8ad2b5955b86)
## Registering Client
-
Registering a client with a push notification service.
- A client MAY register with one or more push notification services in order to increase availability.
+
- A client SHOULD make sure that all the notification services they registered with have the same information about their tokens.
+
- A `PNR message` (Push Notification Registration) MUST be sent to the [partitioned topic](https://specs.status.im/spec/10#partitioned-topic) for the public key of the node, encrypted with this key.
+
- The message MUST be wrapped in a [`ApplicationMetadataMessage`](https://specs.status.im/spec/6) with type set to `PUSH_NOTIFICATION_REGISTRATION`.
+
- The marshaled protobuf payload MUST also be encrypted with AES-GCM using the Diffie–Hellman key generated from the client and server identity. This is done in order to ensure that the extracted key from the signature will be considered invalid if it can’t decrypt the payload.
The content of the message MUST contain the following [protobuf record](https://developers.google.com/protocol-buffers/):
@@ -100,13 +100,21 @@ message PushNotificationRegistration {
A push notification server will handle the message according to the following rules:
- it MUST extract the public key of the sender from the signature and verify that the payload can be decrypted successfully.
+
- it MUST verify that `token_type` is supported.
+
- it MUST verify that `device_token` is non empty.
+
- it MUST verify that `installation_id` is non empty.
+
- it MUST verify that `version` is non-zero and greater than the currently stored version for the public key and `installation_id` of the sender, if any.
+
- it MUST verify that `grant` is non empty and according to the Grant Server specs.
+
- it MUST verify that `access_token` is a valid uuid.
+
- it MUST verify that `apn_topic` is set if token_type is APN_TOKEN.
+
- The message MUST be wrapped in a [`ApplicationMetadataMessage`](https://specs.status.im/spec/6) with type set to `PUSH_NOTIFICATION_REGISTRATION_RESPONSE`.
The payload of the response is:
@@ -136,13 +144,21 @@ If `success` is `false`:
### Handle Errors:
- If the message can’t be decrypted, the message MUST be discarded.
+
- If `token_type` is not supported, a response MUST be sent with `error` set to `UNSUPPORTED_TOKEN_TYPE`.
--If `token`, `installation_id`, `device_tokens`, `version` are empty, a response MUST be sent with `error` set to `MALFORMED_MESSAGE`.
+
+- If `token`, `installation_id`, `device_tokens`, `version` are empty, a response MUST be sent with `error` set to `MALFORMED_MESSAGE`.
+
- If the `version` is equal or less than the currently stored `version`, a response MUST be sent with `error` set to `VERSION_MISMATCH`.
+
- If any other error occurs the `error` SHOULD be set to `INTERNAL_ERROR`.
+
- If the response is successful `success` MUST be set to `true` otherwise a response MUST be sent with `success` set to `false`.
+
- `request_id` SHOULD be set to the `SHAKE-256` of the encrypted payload.
+
- The response MUST be sent on the [partitioned topic](https://specs.status.im/spec/10#partitioned-topic) of the sender and MUST not be encrypted using the secure transport to facilitate the usage of ephemeral keys.
+
- If no response is returned, the request SHOULD be considered failed and MAY be retried with the same server or a different one, but clients MUST exponentially backoff after each trial.
## Push Notification Server
@@ -162,12 +178,16 @@ The grant is built as:
### Unregistering with a Server:
- To unregister a client MUST send a `PushNotificationRegistration` request as described above with `unregister` set to `true`, or removing their device information.
+
- The server MUST remove all data about this user if `unregistering` is `true`, apart from the `hash` of the public key and the `version` of the last options, in order to make sure that old messages are not processed.
+
- A client MAY unregister from a server on explicit logout if multiple chat keys are used on a single device.
### Re-registering with a Server:
- A client SHOULD re-register with the node if the APN or FIREBASE token changes.
+
- When re-registering a client SHOULD ensure that it has the most up-to-date `PushNotificationRegistration` and increment `version` if necessary.
+
- Once re-registered, a client SHOULD advertise the changes.
Changing options is handled the same as re-registering.
@@ -193,13 +213,17 @@ message ContactCodeAdvertisement {
### Handle Advertisement Message:
- The message MUST be wrapped in a [`ApplicationMetadataMessage`](https://specs.status.im/spec/6) with type set to `PUSH_NOTIFICATION_QUERY_INFO`.
+
- If no filtering is done based on public keys, the access token SHOULD be included in the advertisement. Otherwise it SHOULD be left empty.
+
- This SHOULD be advertised on the [contact code topic](https://specs.status.im/spec/10#contact-code-topic) and SHOULD be coupled with normal contact-code advertisement.
+
- When a user register or re-register with a push notification service, their contact-code SHOULD be re-advertised.
+
- Multiple servers MAY be advertised for the same installation_id for redundancy reasons.
### Discovering a Server:
-To discover a push notification service for a given user, their [contact code topic](https://specs.status.im/spec/10#contact-code-topic) SHOULD be listened to. A mailserver can be queried for the specific topic to retrieve the most up-to-date contact code.
+To discover a push notification service for a given user, their [contact code topic](https://specs.status.im/spec/10#contact-code-topic) SHOULD be listened to.
### Querying a Server:
If a token is not present in the latest advertisement for a user, the server SHOULD be queried directly.
@@ -242,19 +266,30 @@ message PushNotificationQueryResponse {
### Handle Query Response:
- A `PushNotificationQueryResponse` message MUST be wrapped in a [`ApplicationMetadataMessage`](https://specs.status.im/spec/6) with type set to `PUSH_NOTIFICATION_QUERY_RESPONSE`.
Otherwise a response MUST NOT be sent.
+
- If `allowed_key_list` is not set `access_token` MUST be set and `allowed_key_list` MUST NOT be set.
+
- If `allowed_key_list` is set `allowed_key_list` MUST be set and `access_token` MUST NOT be set.
+
- If `access_token` is returned, the `access_token` SHOULD be used to send push notifications.
+
- If `allowed_key_list` are returned, the client SHOULD decrypt each token by generating an `AES-GCM` symmetric key from the Diffie–Hellman between the target client and itself If AES decryption succeeds it will return a valid `uuid` which is what is used for access_token. The token SHOULD be used to send push notifications.
+
- The response MUST be sent on the [partitioned topic](https://specs.status.im/spec/10#partitioned-topic) of the sender and MUST NOT be encrypted using the [secure transport](https://specs.status.im/spec/5) to facilitate the usage of ephemeral keys.
+
- On receiving a response a client MUST verify `grant` to ensure that the server has been authorized to send push notification to a given client.
## Sending Client
Sending a push notification
+
- When sending a push notification, only the `installation_id` for the devices targeted by the message SHOULD be used.
+
- If a message is for all the user devices, all the `installation_id` known to the client MAY be used.
+
- The number of devices MAY be capped in order to reduce resource consumption.
+
- At least 3 devices SHOULD be targeted, ordered by last activity.
+
- For any device that a token is available, or that a token is successfully queried, a push notification message SHOULD be sent to the corresponding push notification server.
```protobuf
@@ -281,9 +316,13 @@ message PushNotificationRequest {
```
### Handle Notification Request:
- A `PushNotificationRequest` message MUST be wrapped in a [`ApplicationMetadataMessage`](https://specs.status.im/spec/6) with type set to `PUSH_NOTIFICATION_REQUEST`.
+
- Where `message` is the encrypted payload of the message and `chat_id` is the `SHAKE-256` of the `chat_id`. `message_id` is the id of the message `author` is the `SHAKE-256` of the public key of the sender.
+
- If multiple server are available for a given push notification, only one notification MUST be sent.
+
- If no response is received a client SHOULD wait at least 3 seconds, after which the request MAY be retried against a different server.
+
- This message SHOULD be sent using an ephemeral key.
On receiving the message, the push notification server MUST validate the access token. If the access token is valid, a notification MUST be sent to the [gorush](https://github.com/appleboy/gorush) instance with the following data:
@@ -338,9 +377,13 @@ Where `message_id` is the `message_id` sent by the client.
### Handle Notification Response:
- A `PushNotificationResponse` message MUST be wrapped in a [`ApplicationMetadataMessage`](https://specs.status.im/spec/6) with type set to `PUSH_NOTIFICATION_RESPONSE`.
--The response MUST be sent on the [partitioned topic](https://specs.status.im/spec/10#partitioned-topic) of the sender and MUST not be encrypted using the [secure transport](https://specs.status.im/spec/5) to facilitate the usage of ephemeral keys.
+
+- The response MUST be sent on the [partitioned topic](https://specs.status.im/spec/10#partitioned-topic) of the sender and MUST not be encrypted using the [secure transport](https://specs.status.im/spec/5) to facilitate the usage of ephemeral keys.
+
- If the request is accepted `success` MUST be set to `true`. Otherwise `success` MUST be set to `false`.
+
- If `error` is `BAD_TOKEN` the client MAY query again the server for the token and retry the request.
+
- If `error` is `INTERNAL_ERROR` the client MAY retry the request.
## Protobuf Description
@@ -350,9 +393,13 @@ Where `message_id` is the `message_id` sent by the client.
DATA DISCLOSED
- Type of device owned by a given user.
+
- The `FIREBASE` or `APN` push notification token,
+
- Hash of the `chat_id` a user is not interested in for notifications,
+
- The number of times a push notification record has been modified by the user,
+
- The number of contacts a client has, in case `allowed_key_list` is set.
### PushNotificationRegistrationResponse:
@@ -381,8 +428,11 @@ DATA DISCLOSED
Data disclosed
- The `SHAKE-256` hash of the `chat_id` the notification is to be sent for
+
- The cypher text of the message
+
- The `SHAKE-256` hash of the public key of the sender
+
- The type of notification
### PushNotificationRequest:
@@ -401,14 +451,18 @@ Data disclosed
In order to preserve privacy, the client MAY provide anonymous mode of operations to propagate information about the user. A client in anonymous mode can register with the server using a key that is different from their chat key. This will hide their real chat key. This public key is effectively a secret and SHOULD only be disclosed to clients approved to notify a user.
- A client MAY advertise the access token on the [contact-code topic](https://specs.status.im/spec/6) of the key generated.
+
- A client MAY share their public key contact updates in the [protobuf record](https://developers.google.com/protocol-buffers/).
+
- A client receiving a push notification public key SHOULD listen to the contact code topic of the push notification public key for updates.
The method described above effectively does not share the identity of the sender nor the receiver to the server, but MAY result in missing push notifications as the propagation of the secret is left to the client. This can be mitigated by [device syncing](https://specs.status.im/spec/6), but not completely addressed.
# Security/Privacy Considerations
If anonymous mode is not used, when registering with a push notification service a client discloses:
+
- The devices that will receive notifications.
+
- The chat key.
A client MAY disclose:
@@ -419,6 +473,7 @@ When running in anonymous mode, the client’s chat key is not disclosed.
When querying a push notification server a client will disclose:
- That it is interested in sending push notification to another client, but querying client’s chat key is not disclosed.
When sending a push notification a client disclose:
+
- The `shake-256` of the `chat_id`.
# Copyright
@@ -426,7 +481,17 @@ When sending a push notification a client disclose:
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
# References
-
+1. [16/PUSH-NOTIFICATION-SERVER] Andrea Maria Piana, "16/PUSH-NOTIFICATION-SERVER", < https://github.com/status-im/specs/blob/master/docs/raw/push-notification-server.md>
+2. "Push Notification", Apple Developer
+3. "Firebase" Firebase
+4. "gorush", Appleboy,
+5. [10/WAKU-USAGE] Adam Babik, Corey Petty, Oskar Thorén, Samuel Hawksby-Robinson, “10/WAKU-USAGE”, May 22, 2020,
+6. [62/PAYLOAD] Adam Babik, Andrea Maria Piana, Oskar Thorén, "/spec/62/
+7. "Protocol Buffers",
+8. [5/SECURE-TRANSPORT] Andrea Piana, Pedro Pombeiro, Corey Petty, Oskar Thorén, Dean Eigenmann, "5/SECURE-TRANSPORT", May 22, 2020,
+9. [1/CLIENT] Adam Babik, Andrea Maria Piana, Dean Eigenmann, Corey Petty, Oskar Thorén, Samuel Hawksby-Robinson, “1/CLIENT”, May 22, 2020,
+10.
+11. [62/PAYLOAD] Adam Babik, Andrea Maria Piana, Oskar Thorén,
From 0ea85b89c5958366d52323396cf193a85df34df3 Mon Sep 17 00:00:00 2001
From: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Date: Tue, 7 Nov 2023 07:58:24 -0500
Subject: [PATCH 21/67] Update README.md
---
content/docs/rfcs/71/README.md | 32 +++++++++++++++++++++++---------
1 file changed, 23 insertions(+), 9 deletions(-)
diff --git a/content/docs/rfcs/71/README.md b/content/docs/rfcs/71/README.md
index fabbff323..41524ef63 100644
--- a/content/docs/rfcs/71/README.md
+++ b/content/docs/rfcs/71/README.md
@@ -15,7 +15,11 @@ Push notification server implementation for Android and iOS devices. This specif
# Background
Push notification for iOS and Android devices can only be implemented by relying on [APN](https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/APNSOverview.html#//apple_ref/doc/uid/TP40008194-CH8-SW1), Apple Push Notification, service for iOS or [Firebase](https://firebase.google.com/) for Android.
-For some Android devices, foreground services are restricted, requiring a user to grant authorization to applications to use foreground notifications. Apple iOS devices restrict notifications to a few internal functions that every application can not use. Applications on iOS can request execution time when they are in the background. This has a limited set of use cases for example, it will not schedule any time if the application was closed with force quit. Requesting execution time is not responsive enough to implement a push notification system. Status provides a set of methods to acheive push notification services.
+For some Android devices, foreground services are restricted, requiring a user to grant authorization to applications to use foreground notifications.
+Apple iOS devices restrict notifications to a few internal functions that every application can not use.
+Applications on iOS can request execution time when they are in the background. This has a limited set of use cases for example, it will not schedule any time if the application was closed with force quit.
+Requesting execution time is not responsive enough to implement a push notification system.
+Status provides a set of methods to acheive push notification services.
Since this can not be safely implemented in a privacy-preserving manner, clients need to be given an option to opt-in to receive and send push notifications. They are disabled by default.
@@ -48,7 +52,8 @@ Sending Client
> A client that wants to send push notifications.
Requirements:
-The party releasing the app MUST possess a certificate for the Apple Push Notification service and it MUST run a [gorush](https://github.com/appleboy/gorush) publicly accessible server for sending the actual notification. The party releasing the app MUST run its own [gorush](https://github.com/appleboy/gorush).
+The party releasing the app MUST possess a certificate for the Apple Push Notification service and it MUST run a [gorush](https://github.com/appleboy/gorush) publicly accessible server for sending the actual notification.
+The party releasing the app MUST run its own [gorush](https://github.com/appleboy/gorush).
## Push Notification Server Flow
### Registration Process:
@@ -70,7 +75,8 @@ Registering a client with a push notification service.
- The message MUST be wrapped in a [`ApplicationMetadataMessage`](https://specs.status.im/spec/6) with type set to `PUSH_NOTIFICATION_REGISTRATION`.
-- The marshaled protobuf payload MUST also be encrypted with AES-GCM using the Diffie–Hellman key generated from the client and server identity. This is done in order to ensure that the extracted key from the signature will be considered invalid if it can’t decrypt the payload.
+- The marshaled protobuf payload MUST also be encrypted with AES-GCM using the Diffie–Hellman key generated from the client and server identity.
+This is done in order to ensure that the extracted key from the signature will be considered invalid if it can’t decrypt the payload.
The content of the message MUST contain the following [protobuf record](https://developers.google.com/protocol-buffers/):
@@ -136,7 +142,8 @@ message PushNotificationRegistrationResponse {
```
-A client SHOULD listen for a response sent on the [partitioned topic](https://specs.status.im/spec/10#partitioned-topic) that the key used to register. If success is true the client has registered successfully.
+A client SHOULD listen for a response sent on the [partitioned topic](https://specs.status.im/spec/10#partitioned-topic) that the key used to register.
+If success is true the client has registered successfully.
If `success` is `false`:
> If `MALFORMED_MESSAGE` is returned, the request SHOULD NOT be retried without ensuring that it is correctly formed.
@@ -171,7 +178,9 @@ On successful registration the server MUST be listening to the topic derived fro
Using the topic derivation algorithm described here and listen for client queries.
### Server Grant:
-A client MUST authorize a push notification server to send them push notifications. This is done by building a grant which is specific to a given client-server pair. When receiving a grant, the server MUST validate that the signature matches the registering client.
+A client MUST authorize a push notification server to send them push notifications.
+This is done by building a grant which is specific to a given client-server pair.
+When receiving a grant, the server MUST validate that the signature matches the registering client.
The grant is built as:
> `Signature(Keccak256(CompressedPublicKeyOfClient . CompressedPublicKeyOfServer . AccessToken), PrivateKeyOfClient)`
@@ -214,7 +223,8 @@ message ContactCodeAdvertisement {
### Handle Advertisement Message:
- The message MUST be wrapped in a [`ApplicationMetadataMessage`](https://specs.status.im/spec/6) with type set to `PUSH_NOTIFICATION_QUERY_INFO`.
-- If no filtering is done based on public keys, the access token SHOULD be included in the advertisement. Otherwise it SHOULD be left empty.
+- If no filtering is done based on public keys, the access token SHOULD be included in the advertisement.
+ Otherwise it SHOULD be left empty.
- This SHOULD be advertised on the [contact code topic](https://specs.status.im/spec/10#contact-code-topic) and SHOULD be coupled with normal contact-code advertisement.
@@ -273,7 +283,8 @@ Otherwise a response MUST NOT be sent.
- If `access_token` is returned, the `access_token` SHOULD be used to send push notifications.
-- If `allowed_key_list` are returned, the client SHOULD decrypt each token by generating an `AES-GCM` symmetric key from the Diffie–Hellman between the target client and itself If AES decryption succeeds it will return a valid `uuid` which is what is used for access_token. The token SHOULD be used to send push notifications.
+- If `allowed_key_list` are returned, the client SHOULD decrypt each token by generating an `AES-GCM` symmetric key from the Diffie–Hellman between the target client and itself If AES decryption succeeds it will return a valid `uuid` which is what is used for access_token.
+The token SHOULD be used to send push notifications.
- The response MUST be sent on the [partitioned topic](https://specs.status.im/spec/10#partitioned-topic) of the sender and MUST NOT be encrypted using the [secure transport](https://specs.status.im/spec/5) to facilitate the usage of ephemeral keys.
@@ -448,7 +459,9 @@ Data disclosed
`success`: whether the push notification was successful. `error`: the type of the error in case of failure. `public_key`: the public key of the user being notified. `installation_id`: the `installation_id` of the user being notified.
## Anonymous Mode
-In order to preserve privacy, the client MAY provide anonymous mode of operations to propagate information about the user. A client in anonymous mode can register with the server using a key that is different from their chat key. This will hide their real chat key. This public key is effectively a secret and SHOULD only be disclosed to clients approved to notify a user.
+In order to preserve privacy, the client MAY provide anonymous mode of operations to propagate information about the user.
+A client in anonymous mode can register with the server using a key that is different from their chat key.
+This will hide their real chat key. This public key is effectively a secret and SHOULD only be disclosed to clients approved to notify a user.
- A client MAY advertise the access token on the [contact-code topic](https://specs.status.im/spec/6) of the key generated.
@@ -456,7 +469,8 @@ In order to preserve privacy, the client MAY provide anonymous mode of operation
- A client receiving a push notification public key SHOULD listen to the contact code topic of the push notification public key for updates.
-The method described above effectively does not share the identity of the sender nor the receiver to the server, but MAY result in missing push notifications as the propagation of the secret is left to the client. This can be mitigated by [device syncing](https://specs.status.im/spec/6), but not completely addressed.
+The method described above effectively does not share the identity of the sender nor the receiver to the server, but MAY result in missing push notifications as the propagation of the secret is left to the client.
+This can be mitigated by [device syncing](https://specs.status.im/spec/6), but not completely addressed.
# Security/Privacy Considerations
If anonymous mode is not used, when registering with a push notification service a client discloses:
From 21c606aecbac9d3e655106304dedefb65eba7500 Mon Sep 17 00:00:00 2001
From: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Date: Thu, 9 Nov 2023 22:07:21 -0500
Subject: [PATCH 22/67] Create waku-keystore.md
---
content/docs/rfcs/waku-keystore.md | 128 +++++++++++++++++++++++++++++
1 file changed, 128 insertions(+)
create mode 100644 content/docs/rfcs/waku-keystore.md
diff --git a/content/docs/rfcs/waku-keystore.md b/content/docs/rfcs/waku-keystore.md
new file mode 100644
index 000000000..c2802766a
--- /dev/null
+++ b/content/docs/rfcs/waku-keystore.md
@@ -0,0 +1,128 @@
+---
+slug:
+title: WAKU-KEYSTORE
+name: Waku Keystore
+status: raw
+category: Standards Track
+editor: Jimmy Debe
+contributors:
+---
+
+# Abstract
+Encrypted credentials in JSON format stored in a keystore to securely exchange credentials between peers.
+
+# Summary
+A keystore is a construct that store a peer’s keys. The keys will be encrypted and decrypted based on methods species in the keystore. This specification will introduce how a keystore is constructed.
+
+# Background
+Rate Limit Nullifiers, is a method that uses zero knowledge proofs for anonymous rate-limited for messaging/ signaling frameworks.
+The secure transfer of keys are important in peer to peer messaging applications. The Waku RLN keystore can be used by peers to store credentials securely and exchange credentials anonymously.
+
+# Example of a Waku Keystore
+This is an example of a keystore that is used by a Waku RLN Relay.
+
+```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",
+ },
+ }
+
+```
+# Specification:
+- The keystore MUST be in JSON format:
+-
+
+ ## Header Options:
+- application: string;
+- version: string;
+- appIdentifier: string;
+
+## Credentials:
+- [key: MembershipHash]: nWakuCredential
+
+MembershipHash : Compute MembershipHash
+ - The hash SHOULD be created with three values `membershipContract`, `treeIndex`, `identityCredential`
+
+ Encode
+- Tree Index = Merkle tree filled with identity commitments of peers.
+ COULD be obtained with the leaf_index of identity_commitment.
+ RLN membership tree filled with identity commitments of peers, a data structure that ensures peer registrations.
+### Membership Hash Values
+- membershipContract = (contract - ChainId, contractAddress)
+Peer identity = required by RLN/V1, generate zero-knowlege proof
+- idCommitment: options.identity.IDCommitment
+- idNullifier: options.identity.IDNullifier
+- idSecretHash: options.identity.IDSecretHash
+- idTrapdoor: options.identity.IDTrapdoor
+
+### Peer’s identity is composed of:
+identity_secret: identity_nullifier + identity_trapdoor
+- This hash is created with the poseidonHash Function.
+It is used to obtain the identity commitment of a peer.
+Also used as input for zk proof generation.
+- identity_nullifier = Random 32 byte value used as component for identity_secret generation.
+- identity_trapdoor = Random 32 byte value used as component for identity_secret generation.
+
+identity_secret_hash: poseidonHash(identity_secret)
+- poseidonHash Function = hash function for Zero Knowledge proofs
+identity_commitment: poseidonHash([identiy_secret_hash])
+
+### Waku IdentityCredential (nWakuCredential):
+
+nWakuCredential - follows EIP-2335
+- checksum = Keccak256Hash
+
+EIP Keystore
+- password
+- Secret
+- stubPubKey
+- stubPath
+
+KDF as Pbkdf2kdf
+ crypto: {
+ cipher: eipCrypto.cipher.function;
+ cipherparams: eipCrypto.cipher.params;
+ ciphertext: eipCrypto.cipher.message;
+ kdf: eipkdf.function;
+ kdfparams: eipkdf.params;
+ mac: checksum; located fromEipToCredential
+ }
+
+- cipherFunction = is poseidonHash implementation, Poseidon paper.
+- nWaku uses Keccak256 for hash function
+
+## KDF:
+- KDF, key derivation function, produces a derived key from a base key and other parameters.
+For this specification usesPBKDF2.
+RFC 2898 - Password-Based Cryptography
+- baseKey = password,
+- param = salt value and iteration count) / is used by RLN to for peer encryption
+dklen= length in octets of derived key, MUST be positive integer
+c= iteration count, MUST be positive integer
+prf= Underlying pseudorandom function?
+salt= produces a large set of keys based on the password. Builds the derived key?
+
+## Decryption:
+
+# Security Considerations:
+- Add a password to membership hash creation. Reason:
+
+
From 2b5003f52a44407921f3802ee2bbb6cb9a72854a Mon Sep 17 00:00:00 2001
From: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Date: Thu, 9 Nov 2023 22:13:57 -0500
Subject: [PATCH 23/67] Update waku-keystore.md
From a4ce74936670d2281d8c0ed03e90d7e3e964a45c Mon Sep 17 00:00:00 2001
From: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Date: Fri, 10 Nov 2023 12:18:39 -0500
Subject: [PATCH 24/67] Update and rename
---
content/docs/rfcs/{waku-keystore.md => 72/README.md} | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
rename content/docs/rfcs/{waku-keystore.md => 72/README.md} (94%)
diff --git a/content/docs/rfcs/waku-keystore.md b/content/docs/rfcs/72/README.md
similarity index 94%
rename from content/docs/rfcs/waku-keystore.md
rename to content/docs/rfcs/72/README.md
index c2802766a..f555f93b3 100644
--- a/content/docs/rfcs/waku-keystore.md
+++ b/content/docs/rfcs/72/README.md
@@ -12,11 +12,14 @@ contributors:
Encrypted credentials in JSON format stored in a keystore to securely exchange credentials between peers.
# Summary
-A keystore is a construct that store a peer’s keys. The keys will be encrypted and decrypted based on methods species in the keystore. This specification will introduce how a keystore is constructed.
+A keystore is a construct that store a peer’s keys.
+The keys will be encrypted and decrypted based on methods species in the keystore.
+This specification will introduce how a keystore is constructed.
# Background
Rate Limit Nullifiers, is a method that uses zero knowledge proofs for anonymous rate-limited for messaging/ signaling frameworks.
-The secure transfer of keys are important in peer to peer messaging applications. The Waku RLN keystore can be used by peers to store credentials securely and exchange credentials anonymously.
+The secure transfer of keys are important in peer to peer messaging applications.
+The Waku RLN keystore can be used by peers to store credentials securely and exchange credentials anonymously.
# Example of a Waku Keystore
This is an example of a keystore that is used by a Waku RLN Relay.
From 5838105d626e0e4b97da2fa67d450a3cc7309bc1 Mon Sep 17 00:00:00 2001
From: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Date: Fri, 10 Nov 2023 12:39:19 -0500
Subject: [PATCH 25/67] Delete content/docs/rfcs/71 directory
---
content/docs/rfcs/71/README.md | 512 ---------------------------------
1 file changed, 512 deletions(-)
delete mode 100644 content/docs/rfcs/71/README.md
diff --git a/content/docs/rfcs/71/README.md b/content/docs/rfcs/71/README.md
deleted file mode 100644
index 41524ef63..000000000
--- a/content/docs/rfcs/71/README.md
+++ /dev/null
@@ -1,512 +0,0 @@
----
-slug: 71
-title: 71/STATUS-PUSH-NOTIFICATION-SERVER
-name: Push Notification Server
-status: raw
-category: Standards Track
-editor: Jimmy Debe
-contributors:
- - Andrea Maria Piana
----
-
-# Abstract
-Push notification server implementation for Android and iOS devices. This specification provides a set of methods that allow clients to use push notification services in mobile environments.
-
-# Background
-Push notification for iOS and Android devices can only be implemented by relying on [APN](https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/APNSOverview.html#//apple_ref/doc/uid/TP40008194-CH8-SW1), Apple Push Notification, service for iOS or [Firebase](https://firebase.google.com/) for Android.
-
-For some Android devices, foreground services are restricted, requiring a user to grant authorization to applications to use foreground notifications.
-Apple iOS devices restrict notifications to a few internal functions that every application can not use.
-Applications on iOS can request execution time when they are in the background. This has a limited set of use cases for example, it will not schedule any time if the application was closed with force quit.
-Requesting execution time is not responsive enough to implement a push notification system.
-Status provides a set of methods to acheive push notification services.
-
-Since this can not be safely implemented in a privacy-preserving manner, clients need to be given an option to opt-in to receive and send push notifications. They are disabled by default.
-
-# Specification
-The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.
-
-### Definitions:
-
-client
-> A node that implements the [Status specification](https://specs.status.im/spec/1).
-
-user
-> The owner of a device that runs a client.
-
-server
-> A service that performs push notifications.
-
-### Components:
-
-gorush Instance
-> Only used by push notification servers and MUST be publicly available.
-
-Push Notification Server
-> Used by clients to register for receiving and sending notifications.
-
-Registering Client
-> A client that wants to receive push notifications.
-
-Sending Client
-> A client that wants to send push notifications.
-
-Requirements:
-The party releasing the app MUST possess a certificate for the Apple Push Notification service and it MUST run a [gorush](https://github.com/appleboy/gorush) publicly accessible server for sending the actual notification.
-The party releasing the app MUST run its own [gorush](https://github.com/appleboy/gorush).
-
-## Push Notification Server Flow
-### Registration Process:
-
-![image](https://github.com/jimstir/rfc/assets/91767824/00cae4bf-6eb5-4e7b-9377-3a5d01b041a1)
-
-### Sending and Receiving Notification Process:
-
-![image](https://github.com/jimstir/rfc/assets/91767824/b2c66ddf-d13a-4373-9e24-8ad2b5955b86)
-
-## Registering Client
-Registering a client with a push notification service.
-
-- A client MAY register with one or more push notification services in order to increase availability.
-
-- A client SHOULD make sure that all the notification services they registered with have the same information about their tokens.
-
-- A `PNR message` (Push Notification Registration) MUST be sent to the [partitioned topic](https://specs.status.im/spec/10#partitioned-topic) for the public key of the node, encrypted with this key.
-
-- The message MUST be wrapped in a [`ApplicationMetadataMessage`](https://specs.status.im/spec/6) with type set to `PUSH_NOTIFICATION_REGISTRATION`.
-
-- The marshaled protobuf payload MUST also be encrypted with AES-GCM using the Diffie–Hellman key generated from the client and server identity.
-This is done in order to ensure that the extracted key from the signature will be considered invalid if it can’t decrypt the payload.
-
-The content of the message MUST contain the following [protobuf record](https://developers.google.com/protocol-buffers/):
-
-```protobuf
-message PushNotificationRegistration {
- enum TokenType {
- UNKNOWN_TOKEN_TYPE = 0;
- APN_TOKEN = 1;
- FIREBASE_TOKEN = 2;
- }
- TokenType token_type = 1;
- string device_token = 2;
- string installation_id = 3;
- string access_token = 4;
- bool enabled = 5;
- uint64 version = 6;
- repeated bytes allowed_key_list = 7;
- repeated bytes blocked_chat_list = 8;
- bool unregister = 9;
- bytes grant = 10;
- bool allow_from_contacts_only = 11;
- string apn_topic = 12;
- bool block_mentions = 13;
- repeated bytes allowed_mentions_chat_list = 14;
-}
-```
-
-A push notification server will handle the message according to the following rules:
-- it MUST extract the public key of the sender from the signature and verify that the payload can be decrypted successfully.
-
-- it MUST verify that `token_type` is supported.
-
-- it MUST verify that `device_token` is non empty.
-
-- it MUST verify that `installation_id` is non empty.
-
-- it MUST verify that `version` is non-zero and greater than the currently stored version for the public key and `installation_id` of the sender, if any.
-
-- it MUST verify that `grant` is non empty and according to the Grant Server specs.
-
-- it MUST verify that `access_token` is a valid uuid.
-
-- it MUST verify that `apn_topic` is set if token_type is APN_TOKEN.
-
-- The message MUST be wrapped in a [`ApplicationMetadataMessage`](https://specs.status.im/spec/6) with type set to `PUSH_NOTIFICATION_REGISTRATION_RESPONSE`.
-
-The payload of the response is:
-
-```protobuf
-message PushNotificationRegistrationResponse {
- bool success = 1;
- ErrorType error = 2;
- bytes request_id = 3;
-
- enum ErrorType {
- UNKNOWN_ERROR_TYPE = 0;
- MALFORMED_MESSAGE = 1;
- VERSION_MISMATCH = 2;
- UNSUPPORTED_TOKEN_TYPE = 3;
- INTERNAL_ERROR = 4;
- }
-}
-
-```
-
-A client SHOULD listen for a response sent on the [partitioned topic](https://specs.status.im/spec/10#partitioned-topic) that the key used to register.
-If success is true the client has registered successfully.
-
-If `success` is `false`:
- > If `MALFORMED_MESSAGE` is returned, the request SHOULD NOT be retried without ensuring that it is correctly formed.
- > If `INTERNAL_ERROR` is returned, the request MAY be retried, but the client MUST backoff exponentially.
-
-### Handle Errors:
-- If the message can’t be decrypted, the message MUST be discarded.
-
-- If `token_type` is not supported, a response MUST be sent with `error` set to `UNSUPPORTED_TOKEN_TYPE`.
-
-- If `token`, `installation_id`, `device_tokens`, `version` are empty, a response MUST be sent with `error` set to `MALFORMED_MESSAGE`.
-
-- If the `version` is equal or less than the currently stored `version`, a response MUST be sent with `error` set to `VERSION_MISMATCH`.
-
-- If any other error occurs the `error` SHOULD be set to `INTERNAL_ERROR`.
-
-- If the response is successful `success` MUST be set to `true` otherwise a response MUST be sent with `success` set to `false`.
-
-- `request_id` SHOULD be set to the `SHAKE-256` of the encrypted payload.
-
-- The response MUST be sent on the [partitioned topic](https://specs.status.im/spec/10#partitioned-topic) of the sender and MUST not be encrypted using the secure transport to facilitate the usage of ephemeral keys.
-
-- If no response is returned, the request SHOULD be considered failed and MAY be retried with the same server or a different one, but clients MUST exponentially backoff after each trial.
-
-## Push Notification Server
-A node that handles receiving and sending push notifications for clients.
-
-### Query Topic:
-On successful registration the server MUST be listening to the topic derived from:
- > `0x` + HexEncode(Shake256(CompressedClientPublicKey))
-
-Using the topic derivation algorithm described here and listen for client queries.
-
-### Server Grant:
-A client MUST authorize a push notification server to send them push notifications.
-This is done by building a grant which is specific to a given client-server pair.
-When receiving a grant, the server MUST validate that the signature matches the registering client.
-
-The grant is built as:
- > `Signature(Keccak256(CompressedPublicKeyOfClient . CompressedPublicKeyOfServer . AccessToken), PrivateKeyOfClient)`
-
-### Unregistering with a Server:
-- To unregister a client MUST send a `PushNotificationRegistration` request as described above with `unregister` set to `true`, or removing their device information.
-
-- The server MUST remove all data about this user if `unregistering` is `true`, apart from the `hash` of the public key and the `version` of the last options, in order to make sure that old messages are not processed.
-
-- A client MAY unregister from a server on explicit logout if multiple chat keys are used on a single device.
-
-### Re-registering with a Server:
-- A client SHOULD re-register with the node if the APN or FIREBASE token changes.
-
-- When re-registering a client SHOULD ensure that it has the most up-to-date `PushNotificationRegistration` and increment `version` if necessary.
-
-- Once re-registered, a client SHOULD advertise the changes.
-Changing options is handled the same as re-registering.
-
-### Advertising a Server:
-Each user registered with one or more push notification servers SHOULD advertise periodically the push notification services that they have registered with for each device they own.
-
-```protobuf
-message PushNotificationQueryInfo {
- string access_token = 1;
- string installation_id = 2;
- bytes public_key = 3;
- repeated bytes allowed_user_list = 4;
- bytes grant = 5;
- uint64 version = 6;
- bytes server_public_key = 7;
-}
-
-message ContactCodeAdvertisement {
- repeated PushNotificationQueryInfo push_notification_info = 1;
-}
-
-```
-
-### Handle Advertisement Message:
-- The message MUST be wrapped in a [`ApplicationMetadataMessage`](https://specs.status.im/spec/6) with type set to `PUSH_NOTIFICATION_QUERY_INFO`.
-
-- If no filtering is done based on public keys, the access token SHOULD be included in the advertisement.
- Otherwise it SHOULD be left empty.
-
-- This SHOULD be advertised on the [contact code topic](https://specs.status.im/spec/10#contact-code-topic) and SHOULD be coupled with normal contact-code advertisement.
-
-- When a user register or re-register with a push notification service, their contact-code SHOULD be re-advertised.
-
-- Multiple servers MAY be advertised for the same installation_id for redundancy reasons.
-
-### Discovering a Server:
-To discover a push notification service for a given user, their [contact code topic](https://specs.status.im/spec/10#contact-code-topic) SHOULD be listened to.
-
-### Querying a Server:
-If a token is not present in the latest advertisement for a user, the server SHOULD be queried directly.
-
-To query a server a message:
-
-```protobuf
-message PushNotificationQuery {
- repeated bytes public_keys = 1;
-}
-
-```
-
-### Handle Query Message:
-- The message MUST be wrapped in a [`ApplicationMetadataMessage`](https://specs.status.im/spec/6) with type set to `PUSH_NOTIFICATION_QUERY`.
-- it MUST be sent to the server on the topic derived from the hashed public key of the key we are querying, [as described above](###query-topic).
-- An ephemeral key SHOULD be used and SHOULD NOT be encrypted using the [secure transport](https://specs.status.im/spec/5).
-
-If the server has information about the client a response MUST be sent:
-
-```protobuf
-message PushNotificationQueryInfo {
- string access_token = 1;
- string installation_id = 2;
- bytes public_key = 3;
- repeated bytes allowed_user_list = 4;
- bytes grant = 5;
- uint64 version = 6;
- bytes server_public_key = 7;
-}
-
-message PushNotificationQueryResponse {
- repeated PushNotificationQueryInfo info = 1;
- bytes message_id = 2;
- bool success = 3;
-}
-
-```
-
-### Handle Query Response:
-- A `PushNotificationQueryResponse` message MUST be wrapped in a [`ApplicationMetadataMessage`](https://specs.status.im/spec/6) with type set to `PUSH_NOTIFICATION_QUERY_RESPONSE`.
-Otherwise a response MUST NOT be sent.
-
-- If `allowed_key_list` is not set `access_token` MUST be set and `allowed_key_list` MUST NOT be set.
-
-- If `allowed_key_list` is set `allowed_key_list` MUST be set and `access_token` MUST NOT be set.
-
-- If `access_token` is returned, the `access_token` SHOULD be used to send push notifications.
-
-- If `allowed_key_list` are returned, the client SHOULD decrypt each token by generating an `AES-GCM` symmetric key from the Diffie–Hellman between the target client and itself If AES decryption succeeds it will return a valid `uuid` which is what is used for access_token.
-The token SHOULD be used to send push notifications.
-
-- The response MUST be sent on the [partitioned topic](https://specs.status.im/spec/10#partitioned-topic) of the sender and MUST NOT be encrypted using the [secure transport](https://specs.status.im/spec/5) to facilitate the usage of ephemeral keys.
-
-- On receiving a response a client MUST verify `grant` to ensure that the server has been authorized to send push notification to a given client.
-
-## Sending Client
-Sending a push notification
-
-- When sending a push notification, only the `installation_id` for the devices targeted by the message SHOULD be used.
-
-- If a message is for all the user devices, all the `installation_id` known to the client MAY be used.
-
-- The number of devices MAY be capped in order to reduce resource consumption.
-
-- At least 3 devices SHOULD be targeted, ordered by last activity.
-
-- For any device that a token is available, or that a token is successfully queried, a push notification message SHOULD be sent to the corresponding push notification server.
-
-```protobuf
-message PushNotification {
- string access_token = 1;
- string chat_id = 2;
- bytes public_key = 3;
- string installation_id = 4;
- bytes message = 5;
- PushNotificationType type = 6;
- enum PushNotificationType {
- UNKNOWN_PUSH_NOTIFICATION_TYPE = 0;
- MESSAGE = 1;
- MENTION = 2;
- }
- bytes author = 7;
-}
-
-message PushNotificationRequest {
- repeated PushNotification requests = 1;
- bytes message_id = 2;
-}
-
-```
-### Handle Notification Request:
-- A `PushNotificationRequest` message MUST be wrapped in a [`ApplicationMetadataMessage`](https://specs.status.im/spec/6) with type set to `PUSH_NOTIFICATION_REQUEST`.
-
-- Where `message` is the encrypted payload of the message and `chat_id` is the `SHAKE-256` of the `chat_id`. `message_id` is the id of the message `author` is the `SHAKE-256` of the public key of the sender.
-
-- If multiple server are available for a given push notification, only one notification MUST be sent.
-
-- If no response is received a client SHOULD wait at least 3 seconds, after which the request MAY be retried against a different server.
-
-- This message SHOULD be sent using an ephemeral key.
-
-On receiving the message, the push notification server MUST validate the access token. If the access token is valid, a notification MUST be sent to the [gorush](https://github.com/appleboy/gorush) instance with the following data:
-
-```yaml
-{
- "notifications": [
- {
- "tokens": ["token_a", "token_b"],
- "platform": 1,
- "message": "You have a new message",
- "data": {
- "chat_id": chat_id,
- "message": message,
- "installation_ids": [installation_id_1, installation_id_2]
- }
- }
- ]
-}
-
-```
-
-Where platform is 1 for iOS and 2 for Firebase, according to the [gorush documentation](https://github.com/appleboy/gorush).
-
-A server MUST return a response message:
-
-```protobuf
-message PushNotificationReport {
- bool success = 1;
- ErrorType error = 2;
- enum ErrorType {
- UNKNOWN_ERROR_TYPE = 0;
- WRONG_TOKEN = 1;
- INTERNAL_ERROR = 2;
- NOT_REGISTERED = 3;
- }
- bytes public_key = 3;
- string installation_id = 4;
-}
-
-```
-
-```protobuf
-message PushNotificationResponse {
- bytes message_id = 1;
- repeated PushNotificationReport reports = 2;
-}
-
-```
-
-Where `message_id` is the `message_id` sent by the client.
-
-### Handle Notification Response:
-- A `PushNotificationResponse` message MUST be wrapped in a [`ApplicationMetadataMessage`](https://specs.status.im/spec/6) with type set to `PUSH_NOTIFICATION_RESPONSE`.
-
-- The response MUST be sent on the [partitioned topic](https://specs.status.im/spec/10#partitioned-topic) of the sender and MUST not be encrypted using the [secure transport](https://specs.status.im/spec/5) to facilitate the usage of ephemeral keys.
-
-- If the request is accepted `success` MUST be set to `true`. Otherwise `success` MUST be set to `false`.
-
-- If `error` is `BAD_TOKEN` the client MAY query again the server for the token and retry the request.
-
-- If `error` is `INTERNAL_ERROR` the client MAY retry the request.
-
-## Protobuf Description
-
-### PushNotificationRegistration:
-`token_type`: the type of token. Currently supported is `APN_TOKEN` for Apple Push `device_token`: the actual push notification token sent by `Firebase` or `APN` and `FIREBASE_TOKEN` for firebase. `installation_id`: the `installation_id` of the device `access_token`: the access token that will be given to clients to send push notifications `enabled`: whether the device wants to be sent push notifications `version`: a monotonically increasing number identifying the current `PushNotificationRegistration`. Any time anything is changed in the record it MUST be increased by the client, otherwise the request will not be accepted. `allowed_key_list`: a list of `access_token` encrypted with the AES key generated by Diffie–Hellman between the publisher and the allowed contact. `blocked_chat_list`: a list of `SHA2-256` hashes of chat ids. Any chat id in this list will not trigger a notification. `unregister`: whether the account should be unregistered `grant`: the grant for this specific server `allow_from_contacts_only`: whether the client only wants push notifications from contacts `apn_topic`: the APN topic for the push notification `block_mentions`: whether the client does not want to be notified on mentions `allowed_mentions_chat_list`: a list of SHA2-256 hashes of chat ids where we want to receive mentions
-
-DATA DISCLOSED
-- Type of device owned by a given user.
-
-- The `FIREBASE` or `APN` push notification token,
-
-- Hash of the `chat_id` a user is not interested in for notifications,
-
-- The number of times a push notification record has been modified by the user,
-
-- The number of contacts a client has, in case `allowed_key_list` is set.
-
-### PushNotificationRegistrationResponse:
-`success`: whether the registration was successful `error`: the error type, if any `request_id`: the `SHAKE-256` hash of the `signature` of the request `preferences`: the server stored preferences in case of an error.
-
-### ContactCodeAdvertisement:
-`push_notification_info`: the information for each device advertised
-
-DATA DISCLOSED
-- The chat key of the sender
-
-### PushNotificationQuery:
-`public_keys`: the `SHAKE-256` of the public keys the client is interested in
-
-DATA DISCLOSED
-- The hash of the public keys the client is interested in
-
-### PushNotificationQueryInfo:
-`access_token`: the access token used to send a push notification `installation_id`: the `installation_id` of the device associated with the `access_token` `public_key`: the `SHAKE-256` of the public key associated with this `access_token` and `installation_id`. `allowed_key_list`: a list of encrypted access tokens to be returned to the client in case there’s any filtering on public keys in place. `grant`: the grant used to register with this server. `version`: the version of the registration on the server. `server_public_key`: the compressed public key of the server.
-
-### PushNotificationQueryResponse:
-`info`: a list of `PushNotificationQueryInfo`. `message_id`: the message id of the `PushNotificationQueryInfo` the server is replying to. `success`: whether the query was successful.
-
-### PushNotification:
-`access_token`: the access token used to send a push notification. `chat_id`: the `SHAKE-256` of the `chat_id`. `public_key`: the `SHAKE-256` of the compressed public key of the receiving client. `installation_id`: the `installation_id` of the receiving client. `message`: the encrypted message that is being notified on. `type`: the type of the push notification, either `MESSAGE` or `MENTION` `author`: the `SHAKE-256` of the public key of the sender
-
-Data disclosed
-- The `SHAKE-256` hash of the `chat_id` the notification is to be sent for
-
-- The cypher text of the message
-
-- The `SHAKE-256` hash of the public key of the sender
-
-- The type of notification
-
-### PushNotificationRequest:
-`requests`: a list of PushNotification `message_id`: the [Status message id](https://specs.status.im/spec/6)
-
-Data disclosed
-- The status `message_id` for which the notification is for
-
-### PushNotificationResponse:
-`message_id`: the `message_id` being notified on. `reports`: a list of `PushNotificationReport`.
-
-### PushNotificationReport:
-`success`: whether the push notification was successful. `error`: the type of the error in case of failure. `public_key`: the public key of the user being notified. `installation_id`: the `installation_id` of the user being notified.
-
-## Anonymous Mode
-In order to preserve privacy, the client MAY provide anonymous mode of operations to propagate information about the user.
-A client in anonymous mode can register with the server using a key that is different from their chat key.
-This will hide their real chat key. This public key is effectively a secret and SHOULD only be disclosed to clients approved to notify a user.
-
-- A client MAY advertise the access token on the [contact-code topic](https://specs.status.im/spec/6) of the key generated.
-
-- A client MAY share their public key contact updates in the [protobuf record](https://developers.google.com/protocol-buffers/).
-
-- A client receiving a push notification public key SHOULD listen to the contact code topic of the push notification public key for updates.
-
-The method described above effectively does not share the identity of the sender nor the receiver to the server, but MAY result in missing push notifications as the propagation of the secret is left to the client.
-This can be mitigated by [device syncing](https://specs.status.im/spec/6), but not completely addressed.
-
-# Security/Privacy Considerations
-If anonymous mode is not used, when registering with a push notification service a client discloses:
-
-- The devices that will receive notifications.
-
-- The chat key.
-
-A client MAY disclose:
-- The hash of the `chat_id` they want to filter out.
-
-When running in anonymous mode, the client’s chat key is not disclosed.
-
-When querying a push notification server a client will disclose:
-- That it is interested in sending push notification to another client, but querying client’s chat key is not disclosed.
-When sending a push notification a client disclose:
-
-- The `shake-256` of the `chat_id`.
-
-# Copyright
-
-Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
-
-# References
-1. [16/PUSH-NOTIFICATION-SERVER] Andrea Maria Piana, "16/PUSH-NOTIFICATION-SERVER", < https://github.com/status-im/specs/blob/master/docs/raw/push-notification-server.md>
-2. "Push Notification", Apple Developer
-3. "Firebase" Firebase
-4. "gorush", Appleboy,
-5. [10/WAKU-USAGE] Adam Babik, Corey Petty, Oskar Thorén, Samuel Hawksby-Robinson, “10/WAKU-USAGE”, May 22, 2020,
-6. [62/PAYLOAD] Adam Babik, Andrea Maria Piana, Oskar Thorén, "/spec/62/
-7. "Protocol Buffers",
-8. [5/SECURE-TRANSPORT] Andrea Piana, Pedro Pombeiro, Corey Petty, Oskar Thorén, Dean Eigenmann, "5/SECURE-TRANSPORT", May 22, 2020,
-9. [1/CLIENT] Adam Babik, Andrea Maria Piana, Dean Eigenmann, Corey Petty, Oskar Thorén, Samuel Hawksby-Robinson, “1/CLIENT”, May 22, 2020,
-10.
-11. [62/PAYLOAD] Adam Babik, Andrea Maria Piana, Oskar Thorén,
-
-
-
-
From 3780b73b237f31001c08cb545d25e30f9d2041af Mon Sep 17 00:00:00 2001
From: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Date: Fri, 10 Nov 2023 12:48:46 -0500
Subject: [PATCH 26/67] Update README.md
---
content/docs/rfcs/72/README.md | 3 +++
1 file changed, 3 insertions(+)
diff --git a/content/docs/rfcs/72/README.md b/content/docs/rfcs/72/README.md
index f555f93b3..7322f8c6a 100644
--- a/content/docs/rfcs/72/README.md
+++ b/content/docs/rfcs/72/README.md
@@ -100,6 +100,7 @@ EIP Keystore
- stubPath
KDF as Pbkdf2kdf
+```js
crypto: {
cipher: eipCrypto.cipher.function;
cipherparams: eipCrypto.cipher.params;
@@ -108,6 +109,8 @@ KDF as Pbkdf2kdf
kdfparams: eipkdf.params;
mac: checksum; located fromEipToCredential
}
+
+```
- cipherFunction = is poseidonHash implementation, Poseidon paper.
- nWaku uses Keccak256 for hash function
From 44fdac53bf5f6001c9b6a248380853a7391f90fd Mon Sep 17 00:00:00 2001
From: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Date: Thu, 16 Nov 2023 23:26:13 -0500
Subject: [PATCH 27/67] Update README.md
---
content/docs/rfcs/72/README.md | 44 ++++++++++++++++++----------------
1 file changed, 24 insertions(+), 20 deletions(-)
diff --git a/content/docs/rfcs/72/README.md b/content/docs/rfcs/72/README.md
index 7322f8c6a..539fe582b 100644
--- a/content/docs/rfcs/72/README.md
+++ b/content/docs/rfcs/72/README.md
@@ -1,7 +1,7 @@
---
-slug:
-title: WAKU-KEYSTORE
-name: Waku Keystore
+slug: 72
+title: 72/WAKU-RLN-KEYSTORE
+name: Waku RLN Keystore
status: raw
category: Standards Track
editor: Jimmy Debe
@@ -12,39 +12,43 @@ contributors:
Encrypted credentials in JSON format stored in a keystore to securely exchange credentials between peers.
# Summary
-A keystore is a construct that store a peer’s keys.
-The keys will be encrypted and decrypted based on methods species in the keystore.
-This specification will introduce how a keystore is constructed.
+A keystore is a construct to store a user’s keys.
+The keys will be encrypted and decrypted based on methods specifed in the specification.
+Waku will use RLN as a spam-prevention mechanism that requires zk-proofs generated by users and stored in the keystore.
+The keystore will be stored locally and called by applications.
+
# Background
-Rate Limit Nullifiers, is a method that uses zero knowledge proofs for anonymous rate-limited for messaging/ signaling frameworks.
+A Waku RLN Keystore uses RLN, Rate Limit Nullifiers, which is a method that uses zero knowledge proofs for anonymous rate-limiting for messaging frameworks.
The secure transfer of keys are important in peer to peer messaging applications.
-The Waku RLN keystore can be used by peers to store credentials securely and exchange credentials anonymously.
+RLN will help users receive and send messages from trusted peers/users.
+It will ensure a message rate is being followed in the messaging network and keeping anonymity of the message owner.
+It is a security feature.
+
+The Waku RLN keystore can be used by users to store credentials securely and exchange credentials anonymously.
+
+## Example Waku RLN Keystore:
-# Example of a Waku Keystore
This is an example of a keystore that is used by a Waku RLN Relay.
```js
application: "waku-rln-relay",
- appIdentifier: "01234567890abcdef",
- version: "0.2",
+appIdentifier: "01234567890abcdef",
+version: "0.2",
credentials: {
"9DB2B4718A97485B9F70F68D1CC19F4E10F0B4CE943418838E94956CB8E57548": {
crypto: {
cipher: "aes-128-ctr",
- cipherparams: {
- iv: "fd6b39eb71d44c59f6bf5ff3d8945c80",
- },
- ciphertext:
- "9c72f47ce95de03ed34502d0288e7576b66b51b9e7d5ae882c27bd89f94e6a03c2c44c2ddf0c982e72003d67212105f1b64614f57cabb0ceadab7e07be165eee1121ad6b81951368a9f3be2dd99ea294515f6013d5f2bd4702a40e36cfde2ea298b23b31e5ce719d8040c3331f73d6bf44f88bca39bac0e917d8bf545500e4f40d321c235426a80f315ac70666acbd3bdf803fbc1e7e7103fed466525ed332b25d72b2dbedf6fa383b2305987c1fe276b029570519b3e79930edf08c1029868d05c2c08ab61d7c64f63c054b4f6a5a12d43cdc79751b6fe58d3ed26b69443eb7c9f7efce27912340129c91b6b813ac94efd5776a40b1dda896d61357de208c7c47a14af911cc231355c8093ee6626e89c07e1037f9e0b22c690e3e049014399ca0212c509cb04c71c7860d1b17a0c47711c490c27bad2825926148a1f15a507f36ba2cdaa04897fce2914e53caed0beaf1bebd2a83af76511cc15bff2165ff0860ad6eca1f30022d7739b2a6b6a72f2feeef0f5941183cda015b4631469e1f4cf27003cab9a90920301cb30d95e4554686922dc5a05c13dfb575cdf113c700d607896011970e6ee7d6edb61210ab28ac8f0c84c606c097e3e300f0a5f5341edfd15432bef6225a498726b62a98283829ad51023b2987f30686cfb4ea3951f3957654035ec291f9b0964a3a8665d81b16cec20fb40f944d5f9bf03ac1e444ad45bae3fa85e7465ce620c0966d8148d6e2856f676c4fbbe3ebe470453efb4bbda1866680037917e37765f680e3da96ef3991f3fe5cda80c523996c2234758bf5f7b6d052dc6942f5a92c8b8eec5d2d8940203bbb6b1cba7b7ebc1334334ca69cdb509a5ea58ec6b2ebaea52307589eaae9430eb15ad234c0c39c83accdf3b77e52a616e345209c5bc9b442f9f0fa96836d9342f983a7",
+ cipherparams: { iv: “ “, },
+ ciphertext: "",
kdf: "pbkdf2",
kdfparams: {
- dklen: 32,
- c: 1000000,
+ dklen: interger,
+ c: interger,
prf: "hmac-sha256",
- salt: "60f0aa92fbf63a8356dfdbed2ab18058",
+ salt: "hash",
},
- mac: "51a227ac6db7f2797c63925880b3db664e034231a4c68daa919ab42d8df38bc6",
+ mac: “Byte 256 Hash",
},
}
From 1c2cb23644887670fb5cffc26de4d15c080ce7e7 Mon Sep 17 00:00:00 2001
From: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Date: Thu, 16 Nov 2023 23:27:31 -0500
Subject: [PATCH 28/67] Update README.md
---
content/docs/rfcs/72/README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/content/docs/rfcs/72/README.md b/content/docs/rfcs/72/README.md
index 539fe582b..271933bb9 100644
--- a/content/docs/rfcs/72/README.md
+++ b/content/docs/rfcs/72/README.md
@@ -9,7 +9,7 @@ contributors:
---
# Abstract
-Encrypted credentials in JSON format stored in a keystore to securely exchange credentials between peers.
+Encrypted credentials stored in a JSON schema to securely exchange credentials between peers.
# Summary
A keystore is a construct to store a user’s keys.
From 7d92cf18ce02473cc5735c869153f4337757fce9 Mon Sep 17 00:00:00 2001
From: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Date: Thu, 16 Nov 2023 23:33:22 -0500
Subject: [PATCH 29/67] Update README.md
---
content/docs/rfcs/72/README.md | 14 +++++---------
1 file changed, 5 insertions(+), 9 deletions(-)
diff --git a/content/docs/rfcs/72/README.md b/content/docs/rfcs/72/README.md
index 271933bb9..e82ccea57 100644
--- a/content/docs/rfcs/72/README.md
+++ b/content/docs/rfcs/72/README.md
@@ -13,19 +13,15 @@ Encrypted credentials stored in a JSON schema to securely exchange credentials b
# Summary
A keystore is a construct to store a user’s keys.
-The keys will be encrypted and decrypted based on methods specifed in the specification.
-Waku will use RLN as a spam-prevention mechanism that requires zk-proofs generated by users and stored in the keystore.
-The keystore will be stored locally and called by applications.
-
+The keys will be encrypted and decrypted based on methods specified in the specification.
+This keystore uses RLN, Rate Limit Nullifiers, as a spam-prevention mechanism by generating zero knowledge proofs and storing proofs locally in the keystore.
# Background
-A Waku RLN Keystore uses RLN, Rate Limit Nullifiers, which is a method that uses zero knowledge proofs for anonymous rate-limiting for messaging frameworks.
+A Waku RLN Keystore uses RLN which is a method that uses zero knowledge proofs for anonymous rate-limiting for messaging frameworks.
The secure transfer of keys are important in peer to peer messaging applications.
-RLN will help users receive and send messages from trusted peers/users.
-It will ensure a message rate is being followed in the messaging network and keeping anonymity of the message owner.
-It is a security feature.
+RLN help users receive and send messages from trusted parties.
+It will ensure a message rate is being followed in the network while keeping the anonymity of the message owner.
-The Waku RLN keystore can be used by users to store credentials securely and exchange credentials anonymously.
## Example Waku RLN Keystore:
From 34dffbd08e2be50223165b808eb70e2eb24b7f59 Mon Sep 17 00:00:00 2001
From: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Date: Thu, 16 Nov 2023 23:37:34 -0500
Subject: [PATCH 30/67] Update README.md
---
content/docs/rfcs/72/README.md | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/content/docs/rfcs/72/README.md b/content/docs/rfcs/72/README.md
index e82ccea57..8cb7db44a 100644
--- a/content/docs/rfcs/72/README.md
+++ b/content/docs/rfcs/72/README.md
@@ -32,11 +32,11 @@ application: "waku-rln-relay",
appIdentifier: "01234567890abcdef",
version: "0.2",
credentials: {
- "9DB2B4718A97485B9F70F68D1CC19F4E10F0B4CE943418838E94956CB8E57548": {
+ [memeberHash | string]: {
crypto: {
cipher: "aes-128-ctr",
cipherparams: { iv: “ “, },
- ciphertext: "",
+ ciphertext: "string",
kdf: "pbkdf2",
kdfparams: {
dklen: interger,
@@ -44,7 +44,7 @@ version: "0.2",
prf: "hmac-sha256",
salt: "hash",
},
- mac: “Byte 256 Hash",
+ mac: “Byte256 Hash",
},
}
From 20dc74101166c101fb7dd3513594c77af0095e27 Mon Sep 17 00:00:00 2001
From: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Date: Thu, 16 Nov 2023 23:41:34 -0500
Subject: [PATCH 31/67] Update README.md
---
content/docs/rfcs/72/README.md | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/content/docs/rfcs/72/README.md b/content/docs/rfcs/72/README.md
index 8cb7db44a..4d19bcf2d 100644
--- a/content/docs/rfcs/72/README.md
+++ b/content/docs/rfcs/72/README.md
@@ -50,21 +50,21 @@ version: "0.2",
```
# Specification:
-- The keystore MUST be in JSON format:
--
+- The keystore is constructed with generated cryptographic constructions with password verification and secret decryption.
+- Each module consists of keypair under credentials = key: [MembershipHash]: pair: [nWakuCredential]
+- A keystore object contains a few modules including metadata, kdf, checksum, and cipher.
+nWakuCredential - follows EIP-2335
- ## Header Options:
-- application: string;
-- version: string;
-- appIdentifier: string;
-## Credentials:
-- [key: MembershipHash]: nWakuCredential
+## Metadata:
+The metadata of the keystore will consist of the declaration of `application`, `version`, and `appIdentifier` being used.
-MembershipHash : Compute MembershipHash
- - The hash SHOULD be created with three values `membershipContract`, `treeIndex`, `identityCredential`
+`application` : string
+`version` : string
+`appIdentifier`: string
+
+## Credentials:
- Encode
- Tree Index = Merkle tree filled with identity commitments of peers.
COULD be obtained with the leaf_index of identity_commitment.
RLN membership tree filled with identity commitments of peers, a data structure that ensures peer registrations.
From 7bb67dcf725229e39ce1aab243c7e8b1f31b18c7 Mon Sep 17 00:00:00 2001
From: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Date: Fri, 17 Nov 2023 10:54:41 -0500
Subject: [PATCH 32/67] Update README.md
---
content/docs/rfcs/72/README.md | 42 ++++++++++++++++++++--------------
1 file changed, 25 insertions(+), 17 deletions(-)
diff --git a/content/docs/rfcs/72/README.md b/content/docs/rfcs/72/README.md
index 4d19bcf2d..83e0f5599 100644
--- a/content/docs/rfcs/72/README.md
+++ b/content/docs/rfcs/72/README.md
@@ -51,30 +51,38 @@ version: "0.2",
```
# Specification:
- The keystore is constructed with generated cryptographic constructions with password verification and secret decryption.
-- Each module consists of keypair under credentials = key: [MembershipHash]: pair: [nWakuCredential]
-- A keystore object contains a few modules including metadata, kdf, checksum, and cipher.
-nWakuCredential - follows EIP-2335
+- - A keystore object contains a few modules including metadata, kdf, checksum, and cipher.
+- Each contruct MUST include a keypair in credentials.
+> key: [MembershipHash]: pair: [nWakuCredential]
+nWakuCredential - follows EIP-2335
## Metadata:
The metadata of the keystore will consist of the declaration of `application`, `version`, and `appIdentifier` being used.
-`application` : string
-`version` : string
-`appIdentifier`: string
+`application` : string
+ `version` : string
+`appIdentifier`: string
## Credentials:
-
-- Tree Index = Merkle tree filled with identity commitments of peers.
- COULD be obtained with the leaf_index of identity_commitment.
- RLN membership tree filled with identity commitments of peers, a data structure that ensures peer registrations.
-### Membership Hash Values
-- membershipContract = (contract - ChainId, contractAddress)
-Peer identity = required by RLN/V1, generate zero-knowlege proof
-- idCommitment: options.identity.IDCommitment
-- idNullifier: options.identity.IDNullifier
-- idSecretHash: options.identity.IDSecretHash
-- idTrapdoor: options.identity.IDTrapdoor
+The Waku RLN credentials consists of a `membershipHash` and `nWakuCredential`
+
+### membershipHash
+- a 256 byte generated hash of `treeIndex`, `membershipContract`, and `identityCredential`
+
+`treeIndex` : is a Merkle tree filled with identity commitments of peers.
+RLN membership tree, merkle tree data structure filled with identity commitments of users.
+As described in 32/RLN-V1
+
+`membershipContract` : consist of a `contractId` and `contractAddress`
+
+`identityCredential` : user’s commitments that are stored in a merkle tree.
+Consists of:
+`identity_secret`: `identity_nullifier` + `identity_trapdoor`
+- identity_nullifier : Random 32 byte value used as component for identity_secret generation.
+- identity_trapdoor : Random 32 byte value used as component for identity_secret generation.
+This hash is created with the poseidonHash Function.
+
### Peer’s identity is composed of:
identity_secret: identity_nullifier + identity_trapdoor
From ebabff9662eb9545207b832f43bfb446a557ece5 Mon Sep 17 00:00:00 2001
From: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Date: Fri, 17 Nov 2023 11:37:41 -0500
Subject: [PATCH 33/67] Update README.md
---
content/docs/rfcs/72/README.md | 95 +++++++++++++++-------------------
1 file changed, 43 insertions(+), 52 deletions(-)
diff --git a/content/docs/rfcs/72/README.md b/content/docs/rfcs/72/README.md
index 83e0f5599..27c1ccca3 100644
--- a/content/docs/rfcs/72/README.md
+++ b/content/docs/rfcs/72/README.md
@@ -49,7 +49,7 @@ version: "0.2",
}
```
-# Specification:
+# Specification
- The keystore is constructed with generated cryptographic constructions with password verification and secret decryption.
- - A keystore object contains a few modules including metadata, kdf, checksum, and cipher.
- Each contruct MUST include a keypair in credentials.
@@ -61,7 +61,7 @@ nWakuCredential - follows EIP-2335
The metadata of the keystore will consist of the declaration of `application`, `version`, and `appIdentifier` being used.
`application` : string
- `version` : string
+`version` : string
`appIdentifier`: string
## Credentials:
@@ -79,62 +79,53 @@ As described in 32/RLN-V1
`identityCredential` : user’s commitments that are stored in a merkle tree.
Consists of:
`identity_secret`: `identity_nullifier` + `identity_trapdoor`
-- identity_nullifier : Random 32 byte value used as component for identity_secret generation.
-- identity_trapdoor : Random 32 byte value used as component for identity_secret generation.
-This hash is created with the poseidonHash Function.
-
-
-### Peer’s identity is composed of:
-identity_secret: identity_nullifier + identity_trapdoor
-- This hash is created with the poseidonHash Function.
-It is used to obtain the identity commitment of a peer.
-Also used as input for zk proof generation.
-- identity_nullifier = Random 32 byte value used as component for identity_secret generation.
-- identity_trapdoor = Random 32 byte value used as component for identity_secret generation.
-
-identity_secret_hash: poseidonHash(identity_secret)
-- poseidonHash Function = hash function for Zero Knowledge proofs
-identity_commitment: poseidonHash([identiy_secret_hash])
-
-### Waku IdentityCredential (nWakuCredential):
-
-nWakuCredential - follows EIP-2335
-- checksum = Keccak256Hash
-
-EIP Keystore
-- password
-- Secret
-- stubPubKey
-- stubPath
-
-KDF as Pbkdf2kdf
+- `identity_nullifier` : Random 32 byte value used for identity_secret generation.
+- `identity_trapdoor` : Random 32 byte value for identity_secret generation.
+
+`identity_secret_hash`: Created with `identity_secret` as parameter for hash function
+- Used to decrypt the identity commitment of the user, and as a private input for zero knowlegde proof generation.
+The secret hash should be kept private by the user.
+
+`identity_commitment`: Created with `identity_secret_hash` as parameter for hash function.
+Used by users for registering protocol.
+
+### Waku Credential:
+Waku credential is used for password verification
+nWakuCredential follows EIP-2335
+
+- A Keystore credential object SHOULD include:
+- password: used to encrypt keystore, for decryption key
+- Secret: key to be encrypted
+- PubKey: public key
+- Path: HD path used to generate the secret
+
+- checksum: hashing function
+- cipher: cipher function
+
+### KDF:
+The password based encryption SHOULD be KDF, key derivation function, produces a derived key from a password and other parameters.
+Keystore SHOULD use PBKDF2 password based encryption, as described in RFC 2898
+
```js
crypto: {
- cipher: eipCrypto.cipher.function;
- cipherparams: eipCrypto.cipher.params;
- ciphertext: eipCrypto.cipher.message;
- kdf: eipkdf.function;
- kdfparams: eipkdf.params;
- mac: checksum; located fromEipToCredential
+ cipher: cipher.function,
+ cipherparams: cipher.parameters,
+ ciphertext: cipher.message,
+ kdf: kdf.function,
+ kdfparams: {
+ - param = salt value and iteration count)
+ - dklen= length in octets of derived key, MUST be positive integer
+ - c= iteration count, MUST be positive integer
+ - prf= Underlying pseudorandom function?
+ - salt= produces a large set of keys based on the password.
+ },
+ mac: checksum
}
-
```
-- cipherFunction = is poseidonHash implementation, Poseidon paper.
-- nWaku uses Keccak256 for hash function
-
-## KDF:
-- KDF, key derivation function, produces a derived key from a base key and other parameters.
-For this specification usesPBKDF2.
-RFC 2898 - Password-Based Cryptography
-- baseKey = password,
-- param = salt value and iteration count) / is used by RLN to for peer encryption
-dklen= length in octets of derived key, MUST be positive integer
-c= iteration count, MUST be positive integer
-prf= Underlying pseudorandom function?
-salt= produces a large set of keys based on the password. Builds the derived key?
-
## Decryption:
+To decrypt a merkle proof with password and merkle proof PBKDF2.
+Returns secert key.
# Security Considerations:
- Add a password to membership hash creation. Reason:
From ec4f919025e2c24fb4a5118414a5ee12abe70b04 Mon Sep 17 00:00:00 2001
From: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Date: Fri, 17 Nov 2023 11:38:44 -0500
Subject: [PATCH 34/67] Update README.md
---
content/docs/rfcs/72/README.md | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/content/docs/rfcs/72/README.md b/content/docs/rfcs/72/README.md
index 27c1ccca3..54349ff5f 100644
--- a/content/docs/rfcs/72/README.md
+++ b/content/docs/rfcs/72/README.md
@@ -123,10 +123,13 @@ Keystore SHOULD use PBKDF2 password based encryption, as described in RFC 2898
}
```
-## Decryption:
-To decrypt a merkle proof with password and merkle proof PBKDF2.
+### Decryption:
+To decrypt a merkle proof with password and merkle proof PBKDF2.
Returns secert key.
+### Test Vector:
+Input:
+
# Security Considerations:
- Add a password to membership hash creation. Reason:
From 9dd5b8eb142780074b277361d0b8ee4107408152 Mon Sep 17 00:00:00 2001
From: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Date: Fri, 17 Nov 2023 21:30:22 -0500
Subject: [PATCH 35/67] Update README.md
---
content/docs/rfcs/72/README.md | 116 ++++++++++++++++++++++++++-------
1 file changed, 92 insertions(+), 24 deletions(-)
diff --git a/content/docs/rfcs/72/README.md b/content/docs/rfcs/72/README.md
index 54349ff5f..16335ded7 100644
--- a/content/docs/rfcs/72/README.md
+++ b/content/docs/rfcs/72/README.md
@@ -29,38 +29,37 @@ This is an example of a keystore that is used by a Waku RLN Relay.
```js
application: "waku-rln-relay",
-appIdentifier: "01234567890abcdef",
-version: "0.2",
+appIdentifier: "string",
+version: "string",
credentials: {
[memeberHash | string]: {
crypto: {
- cipher: "aes-128-ctr",
- cipherparams: { iv: “ “, },
+ cipher: "string",
+ cipherparams: { object },
ciphertext: "string",
kdf: "pbkdf2",
kdfparams: {
dklen: interger,
c: interger,
- prf: "hmac-sha256",
- salt: "hash",
+ prf: "string",
+ salt: "string",
},
- mac: “Byte256 Hash",
+ mac: “string",
},
}
```
# Specification
-- The keystore is constructed with generated cryptographic constructions with password verification and secret decryption.
-- - A keystore object contains a few modules including metadata, kdf, checksum, and cipher.
-- Each contruct MUST include a keypair in credentials.
+The keystore MUST be generated with a cryptographic constructions for password verification and decryption.
+- Keystore modules SHOULD include metadata, key derivation function, checksum, and cipher.
+- Each contruct MUST include a keypair:
> key: [MembershipHash]: pair: [nWakuCredential]
-nWakuCredential - follows EIP-2335
-
## Metadata:
-The metadata of the keystore will consist of the declaration of `application`, `version`, and `appIdentifier` being used.
+Information about the keystore SHOULD be stored in the metadata.
+- The declaration of `application`, `version`, and `appIdentifier` COULD occur in the metadata.
-`application` : string
+`application` : current application
`version` : string
`appIdentifier`: string
@@ -74,9 +73,9 @@ The Waku RLN credentials consists of a `membershipHash` and `nWakuCredential`
RLN membership tree, merkle tree data structure filled with identity commitments of users.
As described in 32/RLN-V1
-`membershipContract` : consist of a `contractId` and `contractAddress`
+`membershipContract` : MUST be a hash of a `contractId` and `contractAddress`
-`identityCredential` : user’s commitments that are stored in a merkle tree.
+`identityCredential` : MUST be a hash of user’s commitments that are stored in a merkle tree.
Consists of:
`identity_secret`: `identity_nullifier` + `identity_trapdoor`
- `identity_nullifier` : Random 32 byte value used for identity_secret generation.
@@ -90,21 +89,21 @@ The secret hash should be kept private by the user.
Used by users for registering protocol.
### Waku Credential:
-Waku credential is used for password verification
+nWakuCredential MUST be used for password verification
nWakuCredential follows EIP-2335
-- A Keystore credential object SHOULD include:
+A nWakuCredential object SHOULD include:
- password: used to encrypt keystore, for decryption key
- Secret: key to be encrypted
- PubKey: public key
-- Path: HD path used to generate the secret
+- Path: HD, hardened derivation, path used to generate the secret
- checksum: hashing function
- cipher: cipher function
### KDF:
-The password based encryption SHOULD be KDF, key derivation function, produces a derived key from a password and other parameters.
-Keystore SHOULD use PBKDF2 password based encryption, as described in RFC 2898
+The password based encryption SHOULD be KDF, key derivation function, which produces a derived key from a password and other parameters.
+Keystore COULD use PBKDF2 password based encryption, as described in RFC 2898
```js
crypto: {
@@ -124,11 +123,80 @@ Keystore SHOULD use PBKDF2 password based encryption, as described in RFC 2898
```
### Decryption:
-To decrypt a merkle proof with password and merkle proof PBKDF2.
+The keystore decrypt a merkle proof with password and merkle proof PBKDF2.
Returns secert key.
-### Test Vector:
-Input:
+## 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"
+`hash_function`: "poseidonHash"
+
+```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,
+ ],
+ IDCommitmentBigInt: buildBigIntFromUint8Array(
+ new Uint8Array([
+ 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:
- Add a password to membership hash creation. Reason:
From f3131fe8a1fdda483c486f2c469a34ec492a97af Mon Sep 17 00:00:00 2001
From: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Date: Fri, 17 Nov 2023 21:36:29 -0500
Subject: [PATCH 36/67] Update README.md
---
content/docs/rfcs/72/README.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/content/docs/rfcs/72/README.md b/content/docs/rfcs/72/README.md
index 16335ded7..4cb5e6865 100644
--- a/content/docs/rfcs/72/README.md
+++ b/content/docs/rfcs/72/README.md
@@ -67,9 +67,9 @@ Information about the keystore SHOULD be stored in the metadata.
The Waku RLN credentials consists of a `membershipHash` and `nWakuCredential`
### membershipHash
-- a 256 byte generated hash of `treeIndex`, `membershipContract`, and `identityCredential`
+MUST be a byte 256 hash generated with `treeIndex`, `membershipContract`, and `identityCredential`
-`treeIndex` : is a Merkle tree filled with identity commitments of peers.
+`treeIndex` : is a Merkle tree filled with identity commitments of users.
RLN membership tree, merkle tree data structure filled with identity commitments of users.
As described in 32/RLN-V1
From ab283d87fd000829ce99b935b08cb53e616659c5 Mon Sep 17 00:00:00 2001
From: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Date: Fri, 17 Nov 2023 21:39:36 -0500
Subject: [PATCH 37/67] Update README.md
---
content/docs/rfcs/72/README.md | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/content/docs/rfcs/72/README.md b/content/docs/rfcs/72/README.md
index 4cb5e6865..5c31cd7c2 100644
--- a/content/docs/rfcs/72/README.md
+++ b/content/docs/rfcs/72/README.md
@@ -14,7 +14,7 @@ Encrypted credentials stored in a JSON schema to securely exchange credentials b
# Summary
A keystore is a construct to store a user’s keys.
The keys will be encrypted and decrypted based on methods specified in the specification.
-This keystore uses RLN, Rate Limit Nullifiers, as a spam-prevention mechanism by generating zero knowledge proofs and storing proofs locally in the keystore.
+This keystore specification uses RLN, Rate Limit Nullifiers, as a spam-prevention mechanism by generating zero knowledge proofs and storing the proofs locally in the keystore.
# Background
A Waku RLN Keystore uses RLN which is a method that uses zero knowledge proofs for anonymous rate-limiting for messaging frameworks.
@@ -71,7 +71,7 @@ MUST be a byte 256 hash generated with `treeIndex`, `membershipContract`, and `i
`treeIndex` : is a Merkle tree filled with identity commitments of users.
RLN membership tree, merkle tree data structure filled with identity commitments of users.
-As described in 32/RLN-V1
+As described in [32/RLN-V1](https://rfc.vac.dev/spec/32/)
`membershipContract` : MUST be a hash of a `contractId` and `contractAddress`
@@ -201,4 +201,7 @@ version: "0.2",
# Security Considerations:
- Add a password to membership hash creation. Reason:
+# References:
+
+
From afe76c529f18bae25d12fbeeb462a819bdcbc8fa Mon Sep 17 00:00:00 2001
From: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Date: Fri, 17 Nov 2023 22:16:21 -0500
Subject: [PATCH 38/67] Update README.md
---
content/docs/rfcs/72/README.md | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/content/docs/rfcs/72/README.md b/content/docs/rfcs/72/README.md
index 5c31cd7c2..8efb4760a 100644
--- a/content/docs/rfcs/72/README.md
+++ b/content/docs/rfcs/72/README.md
@@ -94,9 +94,9 @@ nWakuCredential follows EIP-2335
A nWakuCredential object SHOULD include:
- password: used to encrypt keystore, for decryption key
-- Secret: key to be encrypted
-- PubKey: public key
-- Path: HD, hardened derivation, path used to generate the secret
+- secret: key to be encrypted
+- pubKey: public key
+- path: HD, hardened derivation, path used to generate the secret
- checksum: hashing function
- cipher: cipher function
@@ -123,8 +123,12 @@ Keystore COULD use PBKDF2 password based encryption, as described in RFC 2898
```
### Decryption:
-The keystore decrypt a merkle proof with password and merkle proof PBKDF2.
-Returns secert key.
+- The keystore decrypt a merkle proof with password and merkle proof PBKDF2.
+- Returns secert key.
+To generate `decryptionKey`, MUST be contructed from password and KDF.
+- The cipher.function encrypts the secret key using the decryption key.
+The `decryptionKey`, cipher.function and cipher.params MUST be used to encrypt the serect.
+If the `decryptionKey` is longer than the key size required by the cipher, it MUST be truncated to the correct number of bits.
## Test Vectors
### Input:
From c07ed834524111251013b3d875e5acffd8d20ecf Mon Sep 17 00:00:00 2001
From: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Date: Fri, 17 Nov 2023 22:17:06 -0500
Subject: [PATCH 39/67] Update README.md
---
content/docs/rfcs/72/README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/content/docs/rfcs/72/README.md b/content/docs/rfcs/72/README.md
index 8efb4760a..6755cb099 100644
--- a/content/docs/rfcs/72/README.md
+++ b/content/docs/rfcs/72/README.md
@@ -132,7 +132,7 @@ If the `decryptionKey` is longer than the key size required by the cipher, it MU
## Test Vectors
### Input:
-- hashing function used: Poseidon Hash as described in [Poseidon Paper](https://eprint.iacr.org/2019/458.pdf)
+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"
From d6a28e4ec73011f6cb175bf8f60535a07e13f14d Mon Sep 17 00:00:00 2001
From: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Date: Fri, 17 Nov 2023 22:19:03 -0500
Subject: [PATCH 40/67] Update README.md
---
content/docs/rfcs/72/README.md | 24 ++++++++++++++----------
1 file changed, 14 insertions(+), 10 deletions(-)
diff --git a/content/docs/rfcs/72/README.md b/content/docs/rfcs/72/README.md
index 6755cb099..e9f01e63f 100644
--- a/content/docs/rfcs/72/README.md
+++ b/content/docs/rfcs/72/README.md
@@ -28,6 +28,7 @@ It will ensure a message rate is being followed in the network while keeping the
This is an example of a keystore that is used by a Waku RLN Relay.
```js
+
application: "waku-rln-relay",
appIdentifier: "string",
version: "string",
@@ -49,6 +50,7 @@ version: "string",
}
```
+
# Specification
The keystore MUST be generated with a cryptographic constructions for password verification and decryption.
- Keystore modules SHOULD include metadata, key derivation function, checksum, and cipher.
@@ -106,20 +108,22 @@ The password based encryption SHOULD be KDF, key derivation function, which prod
Keystore COULD use PBKDF2 password based encryption, as described in RFC 2898
```js
- crypto: {
- cipher: cipher.function,
- cipherparams: cipher.parameters,
- ciphertext: cipher.message,
- kdf: kdf.function,
- kdfparams: {
+
+crypto: {
+ cipher: cipher.function,
+ cipherparams: cipher.parameters,
+ ciphertext: cipher.message,
+ kdf: kdf.function,
+ kdfparams: {
- param = salt value and iteration count)
- dklen= length in octets of derived key, MUST be positive integer
- c= iteration count, MUST be positive integer
- prf= Underlying pseudorandom function?
- salt= produces a large set of keys based on the password.
- },
- mac: checksum
- }
+ },
+ mac: checksum
+}
+
```
### Decryption:
@@ -132,7 +136,7 @@ If the `decryptionKey` is longer than the key size required by the cipher, it MU
## Test Vectors
### Input:
-Hashing function used: Poseidon Hash as described in [Poseidon Paper](https://eprint.iacr.org/2019/458.pdf)
+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"
From 85482b696fae19db5fe7e98fef744b6bfc386527 Mon Sep 17 00:00:00 2001
From: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Date: Sun, 19 Nov 2023 03:05:36 -0500
Subject: [PATCH 41/67] Update README.md
---
content/docs/rfcs/72/README.md | 61 ++++++++++++++++++----------------
1 file changed, 33 insertions(+), 28 deletions(-)
diff --git a/content/docs/rfcs/72/README.md b/content/docs/rfcs/72/README.md
index e9f01e63f..19a706b40 100644
--- a/content/docs/rfcs/72/README.md
+++ b/content/docs/rfcs/72/README.md
@@ -9,18 +9,18 @@ contributors:
---
# Abstract
-Encrypted credentials stored in a JSON schema to securely exchange credentials between peers.
+Encrypted credentials are stored in a JSON schema to securely exchange credentials between peers.
# Summary
A keystore is a construct to store a user’s keys.
The keys will be encrypted and decrypted based on methods specified in the specification.
-This keystore specification uses RLN, Rate Limit Nullifiers, as a spam-prevention mechanism by generating zero knowledge proofs and storing the proofs locally in the keystore.
+This keystore specification uses RLN, Rate Limit Nullifiers, as a spam-prevention mechanism by generating zero-knowledge proofs and storing the proofs locally in the keystore.
# Background
-A Waku RLN Keystore uses RLN which is a method that uses zero knowledge proofs for anonymous rate-limiting for messaging frameworks.
-The secure transfer of keys are important in peer to peer messaging applications.
-RLN help users receive and send messages from trusted parties.
-It will ensure a message rate is being followed in the network while keeping the anonymity of the message owner.
+A Waku RLN Keystore uses RLN which is a method that uses zero-knowledge proofs for anonymous rate-limiting for messaging frameworks.
+The secure transfer of keys is important in peer-to-peer messaging applications.
+RLN helps users receive and send messages from trusted parties.
+It will ensure a message rate is being followed in the network while keeping the anonymity of the message owner.
## Example Waku RLN Keystore:
@@ -62,32 +62,33 @@ 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
-`version` : string
-`appIdentifier`: string
+`version` : application version
+`appIdentifier`: application identifier
## Credentials:
-The Waku RLN credentials consists of a `membershipHash` and `nWakuCredential`
+The Waku RLN credentials consist of a `membershipHash` and `nWakuCredential`
### membershipHash
-MUST be a byte 256 hash generated with `treeIndex`, `membershipContract`, and `identityCredential`
+MUST be a 256 byte hash generated with `treeIndex`, `membershipContract`, and `identityCredential`
`treeIndex` : is a Merkle tree filled with identity commitments of users.
-RLN membership tree, merkle tree data structure filled with identity commitments of users.
+RLN membership tree, Merkle tree data structure filled with identity commitments of users.
As described in [32/RLN-V1](https://rfc.vac.dev/spec/32/)
-`membershipContract` : MUST be a hash of a `contractId` and `contractAddress`
+`membershipContract` : MUST be a hash of a `contractId` and `contractAddress`
+
+`identityCredential` : MUST be a hash of user’s commitments that are stored in a Merkle tree.
-`identityCredential` : MUST be a hash of user’s commitments that are stored in a merkle tree.
Consists of:
-`identity_secret`: `identity_nullifier` + `identity_trapdoor`
+- `identity_secret`: `identity_nullifier` + `identity_trapdoor`
- `identity_nullifier` : Random 32 byte value used for identity_secret generation.
- `identity_trapdoor` : Random 32 byte value for identity_secret generation.
-`identity_secret_hash`: Created with `identity_secret` as parameter for hash function
-- Used to decrypt the identity commitment of the user, and as a private input for zero knowlegde proof generation.
+`identity_secret_hash`: Created with `identity_secret` as the parameters for the hash function
+- Used to decrypt the identity commitment of the user, and as a private input for zero-knowledge proof generation.
The secret hash should be kept private by the user.
-`identity_commitment`: Created with `identity_secret_hash` as parameter for hash function.
+`identity_commitment`: Created with `identity_secret_hash` as a parameter for the hash function.
Used by users for registering protocol.
### Waku Credential:
@@ -104,7 +105,7 @@ A nWakuCredential object SHOULD include:
- cipher: cipher function
### KDF:
-The password based encryption SHOULD be KDF, key derivation function, which produces a derived key from a password and other parameters.
+The password-based encryption SHOULD be KDF, key derivation function, which produces a derived key from a password and other parameters.
Keystore COULD use PBKDF2 password based encryption, as described in RFC 2898
```js
@@ -115,11 +116,11 @@ crypto: {
ciphertext: cipher.message,
kdf: kdf.function,
kdfparams: {
- - param = salt value and iteration count)
- - dklen= length in octets of derived key, MUST be positive integer
- - c= iteration count, MUST be positive integer
- - prf= Underlying pseudorandom function?
- - salt= produces a large set of keys based on the password.
+ - param: salt value and iteration count
+ - dklen: length in octets of derived key, MUST be positive integer
+ - c: iteration count, MUST be positive integer
+ - prf: Underlying pseudorandom function
+ - salt: produces a large set of keys based on the password.
},
mac: checksum
}
@@ -127,11 +128,11 @@ crypto: {
```
### Decryption:
-- The keystore decrypt a merkle proof with password and merkle proof PBKDF2.
-- Returns secert key.
-To generate `decryptionKey`, MUST be contructed from password and KDF.
+- The keystore decrypts a keystore with a password and Merkle proof PBKDF2.
+- Returns secret key.
+To generate `decryptionKey`, MUST be constructed from password and KDF.
- The cipher.function encrypts the secret key using the decryption key.
-The `decryptionKey`, cipher.function and cipher.params MUST be used to encrypt the serect.
+The `decryptionKey`, cipher.function and cipher.params MUST be used to encrypt the secret.
If the `decryptionKey` is longer than the key size required by the cipher, it MUST be truncated to the correct number of bits.
## Test Vectors
@@ -207,7 +208,11 @@ version: "0.2",
```
# Security Considerations:
-- Add a password to membership hash creation. Reason:
+### Add a Password
+An attacker can regenerate a keystore based on a user who registers more than two keystores to the same `membershipContract`.
+Add a password to the construction of `membershipHash` to prevent this attack.
+Suggested Construct:
+- `membershipHash` = `treeIndex`, `membershipContract`, `identityCredential`, `membershipPassword`
# References:
From 20b1d742a298d4391332e22d07acab2ecf79239b Mon Sep 17 00:00:00 2001
From: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Date: Thu, 23 Nov 2023 01:37:17 -0500
Subject: [PATCH 42/67] Update README.md
---
content/docs/rfcs/72/README.md | 48 +++++++++++++++++++++-------------
1 file changed, 30 insertions(+), 18 deletions(-)
diff --git a/content/docs/rfcs/72/README.md b/content/docs/rfcs/72/README.md
index 19a706b40..8eca57e87 100644
--- a/content/docs/rfcs/72/README.md
+++ b/content/docs/rfcs/72/README.md
@@ -14,18 +14,17 @@ Encrypted credentials are stored in a JSON schema to securely exchange credentia
# Summary
A keystore is a construct to store a user’s keys.
The keys will be encrypted and decrypted based on methods specified in the specification.
-This keystore specification uses RLN, Rate Limit Nullifiers, as a spam-prevention mechanism by generating zero-knowledge proofs and storing the proofs locally in the keystore.
+This keystore specification uses [58/RLN-V2](https://rfc.vac.dev/spec/58/), Rate Limit Nullifiers, as a spam-prevention mechanism by generating zero-knowledge proofs and storing the proofs locally in the keystore.
# Background
-A Waku RLN Keystore uses RLN which is a method that uses zero-knowledge proofs for anonymous rate-limiting for messaging frameworks.
-The secure transfer of keys is important in peer-to-peer messaging applications.
-RLN helps users receive and send messages from trusted parties.
-It will ensure a message rate is being followed in the network while keeping the anonymity of the message owner.
-
+The secure transfer 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.
+Generated credentials by a user are encrypted and stored in the keystore to be retrieved over a network.
+With RLN, sending and receiving messages will ensure a message rate for a network is being followed while keeping the anonymity of the message owner.
## Example Waku RLN Keystore:
-This is an example of a keystore that is used by a Waku RLN Relay.
+This is an example of a keystore used by a [17/WAKU2-RLN-Relay](https://rfc.vac.dev/spec/17/).
```js
@@ -52,27 +51,33 @@ version: "string",
```
# Specification
-The keystore MUST be generated with a cryptographic constructions for password verification and decryption.
-- Keystore modules SHOULD include metadata, key derivation function, checksum, and cipher.
-- Each contruct MUST include a keypair:
-> key: [MembershipHash]: pair: [nWakuCredential]
+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://datatracker.ietf.org/doc/html/rfc2119) and [RFC 8174](https://datatracker.ietf.org/doc/html/rfc8174).
+#
+
+The keystore MUST be generated with a cryptographic construction for 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
-`version` : application version
-`appIdentifier`: application identifier
+`application` : current application
+
+`version` : application version
+
+`appIdentifier`: application identifier
## Credentials:
-The Waku RLN credentials consist of a `membershipHash` and `nWakuCredential`
+The Waku RLN credentials MUST consist of a `membershipHash` and `nWakuCredential`
+- Each contruct MUST include the keypair:
+> key: [MembershipHash]: pair: [nWakuCredential]
### membershipHash
MUST be a 256 byte hash generated with `treeIndex`, `membershipContract`, and `identityCredential`
`treeIndex` : is a Merkle tree filled with identity commitments of users.
-RLN membership tree, Merkle tree data structure filled with identity commitments of users.
+RLN membership tree is a merkle tree data structure filled with identity_commitments of users.
As described in [32/RLN-V1](https://rfc.vac.dev/spec/32/)
`membershipContract` : MUST be a hash of a `contractId` and `contractAddress`
@@ -207,14 +212,21 @@ version: "0.2",
```
-# Security Considerations:
+# Security Considerations
### Add a Password
An attacker can regenerate a keystore based on a user who registers more than two keystores to the same `membershipContract`.
Add a password to the construction of `membershipHash` to prevent this attack.
Suggested Construct:
- `membershipHash` = `treeIndex`, `membershipContract`, `identityCredential`, `membershipPassword`
-# References:
+# Copyright
+Copyright and related rights waived via CC0.
+
+# References
+1. [58/RLN-V2](https://rfc.vac.dev/spec/58/)
+2. [17/WAKU2-RLN-RELAY](https://rfc.vac.dev/spec/17/)
+3. [RFC 2119](https://datatracker.ietf.org/doc/html/rfc2119)
+4. [RFC 8174](https://datatracker.ietf.org/doc/html/rfc8174)
From cb1b36a57ea49f033264788142b0fa9395b62331 Mon Sep 17 00:00:00 2001
From: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Date: Thu, 23 Nov 2023 03:23:33 -0500
Subject: [PATCH 43/67] Update README.md
---
content/docs/rfcs/72/README.md | 102 ++++++++++++++++++++-------------
1 file changed, 63 insertions(+), 39 deletions(-)
diff --git a/content/docs/rfcs/72/README.md b/content/docs/rfcs/72/README.md
index 8eca57e87..47d4b8ca3 100644
--- a/content/docs/rfcs/72/README.md
+++ b/content/docs/rfcs/72/README.md
@@ -14,13 +14,13 @@ Encrypted credentials are stored in a JSON schema to securely exchange credentia
# Summary
A keystore is a construct to store a user’s keys.
The keys will be encrypted and decrypted based on methods specified in the specification.
-This keystore specification uses [58/RLN-V2](https://rfc.vac.dev/spec/58/), Rate Limit Nullifiers, as a spam-prevention mechanism by generating zero-knowledge proofs and storing the proofs locally in the keystore.
+This keystore specification uses [32/RLN-V1](https://rfc.vac.dev/spec/32/), Rate Limit Nullifiers, as a spam-prevention mechanism by generating zero-knowledge proofs and storing the proofs locally in the keystore.
# Background
The secure transfer 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.
Generated credentials by a user are encrypted and stored in the keystore to be retrieved over a network.
-With RLN, sending and receiving messages will ensure a message rate for a network is being followed while keeping the anonymity of the message owner.
+With [32/RLN-V1](https://rfc.vac.dev/spec/32/), sending and receiving messages will ensure a message rate for a network is being followed while keeping the anonymity of the message owner.
## Example Waku RLN Keystore:
@@ -32,19 +32,19 @@ application: "waku-rln-relay",
appIdentifier: "string",
version: "string",
credentials: {
- [memeberHash | string]: {
+ ["memberHash | string"]: {
crypto: {
cipher: "string",
- cipherparams: { object },
+ cipherparams: { object },
ciphertext: "string",
- kdf: "pbkdf2",
+ kdf: "pbkdf2 | string",
kdfparams: {
dklen: interger,
c: interger,
prf: "string",
salt: "string",
},
- mac: “string",
+ mac: “SHA 256 Hash | string",
},
}
@@ -55,11 +55,12 @@ The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL
#
The keystore MUST be generated with a cryptographic construction for password verification and decryption.
-- Keystore modules MUST include metadata, key derivation function, checksum, cipher, and a membership hash.
+
+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.
+- 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
@@ -69,39 +70,59 @@ Information about the keystore SHOULD be stored in the metadata.
`appIdentifier`: application identifier
## Credentials:
-The Waku RLN credentials MUST consist of a `membershipHash` and `nWakuCredential`
+The Waku RLN credentials MUST consist of a `membershipHash` and `WakuCredential`
- Each contruct MUST include the keypair:
-> key: [MembershipHash]: pair: [nWakuCredential]
+> key: [MembershipHash]: pair: [WakuCredential]
### membershipHash
-MUST be a 256 byte hash generated with `treeIndex`, `membershipContract`, and `identityCredential`
+- MUST be a 256 byte hash.
+- SHOULD be generated with `treeIndex`, `membershipContract`, and `identityCredential`.
+- MUST not already exist in the keystore.
-`treeIndex` : is a Merkle tree filled with identity commitments of users.
-RLN membership tree is a merkle tree data structure filled with identity_commitments of users.
+`treeIndex` :
+- it MUST be a RLN membership tree index in a merkle tree data structure filled with `identity_commitment` from user registrations.
As described in [32/RLN-V1](https://rfc.vac.dev/spec/32/)
+- MUST be integer
-`membershipContract` : MUST be a hash of a `contractId` and `contractAddress`
+`membershipContract` :
+- it MUST be a hash of a `contractId` and `contractAddress`
+- `contractId` MUST be an integer.
+- `contractAddess` MUST be a string.
-`identityCredential` : MUST be a hash of user’s commitments that are stored in a Merkle tree.
+`identityCredential` :
+- it MUST be a hash of `identity_commitment` stored in a Merkle tree.
+- MUST be a string.
-Consists of:
+it MUST Consists of:
- `identity_secret`: `identity_nullifier` + `identity_trapdoor`
-- `identity_nullifier` : Random 32 byte value used for identity_secret generation.
-- `identity_trapdoor` : Random 32 byte value for identity_secret generation.
+ - `identity_nullifier` : Random 32 byte value used for `identity_secret` generation.
+ - `identity_trapdoor` : Random 32 byte value for `identity_secret` generation.
-`identity_secret_hash`: Created with `identity_secret` as the parameters for the hash function
-- Used to decrypt the identity commitment of the user, and as a private input for zero-knowledge proof generation.
-The secret hash should be kept private by the user.
+`identity_secret_hash`:
+- it MUST be created with `identity_secret` as a parameter for the hash function.
+- Used to decrypt the `identity_commitment` of the user, and as
+a private input for zero-knowledge proof generation.
+- The secret hash SHOULD be kept private by the user.
-`identity_commitment`: Created with `identity_secret_hash` as a parameter for the hash function.
-Used by users for registering protocol.
+`identity_commitment`:
+- it MUST be created with `identity_secret_hash` for hash creation.
+- MUST be used by a user for contract registering.
### Waku Credential:
-nWakuCredential MUST be used for password verification
-nWakuCredential follows EIP-2335
+`WakuCredential` MUST be used for password verification.
+
+`WakuCredential` follows [EIP-2335](https://eips.ethereum.org/EIPS/eip-2335)
+
+
+### KDF:
-A nWakuCredential object SHOULD include:
-- password: used to encrypt keystore, for decryption key
+The password-based encryption SHOULD be KDF, key derivation function,
+to produce a derived key from a password and other parameters.
+Keystore COULD use PBKDF2 password based encryption,
+as described in [RFC 2898](https://www.ietf.org/rfc/rfc2898.txt).
+
+A `WakuCredential` object MUST include:
+- 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
@@ -109,10 +130,6 @@ A nWakuCredential object SHOULD include:
- checksum: hashing function
- cipher: cipher function
-### KDF:
-The password-based encryption SHOULD be KDF, key derivation function, which produces a derived key from a password and other parameters.
-Keystore COULD use PBKDF2 password based encryption, as described in RFC 2898
-
```js
crypto: {
@@ -133,16 +150,18 @@ crypto: {
```
### Decryption:
-- The keystore decrypts a keystore with a password and Merkle proof PBKDF2.
+- The keystore decrypts a keystore with a password and Merkle proof with PBKDF2.
- Returns secret key.
To generate `decryptionKey`, MUST be constructed from password and KDF.
- The cipher.function encrypts the secret key using the decryption key.
-The `decryptionKey`, cipher.function and cipher.params MUST be used to encrypt the secret.
-If the `decryptionKey` is longer than the key size required by the cipher, it MUST be truncated to the correct number of bits.
+- The `decryptionKey`, cipher.function and cipher.params MUST be used to encrypt the secret.
+- If the `decryptionKey` is longer than the key size required by the cipher,
+it MUST be truncated to the correct number of bits.
## Test Vectors
### Input:
-Hashing function used: Poseidon Hash as described in [Poseidon Paper](https://eprint.iacr.org/2019/458.pdf)
+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"
@@ -213,11 +232,14 @@ version: "0.2",
```
# Security Considerations
-### Add a Password
-An attacker can regenerate a keystore based on a user who registers more than two keystores to the same `membershipContract`.
-Add a password to the construction of `membershipHash` to prevent this attack.
+### 1.) Add a Password
+
+An attacker can regenerate a keystore based on a user who registers to more than one keystore on the same `membershipContract`.
+Suggest Solution : Add a password to the construction of `membershipHash` to prevent this attack.
+
Suggested Construct:
-- `membershipHash` = `treeIndex`, `membershipContract`, `identityCredential`, `membershipPassword`
+- `membershipHash` SHOULD be contructed with `treeIndex`, `membershipContract`, `identityCredential`, `membershipPassword`
+ - `membershipPassword` = a new password created and stored privately by the user.
# Copyright
Copyright and related rights waived via CC0.
@@ -227,6 +249,8 @@ Copyright and related rights waived via CC0.
2. [17/WAKU2-RLN-RELAY](https://rfc.vac.dev/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)
From 486f29bdf6f2f61a4183272bf956069ad3c19e02 Mon Sep 17 00:00:00 2001
From: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Date: Thu, 23 Nov 2023 03:30:54 -0500
Subject: [PATCH 44/67] Update README.md
---
content/docs/rfcs/72/README.md | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/content/docs/rfcs/72/README.md b/content/docs/rfcs/72/README.md
index 47d4b8ca3..79a8a1c5e 100644
--- a/content/docs/rfcs/72/README.md
+++ b/content/docs/rfcs/72/README.md
@@ -72,7 +72,7 @@ Keystore modules MUST include metadata, key derivation function, checksum, ciphe
## Credentials:
The Waku RLN credentials MUST consist of a `membershipHash` and `WakuCredential`
- Each contruct MUST include the keypair:
-> key: [MembershipHash]: pair: [WakuCredential]
+> key: [membershipHash]: pair: [WakuCredential]
### membershipHash
- MUST be a 256 byte hash.
@@ -122,13 +122,14 @@ Keystore COULD use PBKDF2 password based encryption,
as described in [RFC 2898](https://www.ietf.org/rfc/rfc2898.txt).
A `WakuCredential` object MUST include:
-- 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
+| 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
From 6d4c4e2a1c0a24dc1df001ec552de4e3c4575f2f Mon Sep 17 00:00:00 2001
From: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Date: Thu, 23 Nov 2023 03:32:53 -0500
Subject: [PATCH 45/67] Update index.md
---
content/menu/index.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/content/menu/index.md b/content/menu/index.md
index abc4a89f3..f9befdc29 100644
--- a/content/menu/index.md
+++ b/content/menu/index.md
@@ -27,6 +27,7 @@ bookMenuLevels: 1
- [63/STATUS-Keycard-Usage]({{< relref "/docs/rfcs/63/README.md" >}})
- [64/WAKU2-NETWORK]({{< relref "/docs/rfcs/64/README.md" >}})
- [66/WAKU2-METADATA]({{< relref "/docs/rfcs/66/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" >}})
From 69e7e4f7a9ca89390f4442ba38fa3e7eff302ba0 Mon Sep 17 00:00:00 2001
From: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Date: Sun, 26 Nov 2023 17:14:32 -0500
Subject: [PATCH 46/67] Update README.md
---
content/docs/rfcs/72/README.md | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/content/docs/rfcs/72/README.md b/content/docs/rfcs/72/README.md
index 79a8a1c5e..ef196f547 100644
--- a/content/docs/rfcs/72/README.md
+++ b/content/docs/rfcs/72/README.md
@@ -135,15 +135,17 @@ A `WakuCredential` object MUST include:
crypto: {
cipher: cipher.function,
- cipherparams: cipher.parameters,
+ cipherparams: {
+ - cipher.parameters
+ }
ciphertext: cipher.message,
kdf: kdf.function,
kdfparams: {
- - param: salt value and iteration count
- - dklen: length in octets of derived key, MUST be positive integer
- - c: iteration count, MUST be positive integer
- - prf: Underlying pseudorandom function
- - salt: produces a large set of keys based on the password.
+ param: salt value and iteration count,
+ dklen: length in octets of derived key, MUST be positive integer,
+ c: iteration count, MUST be positive integer,
+ prf: Underlying pseudorandom function,
+ salt: produces a large set of keys based on the password
},
mac: checksum
}
From 107e59737e4b7559459a9b7562928f5a4a1d0ba0 Mon Sep 17 00:00:00 2001
From: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Date: Fri, 8 Dec 2023 18:06:54 -0500
Subject: [PATCH 47/67] Update README.md
---
content/docs/rfcs/72/README.md | 124 ++++++++++++++++++---------------
1 file changed, 69 insertions(+), 55 deletions(-)
diff --git a/content/docs/rfcs/72/README.md b/content/docs/rfcs/72/README.md
index ef196f547..841c0db6e 100644
--- a/content/docs/rfcs/72/README.md
+++ b/content/docs/rfcs/72/README.md
@@ -6,6 +6,7 @@ status: raw
category: Standards Track
editor: Jimmy Debe
contributors:
+- ?
---
# Abstract
@@ -27,26 +28,26 @@ With [32/RLN-V1](https://rfc.vac.dev/spec/32/), sending and receiving messages w
This is an example of a keystore used by a [17/WAKU2-RLN-Relay](https://rfc.vac.dev/spec/17/).
```js
-
-application: "waku-rln-relay",
-appIdentifier: "string",
-version: "string",
- credentials: {
- ["memberHash | string"]: {
+application: 1 ,
+appIdentifier: 2,
+version: 3,
+credentials: {
+ membershipHash: {
crypto: {
- cipher: "string",
- cipherparams: { object },
- ciphertext: "string",
- kdf: "pbkdf2 | string",
+ cipher: 4,
+ cipherparams: 5,
+ ciphertext: 6,
+ kdf: 7,
kdfparams: {
- dklen: interger,
- c: interger,
- prf: "string",
- salt: "string",
+ dklen: 8,
+ c: 9,
+ prf: 10,
+ salt: 11,
},
- mac: “SHA 256 Hash | string",
- },
+ mac: 12,
+ }
}
+}
```
@@ -63,11 +64,11 @@ Keystore modules MUST include metadata, key derivation function, checksum, ciphe
- 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
+`application` : current application, MUST be a string
-`version` : application version
+`version` : application version, MUST be a string
-`appIdentifier`: application identifier
+`appIdentifier`: application identifier, MUST be a string
## Credentials:
The Waku RLN credentials MUST consist of a `membershipHash` and `WakuCredential`
@@ -76,47 +77,48 @@ The Waku RLN credentials MUST consist of a `membershipHash` and `WakuCredential`
### membershipHash
- MUST be a 256 byte hash.
+- it Must be a string
- SHOULD be generated with `treeIndex`, `membershipContract`, and `identityCredential`.
- MUST not already exist in the keystore.
-`treeIndex` :
+`treeIndex`
- it MUST be a RLN membership tree index in a merkle tree data structure filled with `identity_commitment` from user registrations.
As described in [32/RLN-V1](https://rfc.vac.dev/spec/32/)
- MUST be integer
-`membershipContract` :
+`membershipContract`
- it MUST be a hash of a `contractId` and `contractAddress`
- `contractId` MUST be an integer.
- `contractAddess` MUST be a string.
-`identityCredential` :
+`identityCredential`
- it MUST be a hash of `identity_commitment` stored in a Merkle tree.
- MUST be a string.
-it MUST Consists of:
-- `identity_secret`: `identity_nullifier` + `identity_trapdoor`
- - `identity_nullifier` : Random 32 byte value used for `identity_secret` generation.
- - `identity_trapdoor` : Random 32 byte value for `identity_secret` generation.
+it MUST consists of:
+- `identity_secret`= `identity_nullifier` + `identity_trapdoor`
+ - `identity_nullifier` : Random 32 byte value
+ - `identity_trapdoor` : Random 32 byte value
-`identity_secret_hash`:
+`identity_secret_hash`
- it MUST be created with `identity_secret` as a parameter for the hash function.
- Used to decrypt the `identity_commitment` of the user, and as
a private input for zero-knowledge proof generation.
- The secret hash SHOULD be kept private by the user.
-`identity_commitment`:
+`identity_commitment`
- it MUST be created with `identity_secret_hash` for hash creation.
- MUST be used by a user for contract registering.
-### Waku Credential:
-`WakuCredential` MUST be used for password verification.
+### Waku Credential
+`WakuCredential`
+- MUST be used for password verification.
+- it MUST follow [EIP-2335](https://eips.ethereum.org/EIPS/eip-2335)
-`WakuCredential` follows [EIP-2335](https://eips.ethereum.org/EIPS/eip-2335)
+### KDF
-### KDF:
-
-The password-based encryption 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.
Keystore COULD use PBKDF2 password based encryption,
as described in [RFC 2898](https://www.ietf.org/rfc/rfc2898.txt).
@@ -134,30 +136,39 @@ A `WakuCredential` object MUST include:
```js
crypto: {
- cipher: cipher.function,
+ // The cipher function
+ cipher: 1
+ // The cipher parameters
cipherparams: {
- - cipher.parameters
- }
- ciphertext: cipher.message,
- kdf: kdf.function,
+ iv: 2
+ },
+ // The cipher message
+ ciphertext: 3,
+ // KDF Function
+ kdf: 4,
kdfparams: {
- param: salt value and iteration count,
- dklen: length in octets of derived key, MUST be positive integer,
- c: iteration count, MUST be positive integer,
- prf: Underlying pseudorandom function,
- salt: produces a large set of keys based on the password
+ // Salt value and iteration count
+ param: 5,
+ // Length in octets of derived key, MUST be positive integer
+ dklen: 6,
+ // Iteration count, MUST be positive integer
+ c: 7,
+ // Underlying pseudorandom function
+ prf: 8,
+ // Produces a large set of keys based on the password
+ salt: 9
},
- mac: checksum
+ // Checksum
+ mac: 10
}
```
-### Decryption:
-- The keystore decrypts a keystore with a password and Merkle proof with PBKDF2.
-- Returns secret key.
-To generate `decryptionKey`, MUST be constructed from password and KDF.
-- The cipher.function encrypts the secret key using the decryption key.
-- The `decryptionKey`, cipher.function and cipher.params MUST be used to encrypt the secret.
+### Decryption
+The keystore decrypts a keystore with a password and Merkle proof with PBKDF2 than returns the secret key.
+- To generate `decryptionKey`, MUST be constructed from password and KDF.
+- The cipher function encrypts the secret key using the `decryptionKey`.
+- The `decryptionKey`, cipher function and cipher parameters MUST be used to encrypt the secret.
- If the `decryptionKey` is longer than the key size required by the cipher,
it MUST be truncated to the correct number of bits.
@@ -165,10 +176,13 @@ it MUST be truncated to the correct number of bits.
### 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"
-`hash_function`: "poseidonHash"
+`application`: "waku-rln-relay"
+
+`appIdentifier`: "01234567890abcdef"
+
+`version`: "0.2"
+
+`hash_function`: "poseidonHash"
```js
identityCredential = {
From db2f25c110ffb86d52be3f3836ca7dd894f099b3 Mon Sep 17 00:00:00 2001
From: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Date: Wed, 20 Dec 2023 11:15:14 -0500
Subject: [PATCH 48/67] Update README.md
---
content/docs/rfcs/72/README.md | 47 +++++++++++++++++++---------------
1 file changed, 27 insertions(+), 20 deletions(-)
diff --git a/content/docs/rfcs/72/README.md b/content/docs/rfcs/72/README.md
index 841c0db6e..0192a7f66 100644
--- a/content/docs/rfcs/72/README.md
+++ b/content/docs/rfcs/72/README.md
@@ -6,28 +6,32 @@ status: raw
category: Standards Track
editor: Jimmy Debe
contributors:
-- ?
+-
---
# Abstract
-Encrypted credentials are stored in a JSON schema to securely exchange credentials between peers.
+This specification describes how encrypted 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 the specification.
-This keystore specification uses [32/RLN-V1](https://rfc.vac.dev/spec/32/), Rate Limit Nullifiers, as a spam-prevention mechanism by generating zero-knowledge proofs and storing the proofs locally in the keystore.
+The keys will be encrypted and decrypted based on methods specified in this specification.
+This keystore uses [58/RLN-V2](/spec/58/) as a spam-prevention mechanism by generating zero-knowledge proofs and
+storing the credentials locally in the keystore.
# Background
-The secure transfer 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.
Generated credentials by a user are encrypted and stored in the keystore to be retrieved over a network.
-With [32/RLN-V1](https://rfc.vac.dev/spec/32/), sending and receiving messages will ensure a message rate for a network is being followed while keeping the anonymity of the message owner.
+With [58/RLN-V2](/spec/58/), sending and receiving
+messages will ensure a message rate for a network is being followed while keeping the anonymity of the message owner.
## Example Waku RLN Keystore:
-This is an example of a keystore used by a [17/WAKU2-RLN-Relay](https://rfc.vac.dev/spec/17/).
+This is an example of a keystore used by a [17/WAKU2-RLN-Relay](/spec/17/).
```js
+
application: 1 ,
appIdentifier: 2,
version: 3,
@@ -52,8 +56,8 @@ credentials: {
```
# 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://datatracker.ietf.org/doc/html/rfc2119) and [RFC 8174](https://datatracker.ietf.org/doc/html/rfc8174).
-#
+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 with a cryptographic construction for password verification and decryption.
@@ -61,8 +65,9 @@ Keystore modules MUST include metadata, key derivation function, checksum, ciphe
## Metadata:
-- Information about the keystore SHOULD be stored in the metadata.
-- The declaration of `application`, `version`, and `appIdentifier` COULD occur 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.
`application` : current application, MUST be a string
@@ -71,20 +76,22 @@ Keystore modules MUST include metadata, key derivation function, checksum, ciphe
`appIdentifier`: application identifier, MUST be a string
## Credentials:
-The Waku RLN credentials MUST consist of a `membershipHash` and `WakuCredential`
-- Each contruct MUST include the keypair:
+The Waku RLN credentials MUST consist of a `membershipHash` and `WakuCredential`.
+
+
+Each contruct MUST include the keypair, :
> key: [membershipHash]: pair: [WakuCredential]
### membershipHash
- MUST be a 256 byte hash.
- it Must be a string
- SHOULD be generated with `treeIndex`, `membershipContract`, and `identityCredential`.
-- MUST not already exist in the keystore.
+- it MUST NOT already exist in the keystore.
`treeIndex`
- it MUST be a RLN membership tree index in a merkle tree data structure filled with `identity_commitment` from user registrations.
As described in [32/RLN-V1](https://rfc.vac.dev/spec/32/)
-- MUST be integer
+- it MUST be integer
`membershipContract`
- it MUST be a hash of a `contractId` and `contractAddress`
@@ -104,7 +111,7 @@ it MUST consists of:
- it MUST be created with `identity_secret` as a parameter for the hash function.
- Used to decrypt the `identity_commitment` of the user, and as
a private input for zero-knowledge proof generation.
-- The secret hash SHOULD be kept private by the user.
+- This secret hash SHOULD be kept private by the user.
`identity_commitment`
- it MUST be created with `identity_secret_hash` for hash creation.
@@ -115,7 +122,6 @@ a private input for zero-knowledge proof generation.
- 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,
@@ -174,7 +180,7 @@ it MUST be truncated to the correct number of bits.
## Test Vectors
### Input:
-Hashing function used: Poseidon Hash as described in [Poseidon Paper](https://eprint.iacr.org/2019/458.pdf)
+Hashing function used: Poseidon Hash, as described in [Poseidon Paper](https://eprint.iacr.org/2019/458.pdf)
`application`: "waku-rln-relay"
@@ -262,12 +268,13 @@ Suggested Construct:
Copyright and related rights waived via CC0.
# References
-1. [58/RLN-V2](https://rfc.vac.dev/spec/58/)
-2. [17/WAKU2-RLN-RELAY](https://rfc.vac.dev/spec/17/)
+1. [58/RLN-V2](/spec/58/)
+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. [Poseidon Paper](https://eprint.iacr.org/2019/458.pdf)
From 77ea5e4ba683aea4d0100e06c22938f4d6158dd3 Mon Sep 17 00:00:00 2001
From: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Date: Wed, 20 Dec 2023 12:09:20 -0500
Subject: [PATCH 49/67] Update README.md
---
content/docs/rfcs/72/README.md | 2 ++
1 file changed, 2 insertions(+)
diff --git a/content/docs/rfcs/72/README.md b/content/docs/rfcs/72/README.md
index 0192a7f66..5055402fd 100644
--- a/content/docs/rfcs/72/README.md
+++ b/content/docs/rfcs/72/README.md
@@ -76,6 +76,8 @@ The declaration of `application`, `version`, and `appIdentifier` COULD occur in
`appIdentifier`: application identifier, MUST be a string
## Credentials:
+After RLN credentials are generated, it MUST be stored in a JSON schema.
+An on chain membership contract SHOULD be used to create the memebershipHash.
The Waku RLN credentials MUST consist of a `membershipHash` and `WakuCredential`.
From e52467e2dd1f6b6ab65a51dbcbbf677e62884505 Mon Sep 17 00:00:00 2001
From: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Date: Thu, 21 Dec 2023 03:09:21 -0500
Subject: [PATCH 50/67] Update README.md
---
content/docs/rfcs/72/README.md | 38 ++++++++++++++++++----------------
1 file changed, 20 insertions(+), 18 deletions(-)
diff --git a/content/docs/rfcs/72/README.md b/content/docs/rfcs/72/README.md
index 5055402fd..5d57b5118 100644
--- a/content/docs/rfcs/72/README.md
+++ b/content/docs/rfcs/72/README.md
@@ -21,7 +21,7 @@ storing the credentials locally in the keystore.
# Background
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.
+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 [58/RLN-V2](/spec/58/), sending and receiving
messages will ensure a message rate for a network is being followed while keeping the anonymity of the message owner.
@@ -59,7 +59,7 @@ credentials: {
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 with a cryptographic construction for password verification and decryption.
+The keystore MUST be generated with a cryptographic construction with password verification and decryption.
Keystore modules MUST include metadata, key derivation function, checksum, cipher, and a membership hash.
@@ -77,7 +77,6 @@ The declaration of `application`, `version`, and `appIdentifier` COULD occur in
## Credentials:
After RLN credentials are generated, it MUST be stored in a JSON schema.
-An on chain membership contract SHOULD be used to create the memebershipHash.
The Waku RLN credentials MUST consist of a `membershipHash` and `WakuCredential`.
@@ -85,15 +84,18 @@ Each contruct MUST include the keypair, :
> key: [membershipHash]: pair: [WakuCredential]
### membershipHash
-- MUST be a 256 byte hash.
-- it Must be a string
-- SHOULD be generated with `treeIndex`, `membershipContract`, and `identityCredential`.
+The `membershipHash` SHOULD be generated by user's participating in a membership group.
+Each user MUST register to group with an `identity_commitment` stored in a Merkle tree.
+A cryptographic hash function used to generate the `membershipHash` is [SHA256](https://www.rfc-editor.org/rfc/rfc4634.txt),
+other hash functions MAY be used.
+To generate the `membershipHash`,
+`treeIndex`, `membershipContract`, and `identityCredential` SHOULD be used to create a hexadecimal string.
- it MUST NOT already exist in the keystore.
-`treeIndex`
-- it MUST be a RLN membership tree index in a merkle tree data structure filled with `identity_commitment` from user registrations.
-As described in [32/RLN-V1](https://rfc.vac.dev/spec/32/)
-- it MUST be integer
+`treeIndex`
+After a user registers to a group, a tree index 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`
- it MUST be a hash of a `contractId` and `contractAddress`
@@ -111,13 +113,13 @@ it MUST consists of:
`identity_secret_hash`
- it MUST be created with `identity_secret` as a parameter for the hash function.
-- Used to decrypt the `identity_commitment` of the user, and as
+- Used to derive the `identity_commitment` of the user, and as
a private input for zero-knowledge proof generation.
- This secret hash SHOULD be kept private by the user.
`identity_commitment`
- it MUST be created with `identity_secret_hash` for hash creation.
-- MUST be used by a user for contract registering.
+- it MUST be used by a user for user registering.
### Waku Credential
`WakuCredential`
@@ -128,7 +130,7 @@ a private input for zero-knowledge proof generation.
The password-based encryption used SHOULD be KDF, key derivation function,
to produce a derived key from a password and other parameters.
-Keystore COULD use PBKDF2 password based encryption,
+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:
@@ -173,10 +175,10 @@ crypto: {
```
### Decryption
-The keystore decrypts a keystore with a password and Merkle proof with PBKDF2 than returns the secret key.
-- To generate `decryptionKey`, MUST be constructed from password and KDF.
+The keystore decrypts a user's credentials with a password and Merkle proof with PBKDF2 than returns the secret key.
+- To generate the `decryptionKey`, it MUST be constructed from a password and KDF.
- The cipher function encrypts the secret key using the `decryptionKey`.
-- The `decryptionKey`, cipher function and cipher parameters MUST be used to encrypt the secret.
+- The `decryptionKey`, cipher function and cipher parameters MUST be used to encrypt the secret key.
- If the `decryptionKey` is longer than the key size required by the cipher,
it MUST be truncated to the correct number of bits.
@@ -263,11 +265,11 @@ An attacker can regenerate a keystore based on a user who registers to more than
Suggest Solution : Add a password to the construction of `membershipHash` to prevent this attack.
Suggested Construct:
-- `membershipHash` SHOULD be contructed with `treeIndex`, `membershipContract`, `identityCredential`, `membershipPassword`
+- `membershipHash` SHOULD be constructed with `treeIndex`, `membershipContract`, `identityCredential`, `membershipPassword`
- `membershipPassword` = a new password created and stored privately by the user.
# Copyright
-Copyright and related rights waived via CC0.
+Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
# References
1. [58/RLN-V2](/spec/58/)
From 203db4199e3b983c510d22bf08ffb8bb8789be18 Mon Sep 17 00:00:00 2001
From: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Date: Thu, 21 Dec 2023 03:18:53 -0500
Subject: [PATCH 51/67] Update README.md
---
content/docs/rfcs/72/README.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/content/docs/rfcs/72/README.md b/content/docs/rfcs/72/README.md
index 5d57b5118..f0a0b054f 100644
--- a/content/docs/rfcs/72/README.md
+++ b/content/docs/rfcs/72/README.md
@@ -118,8 +118,8 @@ a private input for zero-knowledge proof generation.
- This secret hash SHOULD be kept private by the user.
`identity_commitment`
-- it MUST be created with `identity_secret_hash` for hash creation.
-- it MUST be used by a user for user registering.
+- 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.
### Waku Credential
`WakuCredential`
From d2c59d17307bd93d476024fceda4ea84c3f440bd Mon Sep 17 00:00:00 2001
From: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Date: Thu, 21 Dec 2023 12:39:01 -0500
Subject: [PATCH 52/67] Update README.md
---
content/docs/rfcs/72/README.md | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/content/docs/rfcs/72/README.md b/content/docs/rfcs/72/README.md
index f0a0b054f..677f15d96 100644
--- a/content/docs/rfcs/72/README.md
+++ b/content/docs/rfcs/72/README.md
@@ -16,14 +16,14 @@ 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.
-This keystore uses [58/RLN-V2](/spec/58/) as a spam-prevention mechanism by generating zero-knowledge proofs and
+This keystore uses [32/RLN-V1](/spec/32/) as a spam-prevention mechanism by generating zero-knowledge proofs and
storing the credentials locally in the keystore.
# 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 [58/RLN-V2](/spec/58/), sending and receiving
+With [32/RLN-V1](/spec/32/), sending and receiving
messages will ensure a message rate for a network is being followed while keeping the anonymity of the message owner.
## Example Waku RLN Keystore:
@@ -272,7 +272,7 @@ Suggested Construct:
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
# References
-1. [58/RLN-V2](/spec/58/)
+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)
From b47509ef6e5749c86360aade120b17e2340017a0 Mon Sep 17 00:00:00 2001
From: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Date: Sat, 30 Dec 2023 18:52:32 -0500
Subject: [PATCH 53/67] Update README.md
---
content/docs/rfcs/72/README.md | 106 +++++++++++++++++++--------------
1 file changed, 62 insertions(+), 44 deletions(-)
diff --git a/content/docs/rfcs/72/README.md b/content/docs/rfcs/72/README.md
index 677f15d96..ce92bf939 100644
--- a/content/docs/rfcs/72/README.md
+++ b/content/docs/rfcs/72/README.md
@@ -26,29 +26,31 @@ Generated credentials by a user are encrypted and stored in the keystore to be r
With [32/RLN-V1](/spec/32/), sending and receiving
messages will ensure a message rate for a network is being followed while keeping the anonymity of the message owner.
-## Example Waku RLN Keystore:
+## Waku RLN Keystore Format:
-This is an 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](/spec/17/).
```js
-application: 1 ,
-appIdentifier: 2,
-version: 3,
+application: "waku-rln-relay" ,
+appIdentifier: "string",
+version: "string",
credentials: {
- membershipHash: {
+ "membershipHash": {
crypto: {
- cipher: 4,
- cipherparams: 5,
- ciphertext: 6,
- kdf: 7,
+ cipher: "string",
+ cipherparams: {
+ iv: "string",
+ },
+ ciphertext: "string",
+ kdf: "string",
kdfparams: {
- dklen: 8,
- c: 9,
- prf: 10,
- salt: 11,
+ dklen: integer,
+ c: integer,
+ prf: "string",
+ salt: "string",
},
- mac: 12,
+ mac: "string",
}
}
}
@@ -67,63 +69,79 @@ Keystore modules MUST include metadata, key derivation function, checksum, ciphe
## 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` COULD occur in the header.
-`application` : current application, MUST be a string
+- `application` : current application, MUST be a string
-`version` : application version, MUST be a string
+- `version` : application version, MUST be a string
-`appIdentifier`: application identifier, MUST be a string
+- `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]
+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 MUST register to group with an `identity_commitment` stored in a Merkle tree.
-A cryptographic hash function used to generate the `membershipHash` is [SHA256](https://www.rfc-editor.org/rfc/rfc4634.txt),
+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),
other hash functions MAY be used.
-To generate the `membershipHash`,
-`treeIndex`, `membershipContract`, and `identityCredential` SHOULD be used to create a hexadecimal string.
+To generate the `membershipHash`, the
+`treeIndex`, `membershipContract`, 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 tree index value of the position in the Merkle tree SHOULD be returned.
+`treeIndex`
+
+After a user registers to a group,
+a tree index 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`
+`membershipContract`
+
+For decentralized membership registrations,
+the `membershipContract` SHOULD be derived from a public blockchain using smart contracts.
+For centralized requirements,
+the `membershipContract` SHOULD be derived from private servers.
- it MUST be a hash of a `contractId` and `contractAddress`
- `contractId` MUST be an integer.
- `contractAddess` MUST be a string.
-`identityCredential`
+`identityCredential`
+
+The `identityCredential` MUST be constructed with the `identity_secret`, `identity_secret_hash`, `identity_commitment` attributes.
- it MUST be a hash of `identity_commitment` stored in a Merkle tree.
-- MUST be a string.
+- it MUST be a string.
+
+##### `identity_secret`
-it MUST consists of:
-- `identity_secret`= `identity_nullifier` + `identity_trapdoor`
- - `identity_nullifier` : Random 32 byte value
- - `identity_trapdoor` : Random 32 byte value
+The `identity_secret` MUST be constructed with the `identity_nullifier` + `identity_trapdoor` values.
+- `identity_nullifier` : Random 32 byte value
+- `identity_trapdoor` : Random 32 byte value
-`identity_secret_hash`
-- it MUST be created with `identity_secret` as a parameter for the hash function.
-- Used to derive the `identity_commitment` of the user, and as
-a private input for zero-knowledge proof generation.
-- This secret hash SHOULD be kept private by the user.
+##### `identity_secret_hash`
-`identity_commitment`
+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.
-### Waku Credential
-`WakuCredential`
-- MUST be used for password verification.
+### `WakuCredential`
+
+The `WakuCredential` will store values used for encrytion and decryting user's credentials.
+- it MUST be used for password verification.
- it MUST follow [EIP-2335](https://eips.ethereum.org/EIPS/eip-2335)
### KDF
From fc6e5179928f38f410fd2feb3c531e353af8c28d Mon Sep 17 00:00:00 2001
From: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Date: Sat, 30 Dec 2023 23:39:24 -0500
Subject: [PATCH 54/67] Update README.md
---
content/docs/rfcs/72/README.md | 115 ++++++++++++++++-----------------
1 file changed, 55 insertions(+), 60 deletions(-)
diff --git a/content/docs/rfcs/72/README.md b/content/docs/rfcs/72/README.md
index ce92bf939..ddc9c67ff 100644
--- a/content/docs/rfcs/72/README.md
+++ b/content/docs/rfcs/72/README.md
@@ -16,43 +16,44 @@ 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.
-This keystore uses [32/RLN-V1](/spec/32/) as a spam-prevention mechanism by generating zero-knowledge proofs and
-storing the credentials locally in the keystore.
+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 keeping the anonymity of the message owner.
+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
-
-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",
- }
- }
+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",
+ }
+ }
+ }
}
```
@@ -61,15 +62,14 @@ credentials: {
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 with a cryptographic construction with password verification and decryption.
+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 header.
+The declaration of `application`, `version`, and `appIdentifier` COULD occur in the metadata.
- `application` : current application, MUST be a string
@@ -94,8 +94,8 @@ The `membershipHash` SHOULD be generated by user's participating in a membership
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),
other hash functions MAY be used.
-To generate the `membershipHash`, the
-`treeIndex`, `membershipContract`, and `identityCredential` attributes SHOULD be used to create a hexadecimal string.
+To generate the `membershipHash`,
+the `treeIndex`, `membershipContract`, and `identityCredential` attributes SHOULD be used to create a hexadecimal string.
- it MUST NOT already exist in the keystore.
`treeIndex`
@@ -117,13 +117,13 @@ the `membershipContract` SHOULD be derived from private servers.
`identityCredential`
-The `identityCredential` MUST be constructed with the `identity_secret`, `identity_secret_hash`, `identity_commitment` attributes.
+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 the `identity_nullifier` + `identity_trapdoor` values.
+The `identity_secret` MUST be constructed with `identity_nullifier` + `identity_trapdoor` values.
- `identity_nullifier` : Random 32 byte value
- `identity_trapdoor` : Random 32 byte value
@@ -131,8 +131,8 @@ The `identity_secret` MUST be constructed with the `identity_nullifier` + `ident
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.
+- 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).
@@ -140,7 +140,7 @@ as a private input for zero-knowledge proof generation.
### `WakuCredential`
-The `WakuCredential` will store values used for encrytion and decryting user's credentials.
+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)
@@ -164,39 +164,31 @@ A `WakuCredential` object MUST include:
```js
crypto: {
- // The cipher function
- cipher: 1
- // The cipher parameters
+
+ cipher: "string" // The cipher function
cipherparams: {
- iv: 2
+ iv: "string" // The cipher parameters
},
- // The cipher message
- ciphertext: 3,
- // KDF Function
- kdf: 4,
+ ciphertext: "string" // The cipher message,
+ kdf: "string" // KDF Function,
kdfparams: {
- // Salt value and iteration count
- param: 5,
- // Length in octets of derived key, MUST be positive integer
- dklen: 6,
- // Iteration count, MUST be positive integer
- c: 7,
- // Underlying pseudorandom function
- prf: 8,
- // Produces a large set of keys based on the password
- salt: 9
+ 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
},
- // Checksum
- mac: 10
+ mac: "string" // Checksum
}
```
### Decryption
-The keystore decrypts a user's credentials with a password and Merkle proof with PBKDF2 than returns the secret key.
+The keystore SOULD decrypt a user's credentials using a password and
+a Merkle proof with PBKDF2 than returns the secret key.
- To generate the `decryptionKey`, it MUST be constructed from a password and KDF.
-- The cipher function encrypts the secret key using the `decryptionKey`.
- The `decryptionKey`, cipher function and cipher parameters MUST be used to encrypt the secret key.
+The cipher function encrypts the secret key using the `decryptionKey`.
- If the `decryptionKey` is longer than the key size required by the cipher,
it MUST be truncated to the correct number of bits.
@@ -212,6 +204,8 @@ Hashing function used: Poseidon Hash, as described in [Poseidon Paper](https://e
`hash_function`: "poseidonHash"
+`password`: "sup3rsecure"
+
```js
identityCredential = {
IDTrapdoor: [
@@ -280,11 +274,12 @@ version: "0.2",
### 1.) Add a Password
An attacker can regenerate a keystore based on a user who registers to more than one keystore on the same `membershipContract`.
-Suggest Solution : Add a password to the construction of `membershipHash` to prevent this attack.
+Recommended Solution : Add a password to the construction of `membershipHash` to prevent this attack.
-Suggested Construct:
+Recommended `membershipHash` Construction:
- `membershipHash` SHOULD be constructed with `treeIndex`, `membershipContract`, `identityCredential`, `membershipPassword`
- - `membershipPassword` = a new password created and stored privately by the user.
+ - `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/).
From 570fd0d5e9d24dd945f86eb51db6b6dd3c73c13a Mon Sep 17 00:00:00 2001
From: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Date: Mon, 8 Jan 2024 15:40:45 -0500
Subject: [PATCH 55/67] Update README.md
---
content/docs/rfcs/72/README.md | 147 +++++++++++++++++----------------
1 file changed, 74 insertions(+), 73 deletions(-)
diff --git a/content/docs/rfcs/72/README.md b/content/docs/rfcs/72/README.md
index ddc9c67ff..2d55f684a 100644
--- a/content/docs/rfcs/72/README.md
+++ b/content/docs/rfcs/72/README.md
@@ -6,11 +6,11 @@ status: raw
category: Standards Track
editor: Jimmy Debe
contributors:
--
+- Aaryamann Challani
---
# Abstract
-This specification describes how encrypted RLN, Rate Limit Nullifier,
+This specification describes how RLN, Rate Limit Nullifier,
credentials are securely stored in a JSON schema.
# Summary
@@ -72,9 +72,7 @@ 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
-
- `appIdentifier`: application identifier, MUST be a string
## Credentials:
@@ -92,10 +90,12 @@ Each contruct MUST include the keypair:
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),
-other hash functions MAY be used.
+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`, and `identityCredential` attributes SHOULD be used to create a hexadecimal string.
+the `treeIndex`, `membershipContract`, and `contractId` attributes SHOULD be used to create a hexadecimal string.
- it MUST NOT already exist in the keystore.
`treeIndex`
@@ -108,35 +108,13 @@ a tree index value of the position in the Merkle tree SHOULD be returned.
`membershipContract`
For decentralized membership registrations,
-the `membershipContract` SHOULD be derived from a public blockchain using smart contracts.
-For centralized requirements,
-the `membershipContract` SHOULD be derived from private servers.
-- it MUST be a hash of a `contractId` and `contractAddress`
-- `contractId` MUST be an integer.
+the `membershipContract` SHOULD be derived from a public blockchain using smart contracts.
+- it MUST be a hash of a `contractAddress`
- `contractAddess` MUST be a string.
-`identityCredential`
-
-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`
+`contractId`
-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.
+The blockchain identifer being used for `membershipcontract`
### `WakuCredential`
@@ -184,13 +162,38 @@ crypto: {
```
### Decryption
-The keystore SOULD decrypt a user's credentials using a password and
-a Merkle proof with PBKDF2 than returns the secret key.
-- To generate the `decryptionKey`, it MUST be constructed from a password and KDF.
-- The `decryptionKey`, cipher function and cipher parameters MUST be used to encrypt the secret key.
-The cipher function encrypts the secret key using the `decryptionKey`.
-- If the `decryptionKey` is longer than the key size required by the cipher,
-it MUST be truncated to the correct number of bits.
+The keystore SHOULD decrypt a user's credentials using a password and
+a Merkle proof, the `membershipHASh`, using PBKDF2 that returns the `decryptionKey` key.
+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.
+
+## Reading Credentials
+
+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.
## Test Vectors
### Input:
@@ -202,39 +205,11 @@ Hashing function used: Poseidon Hash, as described in [Poseidon Paper](https://e
`version`: "0.2"
-`hash_function`: "poseidonHash"
+`hashFunction`: "poseidonHash"
`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,
- ],
- IDCommitmentBigInt: buildBigIntFromUint8Array(
- new Uint8Array([
- 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,
@@ -268,15 +243,40 @@ version: "0.2",
},
}
+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,
+ ],
+
+}
+
+
```
# Security Considerations
### 1.) Add a Password
-An attacker can regenerate a keystore based on a user who registers to more than one keystore on the same `membershipContract`.
-Recommended Solution : Add a password to the construction of `membershipHash` to prevent this attack.
+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.
-Recommended `membershipHash` Construction:
+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.
@@ -291,7 +291,8 @@ Copyright and related rights waived via [CC0](https://creativecommons.org/public
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. [Poseidon Paper](https://eprint.iacr.org/2019/458.pdf)
+7. [ERC-2335: BLS12-381 Keystore](https://eips.ethereum.org/EIPS/eip-2335)
+8. [Poseidon Paper](https://eprint.iacr.org/2019/458.pdf)
From b55d7dd9eee515a7c43e9aa6fc5f76cf92d4a808 Mon Sep 17 00:00:00 2001
From: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Date: Tue, 9 Jan 2024 12:15:33 -0500
Subject: [PATCH 56/67] Update README.md
---
content/docs/rfcs/72/README.md | 104 ++++++++++++++++-----------------
1 file changed, 52 insertions(+), 52 deletions(-)
diff --git a/content/docs/rfcs/72/README.md b/content/docs/rfcs/72/README.md
index 2d55f684a..4c3ba447d 100644
--- a/content/docs/rfcs/72/README.md
+++ b/content/docs/rfcs/72/README.md
@@ -90,12 +90,11 @@ Each contruct MUST include the keypair:
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),
-.
+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`, and `contractId` attributes SHOULD be used to create a hexadecimal string.
+the `treeIndex`, `membershipContract`, `contractId` and `identityCredential` attributes SHOULD be used to create a hexadecimal string.
- it MUST NOT already exist in the keystore.
`treeIndex`
@@ -114,7 +113,30 @@ the `membershipContract` SHOULD be derived from a public blockchain using smart
`contractId`
-The blockchain identifer being used for `membershipcontract`
+The blockchain identifer being used for `membershipcontract`.
+
+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`
@@ -170,31 +192,6 @@ as desrcibed in [ERC-2335: BLS12-381 Keystore](https://eips.ethereum.org/EIPS/ei
- The `decryptionKey`, is derived from the cipher function and
cipher parameters described in the KDF used in the keystore.
-## Reading Credentials
-
-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.
-
## Test Vectors
### Input:
Hashing function used: Poseidon Hash, as described in [Poseidon Paper](https://eprint.iacr.org/2019/458.pdf)
@@ -209,7 +206,33 @@ Hashing function used: Poseidon Hash, as described in [Poseidon Paper](https://e
`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,
@@ -243,29 +266,6 @@ version: "0.2",
},
}
-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,
- ],
-
-}
-
```
From 521967fb7ca20853e7ff0f04ca1920dfe74e7a80 Mon Sep 17 00:00:00 2001
From: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Date: Tue, 9 Jan 2024 12:19:24 -0500
Subject: [PATCH 57/67] Update README.md
---
content/docs/rfcs/72/README.md | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/content/docs/rfcs/72/README.md b/content/docs/rfcs/72/README.md
index 4c3ba447d..a11beeee5 100644
--- a/content/docs/rfcs/72/README.md
+++ b/content/docs/rfcs/72/README.md
@@ -113,7 +113,8 @@ the `membershipContract` SHOULD be derived from a public blockchain using smart
`contractId`
-The blockchain identifer being used for `membershipcontract`.
+The `contractId` SHOULD be the blockchain identifier used for `membershipcontract`.
+- it MUST be a string
The `identityCredential` MUST be derived after a succussful decryption of the keystore.
From c130e262714125c2b3137a71eab29c8fa7a8ca2e Mon Sep 17 00:00:00 2001
From: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Date: Tue, 9 Jan 2024 12:28:10 -0500
Subject: [PATCH 58/67] Update README.md
---
content/docs/rfcs/72/README.md | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/content/docs/rfcs/72/README.md b/content/docs/rfcs/72/README.md
index a11beeee5..a7b3818ef 100644
--- a/content/docs/rfcs/72/README.md
+++ b/content/docs/rfcs/72/README.md
@@ -97,25 +97,27 @@ 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`
+#### treeIndex
After a user registers to a group,
-a tree index 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
-`membershipContract`
+#### 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`
- `contractAddess` MUST be a string.
-`contractId`
+#### contractId
The `contractId` SHOULD be the blockchain identifier used for `membershipcontract`.
- it MUST be a string
+#### 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.
From 956289fd4637cc7aa88c7780b8ad4c6a92036508 Mon Sep 17 00:00:00 2001
From: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Date: Fri, 12 Jan 2024 04:36:46 -0500
Subject: [PATCH 59/67] Update README.md
---
content/docs/rfcs/72/README.md | 36 +++++++++++++++-------------------
1 file changed, 16 insertions(+), 20 deletions(-)
diff --git a/content/docs/rfcs/72/README.md b/content/docs/rfcs/72/README.md
index a7b3818ef..a2135a1ce 100644
--- a/content/docs/rfcs/72/README.md
+++ b/content/docs/rfcs/72/README.md
@@ -94,7 +94,7 @@ A cryptographic hash function that SHOULD be used to generate the `membershipHas
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.
+the `treeIndex`, `membershipContract`, `chainId` and `identityCredential` attributes SHOULD be used to create a hexadecimal string.
- it MUST NOT already exist in the keystore.
#### treeIndex
@@ -107,13 +107,12 @@ a `treeIndex` value of the position in the Merkle tree SHOULD be returned.
#### 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`
-- `contractAddess` MUST be a string.
+the `membershipContract` SHOULD be a `contractAddress` from a public blockchain using smart contracts.
+- it MUST be a string.
-#### contractId
+#### chainId
-The `contractId` SHOULD be the blockchain identifier used for `membershipcontract`.
+The `chainId` SHOULD be the blockchain identifier used for `membershipcontract`.
- it MUST be a string
#### identityCredential
@@ -187,8 +186,8 @@ crypto: {
```
### 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.
+The keystore SHOULD decrypt a user's credentials using a password and the `membershipHash`,
+using PBKDF2 that returns the `decryptionKey` key.
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).
@@ -196,20 +195,18 @@ as desrcibed in [ERC-2335: BLS12-381 Keystore](https://eips.ethereum.org/EIPS/ei
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"
-
-`password`: "sup3rsecure"
+The RLN hashing function used for `identityCredential` is Poseidon Hash,
+as described in [Poseidon Paper](https://eprint.iacr.org/2019/458.pdf).
+The keystore hash function used is [SHA256](https://www.rfc-editor.org/rfc/rfc4634.txt).
+### Input:
+- `application`: "waku-rln-relay"
+- `appIdentifier`: "01234567890abcdef"
+- `version`: "0.2"
+- `hashFunction`: "poseidonHash"
+- `password`: "sup3rsecure"
```js
@@ -269,7 +266,6 @@ version: "0.2",
},
}
-
```
# Security Considerations
From e4aba480618dee38bf13cde053742c3011acd8f7 Mon Sep 17 00:00:00 2001
From: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Date: Fri, 12 Jan 2024 04:42:08 -0500
Subject: [PATCH 60/67] Update README.md
---
content/docs/rfcs/72/README.md | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/content/docs/rfcs/72/README.md b/content/docs/rfcs/72/README.md
index a2135a1ce..da669923e 100644
--- a/content/docs/rfcs/72/README.md
+++ b/content/docs/rfcs/72/README.md
@@ -86,7 +86,7 @@ There COULD be multiple credentials stored in a keystore, categorized by the `me
Each contruct MUST include the keypair:
> key: [`membershipHash`]: pair: [`WakuCredential`]
-### membershipHash
+### 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.
@@ -97,25 +97,25 @@ To generate the `membershipHash`,
the `treeIndex`, `membershipContract`, `chainId` and `identityCredential` attributes SHOULD be used to create a hexadecimal string.
- it MUST NOT already exist in the keystore.
-#### treeIndex
+#### `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
+#### `membershipContract`
For decentralized membership registrations,
the `membershipContract` SHOULD be a `contractAddress` from a public blockchain using smart contracts.
- it MUST be a string.
-#### chainId
+#### `chainId`
The `chainId` SHOULD be the blockchain identifier used for `membershipcontract`.
- it MUST be a string
-#### identityCredential
+#### `identityCredential`
The `identityCredential` MUST be derived after a succussful decryption of the keystore.
@@ -140,7 +140,7 @@ as a private input for zero-knowledge proof generation.
- 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`
+### WakuCredential
The `WakuCredential` will store values used for encrytion and decrypting user's credentials.
- it MUST be used for password verification.
From 8af8f71d9b889eed4fc3fa7c2a696bf3b9641392 Mon Sep 17 00:00:00 2001
From: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Date: Fri, 12 Jan 2024 04:46:48 -0500
Subject: [PATCH 61/67] Update README.md
---
content/docs/rfcs/72/README.md | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/content/docs/rfcs/72/README.md b/content/docs/rfcs/72/README.md
index da669923e..2d7af3939 100644
--- a/content/docs/rfcs/72/README.md
+++ b/content/docs/rfcs/72/README.md
@@ -90,9 +90,11 @@ Each contruct MUST include the keypair:
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).
+A cryptographic hash function that SHOULD be used to generate the `membershipHash` is [SHA256](https://www.rfc-editor.org/rfc/rfc4634.txt),
+other hashing functions MAY be used.
The hash function that is used,
SHOULD be mentioned in the `verison` attribute.
+
To generate the `membershipHash`,
the `treeIndex`, `membershipContract`, `chainId` and `identityCredential` attributes SHOULD be used to create a hexadecimal string.
- it MUST NOT already exist in the keystore.
From 663624590ad74320c312e74c4e1da6b8f32c6473 Mon Sep 17 00:00:00 2001
From: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Date: Sat, 13 Jan 2024 15:52:34 -0500
Subject: [PATCH 62/67] Update README.md
---
content/docs/rfcs/72/README.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/content/docs/rfcs/72/README.md b/content/docs/rfcs/72/README.md
index 2d7af3939..48c30737f 100644
--- a/content/docs/rfcs/72/README.md
+++ b/content/docs/rfcs/72/README.md
@@ -198,9 +198,9 @@ cipher parameters described in the KDF used in the keystore.
## Test Vectors
-The RLN hashing function used for `identityCredential` is Poseidon Hash,
+RLN uses Poseidon hash algorithm for `identityCredential`,
as described in [Poseidon Paper](https://eprint.iacr.org/2019/458.pdf).
-The keystore hash function used is [SHA256](https://www.rfc-editor.org/rfc/rfc4634.txt).
+The keystore hash algorithm used is [SHA256](https://www.rfc-editor.org/rfc/rfc4634.txt).
### Input:
From 056d87b583cadb8c1dcbb2dc3d229404a04a2389 Mon Sep 17 00:00:00 2001
From: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Date: Wed, 17 Jan 2024 18:30:48 -0500
Subject: [PATCH 63/67] Update README.md
---
content/docs/rfcs/72/README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/content/docs/rfcs/72/README.md b/content/docs/rfcs/72/README.md
index 48c30737f..57bcede5b 100644
--- a/content/docs/rfcs/72/README.md
+++ b/content/docs/rfcs/72/README.md
@@ -198,7 +198,7 @@ cipher parameters described in the KDF used in the keystore.
## Test Vectors
-RLN uses Poseidon hash algorithm for `identityCredential`,
+RLN uses Poseidon hash algorithm to generate the `identityCredential`,
as described in [Poseidon Paper](https://eprint.iacr.org/2019/458.pdf).
The keystore hash algorithm used is [SHA256](https://www.rfc-editor.org/rfc/rfc4634.txt).
From 67cc9dd4609cf7d69e647cc167427b4723ddaf65 Mon Sep 17 00:00:00 2001
From: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Date: Wed, 17 Jan 2024 18:51:15 -0500
Subject: [PATCH 64/67] Update README.md
---
content/docs/rfcs/72/README.md | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/content/docs/rfcs/72/README.md b/content/docs/rfcs/72/README.md
index 57bcede5b..7323b2214 100644
--- a/content/docs/rfcs/72/README.md
+++ b/content/docs/rfcs/72/README.md
@@ -91,7 +91,7 @@ Each contruct MUST include the keypair:
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),
-other hashing functions MAY be used.
+other hash functions MAY be used.
The hash function that is used,
SHOULD be mentioned in the `verison` attribute.
@@ -139,14 +139,17 @@ as a private input for zero-knowledge proof generation.
- 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 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.
### WakuCredential
-The `WakuCredential` will store values used for encrytion and decrypting user's credentials.
+The `WakuCredential` will store values used for encryting and decrypting user's keystores.
- 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 MAY use [SHA256](https://www.rfc-editor.org/rfc/rfc4634.txt) as the hash function
+
### KDF
@@ -162,7 +165,7 @@ A `WakuCredential` object MUST include:
| secret | key to be encrypted |
| pubKey | public key |
| path | HD, hardened derivation, path used to generate the secret |
-| checksum | hashing function |
+| checksum | hash function |
| cipher | cipher function |
```js
From 12bc8d336f39f318e3bc51c87e137ba30ae7821a Mon Sep 17 00:00:00 2001
From: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Date: Sun, 21 Jan 2024 18:45:04 -0500
Subject: [PATCH 65/67] Update README.md
---
content/docs/rfcs/72/README.md | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/content/docs/rfcs/72/README.md b/content/docs/rfcs/72/README.md
index 7323b2214..909ed9338 100644
--- a/content/docs/rfcs/72/README.md
+++ b/content/docs/rfcs/72/README.md
@@ -88,7 +88,8 @@ Each contruct MUST include the keypair:
### membershipHash
-The `membershipHash` SHOULD be generated by user's participating in a membership group.
+The `membershipHash` SHOULD be generated by user's participating in a membership group,
+as decribed in [32/RLN-V1](/spec/32/).
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),
other hash functions MAY be used.
From 905260ffb1690a4383735dd27b6749709c803aa5 Mon Sep 17 00:00:00 2001
From: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Date: Mon, 22 Jan 2024 08:46:49 -0500
Subject: [PATCH 66/67] Update README.md
---
content/docs/rfcs/72/README.md | 24 +++++++++++-------------
1 file changed, 11 insertions(+), 13 deletions(-)
diff --git a/content/docs/rfcs/72/README.md b/content/docs/rfcs/72/README.md
index 909ed9338..b5143a7ba 100644
--- a/content/docs/rfcs/72/README.md
+++ b/content/docs/rfcs/72/README.md
@@ -114,8 +114,9 @@ the `membershipContract` SHOULD be a `contractAddress` from a public blockchain
- it MUST be a string.
#### `chainId`
-
-The `chainId` SHOULD be the blockchain identifier used for `membershipcontract`.
+It uniquely defines the chain upon which the registration has occurred.
+The `chainId` SHOULD be the blockchain identifier used for `membershipcontract`,
+as described in [EIP155](https://eips.ethereum.org/EIPS/eip-155).
- it MUST be a string
#### `identityCredential`
@@ -146,10 +147,10 @@ as described in [Poseidon Paper](https://eprint.iacr.org/2019/458.pdf).
### WakuCredential
-The `WakuCredential` will store values used for encryting and decrypting user's keystores.
+The `WakuCredential` will store values used for encrypting and decrypting user's keystores.
- it MUST be used for password verification.
- it MUST follow [EIP-2335](https://eips.ethereum.org/EIPS/eip-2335)
-- it MAY 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
@@ -292,12 +293,9 @@ Copyright and related rights waived via [CC0](https://creativecommons.org/public
# 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)
-
-
-
+3. [SHA256](https://www.rfc-editor.org/rfc/rfc4634.txt)
+4. [EIP155](https://eips.ethereum.org/EIPS/eip-155)
+5. [Poseidon Paper](https://eprint.iacr.org/2019/458.pdf)
+6. [EIP-2335](https://eips.ethereum.org/EIPS/eip-2335)
+7. [RFC 2898](https://www.ietf.org/rfc/rfc2898.txt)
+8. [ERC-2335: BLS12-381 Keystore](https://eips.ethereum.org/EIPS/eip-2335)
From dc64cc520ef953331df142878ba021070bb994aa Mon Sep 17 00:00:00 2001
From: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Date: Fri, 9 Feb 2024 10:56:52 -0500
Subject: [PATCH 67/67] Update README.md
---
content/docs/rfcs/72/README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/content/docs/rfcs/72/README.md b/content/docs/rfcs/72/README.md
index b5143a7ba..7c99af2cf 100644
--- a/content/docs/rfcs/72/README.md
+++ b/content/docs/rfcs/72/README.md
@@ -72,7 +72,7 @@ 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
+- `version` : application version, MUST be a string, SHOULD follow semantic versioning
- `appIdentifier`: application identifier, MUST be a string
## Credentials: