Creating a new Public-key for each communication is a bad idea because of two things:
1. The idea behind a Public-key it's to use it with everyone instead of using different Public-keys for every single communication.
2. This makes SIIP much more likely to suffer a Man In The Middle attack (intercepting Public-key and replacing it with your own.)
Thus, the Public-key will generate about once a month and will be located in a file in the server.
Handshake, then, will look something like this:
User -> Server: Public-Crypt(Symmetric-key)
Server -> User: Success/Failure
The Symmetric-key will be saved encrypted in a temporary database (provided by GEP) and each time needed will be decrypted.
The hash in the Register will be a Cryptographic hash. A regular hash may map the months (January, February...) into values from 0-11. If you can get the value, e.g. 11, you can know the month, e.g. December. In a cryptographic hash, the months will be mapped to values through a one-way function, this is a nontrivial process, and I will implement a known algorithm (such as SHA-2) and invent a new one, just for fun, that won't be used in the project.
Register will return: 'Success', 'Already registered', 'Unknown key' or 'Failure decrypting'. In the latter you should try again and report the error.
Login will follow a similar procedure to Register, just that instead of writing the database, will read it looking for a hash. Will return: 'Success', 'Already connected', 'Not registered', 'Unknown key' or 'Failure decrypting'.
Send will contain messages up to 140 characters and will be mapped by a non-cryptographic hash into 140 character string. This message will not contain new-lines or non-printable characters. The message stream will follow the following structure:
"From:User\nTime:Sent\nMessage\n\n"
Each message is encrypted and added to the stream. The client will provide an option to crypt the message with a symmetric-key. This symmetric-key is different to the one used by the server and must be agreed between users before or at the start of the communication.
Returns: 'Success', 'Not authenticated', 'Unknown user', 'Syntax error', 'Unknown key' or 'Failure decrypting'. Note that 'Unknown user' doesn't means the user is not registered, it just means is not online.
There is no way for an user to know what other users are connected, so you must know the username to contact an user.
Look and Logout remain unchanged.