ZK-Chat Network

We have to come up with a better name lol will brainstorm!

Goal

Create a library and an application that creates a decentralized anonymous chat with spam protection and some sybil resistance.

Meetings

Feb 1 2023

Product Vision Paths

Word filter list

Have a dictionary to filter messages for hate speech

TTL

Moved to its own hackmd/project here

Whisper Protocol

We are kind of building the Whisper protocol except for maybe a mix of people and apps.

Decentralized ZK-Chat for Zkitter

Essentially replacing the client-server zk-chat that is in zkitter now, for a decentralized version

Networking Stack

Waku/Libp2p

Whichever is easier to use and has the features we want

This will provide the foundation in which we : Libp2p (because Waku doesn't have browser support)will build our decentralized networking stack

Waku-RLN-Relay

Transports - WebSockets/WebTransport/WebRTC

We need a message passing mechanism that works in browser

Message Passing

Gossipsub is a protocol that will handle received messages and how we pass them. I think this is a good choice because it bounds network traffic and provides the capability to subscribe to topics.

Message Structure

Protobuf!

message Message {
  optional string message = 1;
  optional uint64 epoch = 2; // unix time rounded to the minute
  optional Bytes rln_proof = 3;
}

Discovery

One of the key hurdles of connecting to a decentralized network is finding peers, where do you start looking. Bootstrap nodes, thats where. They will help you find other peers to connect to, and act consistent peers in the network.

Registration

Optimism

With/Without Stake

Questions

  1. If we handle mutliple types of RLN registration, how do we dedup/handle slashing/connect accounts?

System Engineering

Registration

User Registration

flowchart LR
    peer1 --> stake($stake) --> RegistrationContract
    RegistrationContract --> emit(EmitsRegistration)
    emit --> SubGraph
    SubGraph --> Peers

User Constructs Merkle Tree of all Registrations

flowchart LR
    peer2 --> querySubgraph(Subgraph) --> MerkleTree(Build Merkle Tree of all RLN Registration identities)

Comms

High level (roughly 8 peers connected)

flowchart LR
    peer1 <--> peer2
    peer1 <--> peer3
    peer1 <--> peer4
    peer1 <--> ...

Peer-to-Peer Simple Message

flowchart TB
    peer1 --> msg
    msg --> peer2
    subgraph msg
        msgText
        RLNproof
    end

Network Stack

flowchart TB
    UI(UI-React) --> Zk-ChatLib
    Zk-ChatLib --> Waku/Libp2p
    subgraph Waku/Libp2p
       Waku-RLN-Relay --> ProofGeneration
       ProofGeneration --> WebSockets/WebRTC
    end
    Waku/Libp2p --> BroadcastOnNetwork

Library Stack/Design

flowchart TB
    title[<u>ZK-Chat-Lib</u>]
    ChatApp --> ChatAppContainer
    subgraph ChatAppContainer
        ArrayOfChatrooms --> ChatRoom
        MembershipTree
        ProofFunctions
    end
    subgraph ProofFunctions
        GenerateProof
        VerifyProof
    end
    subgraph ChatRoom
        ContentTopic(ContentTopic + Decoder/Encoder)
        Messages
    end
    subgraph Messages
        ProcessIncomingFunc[[ProcessIncomingFunc]]
        SendMessage
        MessageStore([MessageStore])
    end
    subgraph ProcessIncomingFunc
        MsgReceived --> VerifyProof --> MessageStore(Append to MessgeStore)
        VerifyProof --> |Verify Membership|MembershipTree
        Cleanup[[CleanUpOldMessagesFunc]]
    end
    subgraph SendMessage
        GenerateProof --> BroadcastMessage --> MessageStore(Append to MessgeStore)
    end
    subgraph MessageStore
        MessageText --> Encrypted(LongerTermGoal-Encrypted)
        epoch --> Keep
        Proof --> OnlyKeepForNEpochs
    end
    subgraph MembershipTree
        Register[[RegistrationFunc]]
        querySubgraph(Query Subgraph w timer + unrecognized id) --> BuildMerkleTree
        slashing[[slashingFunc]]
    end
    subgraph Register
        zkIdentity(Create zkIdentity using Semaphore) --> idCommitment(idCommitment = hashed zkid)
        idCommitment --> RegisterOnContract
        PubKey --> RegisterOnContract
        Deposit --> RegisterOnContract
        RegisterOnContract --> Emit 
        Emit --> idCommitment
        Emit --> PubKey
        Emit --> _index
    end

Notes:


Problems todo list:

How to construct encrypted chats with a unique userID per chat?:
* Must be non-reversable (something+something hashed?)
* Must be non-attributable <- hard part
* Must not leak link between user and associates (which semaphore groups they are in)
* Must be stored/generated locally

To have anonymous user-ids in a group chat, how do we deterministically generate the user-id?

Pubkeys can be used for DMs


Ideas

  1. ZK-Chat
    1. Browser extension that acts standalone
    2. zkchat Zkitter improvements
    3. zkchat using semaphore/zk-groups
    4. zkchat for autonomous worlds

Zk chat as a browser extension that is using zkitter backend/groups

  • Message passing - Waku / Gossipsub (the topic would be the semaphore group)
  • Login with zkitter
  • Stretch goal - Autonomous Worlds/Semaphore groups for MUD.dev
    • zkchat commands could be actions in autonomous worlds
      • Promote user within "guild" (semaphore group)

User Traction

A potential idea for gaining users/seeing interactions is to have the extension show how many peers you are connected to, how many are in the topic you are subscribed to (the chat, website, etc), and if there is low activity, an automatic message to/from new peers with similar topics

topics being:

  • chat-ids (this could be a semaphore group id, just a group chat, etc)
  • a top-level domains
  • ens names?

Plan

  1. Build the library
  2. Build browser extension that uses waku to pass messages
    1. Support for firefox and chrome (manifest v3)
    2. WAKU/Gossipsub messaging over websockets
  3. AWS node that subscribes to all messages as a relayer
  4. Integrate RLN/Zkitter/Semaphore Groups
  5. On-chain commands
    1. For autonomous worlds (op mud.dev)

Next Steps

Tyler

Talk with Thore/Nina/Wanseob about grant/contract/etc

Kaylee

random ideas:

  • have a website with a spinning globe and you can explore all the chatrooms and can teleport to the site with a specific chat

GOAL: One p2p library for all zk chat, provide a lot more connection points for p2p message passing :D

Random Notes:

Testing

  • individual function unit testing
  • end-to-end tests: spin up docker containers (can pass a couple messages back and forth)

Useful Links

zk-chat

Potential Problems

Notes: Connect to a person as a peer. If have an anonymous chat with someone else, is your anon id and peer id tied together anywhere or is it part of the construction of the chat.
Can't just do IP address (peer id) because tracking.
Pass to whatever peers you have through the network.
Hide further if you don't want to have your peers know that you're sending.
Implementing Tor within Waku (making flexible long term). Tor-based validator anonymity research

Registration: How do you sign up for this? - Interep?
What is needed to allow for someone to communicate on the protocol. Do you need web3 wallet, ENS, stake?
Balance low barrier to entry and stopping adversaries.

Does registration have to happen on chain?

Registration levels?? - Offchain id commitment (with app id for app whitelist) + web3 wallet + ENS + stake

E2E encryption:
group encryption schemas group signature?

Striking/Moderation:
Should a group be able to remove/ban users based on their actions?
How? Could have 'group requirement settings' (e.g. must have stake to join group X)

RLN for message passage protection & message rate limiting itself too (Waku has RLN build in)

WAKU RLN RELAY
https://vac.dev/rln-relay - easier reading

Layout

ChatApp

  • init name, waku & observers
  • init RLN registry
  • keep message stores
  • send/process msg
  • registration for users (add to rln registry, define registration level)
  • init content topic: create chatRoom (store historical chatRooms to disk > when you want to load up a prev chat > only want to load up that specific one)
  • send message
  • create chat room: return a new chatRoom

ChatRoom

  • init content topic (based on appName)
  • establish group members (and gatekeep based on group requirements)
  • send message

** make everything public first > then later decide protected

References

Waku RLN Relay Spec: https://

Libp2p uses peer id, we could overwrite the peerid & also use identity management side rfc.vac.dev/spec/17/

Message type: https://github.com/waku-org/js-waku/blob/efe5b326a5ba1022e4228cf9c218274a33da1e96/packages/core/src/proto/message.proto

libp2p:

Select a repo