# The Protocol All encryptions are made using RSA (key size to be determined), no symmetric encryptions are used due to messages being short. a. Encryption will be a-symmetric because we can assume messages are short b. See "Registration" below c. Server keeps public keys for everyone, and gives them to a user when they want to send a message to someone (only the relevant key) d. Every e2e message is both signed and encrypted aka, message M from A to B `EM = E_Bpub(E_Apriv(N))` e. message is sent to the server in a `E_server(E_Apriv(metadata + EM from d))`, message ack is sent to the server as a `MessageAck(msg_id)`, which will be retrieved by the user when it pulls for messages. f. TODO: properly explain the different api structs g. TODO: properly explain how the server handles data ### Key Derivation Function as there is no use of symmetric keys (at least for this scope), I dont believe there is a need to use KDF, it will reduce the keyspace and we already have the public key of the server in the clients ## Registration: - User sends a register request to server `(phone number, RSA public key)`, giving them a public key and encrypting using the server's public key - Server sends the user a `VerificationRequired` message & a 6-digit code (Secure channel) - User sends the server the 6-digit code, signed using the key provided at stage 1 (this message is very short and funny, because its a 6-digit code, signed using the user's private key, and encrypted using the server's public key) - Server sends a last `Confirm` and the registration process is done ## "Login" The users dont need to login, as they dont really need to hold a conenction to the server, only thing that matters is that every message to the server should be signed with the user's private key, thus the key acts as a form of credentials ## Passing messages In order to send a message from A to B, A will ask the server for B's key, A will then encrypt the message using B's key, signed with A, wrapped in a `SendMessage` request and ultimately signed by A and encrypted using the server's key. The server will hold on to the message until B will send a `GetMessages` request to the server. ## "Control" requests - Register `(phone, pub RSA key)` extra data: RSA key size (payload length) - ConfirmRegister (signed & encrypted 6 digit code) extra data: 6 bytes for the 6 digit code (can use less but it will be padding otherwise) - GetMessages (signed & encrypted to not allow someone to "flush" someone else's msgs) extra data: EMPTY - GetUserKey (dont think it needs any signing or encryption technically, as it is very simple registering and "stealing" a key outside the system, keys are assumed to be unbreakable) extra data: 8 bytes (4 bits per digit) of whoever we want to get the key of - SendMessage `(to_user, msg_id, EM from d above)` extra data: 8 bytes (4 bits per digit) of who to send the data, 4 bytes (32bit) for length - SendAck `(to_user, msg_id - signed and encrypted)` - server doesnt know if the msg itself is indeed valid and not tempered with extra data: 8 bytes (4 bits per digit) of who to send the data, 4 bytes (32bit) for length I think it all can go into a: ``` { Version byte (0) - 1 byte RequestType - 1 byte, Phone number - 8 bytes (every 4 bits is a number, so we have 16 numbers), UTC timestamp - 8 bytes (long), extra data (based on the request given) - up to 18 bytes } = 32 bytes = 256 bits ``` and we can just append encrypted payloads to it (in SendMessage and SendAck) To each message we also append a sha3-256 signed hash enc_server( request - 256 bits, signed sha3-256 ) which means: Keys: RSA-512 Hashes: SHA3-256