Powered by AppSignal & Oban Pro
Would you like to see your link here? Contact us

Handshake and Contact proposal

docs/proposal/handshake_flow.livemd

Handshake and Contact proposal

Overview

sequenceDiagram
  actor Alice;
  actor Bob;

  Alice ->> Bob : Initiate handshake
  Note over Alice,Bob : Handshake TBD

  Alice ->> Alice : Saves Bob's contact
  Bob ->> Bob : Saves Alice's contact
 

Contact

Contact is a known public key that user can associate name with. Initial name comes from handshake procedure

Contacts are stored in User storage

[userArray, roomsArray, contactsObject, payloadObject]

  • userArray is [name, fullKey]
  • name is a string of user name
  • fullKey is base64 of binary concatenated private key (32 bytes) and public key (33 bytes, ASN.1)
  • roomsArray is an array of fullKeys for each allowed room
  • contactsObject is an object with hex public key (33 bytes, ASN.1) and contactInfoObject as value
  • contactInfoObject contains at least name attribute
  • payloadObject is an object with any additional data

Populated it will look like

[
  ["Charlie", "ioEcyG8l50iIqU/pRaK42Ed6Bl/RRobvVZuCNPlVvT8Dp59rb9LrIPasGtNRBD4EeU/QvPxgnwvqpu3BVSbPsSk="],
  ["FraUpj7c/hRyUcoZKkKFiDPy3CtDtLqqCOXvmdtBH9IDKuFPJ2/MGGA0VQ0XnLfR0ATJj3NTpW6iw1hzJi6IQrc=", "8H0d4d+P43yCaIwxjTMiYKz6py4GZkvQruvZLr4WKJoCVe4nCUVV7nlXIGJ1A9RPjne1nQB1TUiXflGrJTLmxhE=", "rcxtZWF+v5EOW1hSxWxVaCtA1oE6hCJ+FhmC1bKHpUkDTQluXEkZ5sNXcD1Xh8ylQrrw9hofrG/y0u3qO9oSYyE="],
  {
    "02c6c6f5c8d2854896893977f8c0466ccc6d0490bfc77e60c34d0cf6d6b1057d9e": {name: "Alice"},
    "02671f665cdee15d10b938ca601a866b6bfe3efbcd06019b4cfb38ebde1926f492": {name: "Bob"}
  }, 
  {}
]

Handshake

Handshake is performed using public key and digest signing (I guess).

Each user provides public key, name and random digest (in QR code). A peer signs digest and returns signed version (in another QR code). We may claim user known after checking signature validity.

Enigma improvement

To operate with signatures we need new methods in Enigma.js (compatible with BE encryption, for further deeds) This could be done using ECDSA functions from secp.

Following code should work.

const privB64 = "0P1FqbaR+M/UKsv1RE5hGOxo8SZs1BezLi2I/DCV6Ug=";
const pubB64 = "ArLyalm51tJv2uhXhxoESbhRDSP8PDqj3IqfSRGnTows";
const digestB64 = "YiaRhqL4tXmBkZGw7F/2bPQ41OW4+cRj4gTuPEiWR8A="; // some random data

const signB64 = Enigma.sign(digestB64, privB64);
if (! Enigma.is_valid_sign(signB64, digestB64, pubB64)) throw "Incorrect signature"
if (signB64 !== "MEUCIQCcbOEVNgurRLq7LmyO1kAT/4NvjtWV57lw5R3D2/pu1AIgU/mYGTMLFdb1J3xhpeGGSEp9oL8DHtkc+vQ7uc2IS/E=") throw "Not BE compatible signature";

System overview

graph TD;
  subgraph actor[User]
    css[(client side storage)]
    info(Name and Key)
    rooms(Room Key array)
    contacts(Contacts object)
    css --> info
    css --> rooms
    css --> contacts
  end

  buckitup{{https://buckitup.app}}
  buckitup -.-> platform
  buckitup -.-> landing

  stage{{https://offline-chat.gigalixirapp.com/}}
  stage -..-> chat

  subgraph device[Device]
    subgraph platform[Platform]
      wifi
      ds[SD card, USB drives]

      subgraph chat[Chat]
        sse(server-side encryption)
        sse --> db[(db)]
        sse --> files[(files)]
        sse --> css
      end
      
    end
  end

  subgraph landing[Landing]
    cse(client-side encryption)
    cse --> css
  end