Project Fairdice

Client-Server Protocol Specification

Version 0.2

Precepts

Be Boring. This protocol does nothing special in cryptographic terms. In fact it goes out of its way to only use well known and understood procedures like one way hashing. The only thing new about all this is that no one has yet bothered to implement it in an open source (and thus trustable) form.

Require as little as possible. The default client-server connection protocol knows nothing about bets, game rules, game selection, finding hosts or registering public keys. It knows the minimum that it requires in order to let participants collaborate to fairly select between a set of distinct pre-determined outcomes. Anything else that it refers to or passes on is treated as opaque.

Assume as little as possible. Strong versioning and flexible extensibility are intended to promote stability through long term backwards compatibilty. The protocol is designed to seamlessly allow future versions to implement link level encryption, authentication and binary or XML encoding of the link data.

Security through transparency. Everything is coded as simply as possible. No obscurity is used. The aim is to get security by Doing It Right, not by trusting anyone or by relying on just making things difficult. The hash algorithm used as default in this first version (TIGER) is not intrinsic to the overall protocol, and future versions could allow the user to choose between multiple algorithms.

Defintions

numberchar ::= 0..9
integer    ::= numberchar | integer integer
letterchar ::= A..Z | a..Z
word       ::= letterchar | word word
alphanum   ::= letterchar | numberchar | alphanum alphanum
whitechar  ::= " "
whitespace ::= whitechar | whitespace whitespace
otherchar  ::= 
divider    ::= [whitechar] : [whitechar]

size       ::= integer
message    ::= M divider size divider 
gameunit   ::= G gamestr

V = Version
G = Game
C = Client
S = Server
D = Description
A = Action / Activity
B = Binary
L = Link / Local
K = Keepalive
M = Mode
U = Understand
R = Remote

x->y  :  L opening
y->x  :  L opened

x->y  :  L closing
y->x  :  L closed

x->y  :  K null
no action required

x->y  :  K ping request <n>
y->x  :  K ping response <n>
pings the client/server

x->y  :  K time <t>
no action required

x->y  :  K time
y->x  :  K time <t>

x->y  :  V request
y->x  :  V offer <numselection>
eg
y->x  :  V offer 1,3-5,7
x->y  :  V select <num>
eg
x->y  :  V select 4
x->y  :  V unsupported
         means no match found / version not supported.

version negotiation should always be initiated by the client,
with either a request or offer.

version negotiation is over when either the connection is
closed or either side selects in response to an offer.

connections may be closed by going directly to L closed but it
is more courteous to do an L closing and let the other end close.

x->y  :  M auth <foo>
x->y  :  M encrypt <foo>
x->y  :  M encode <foo>

start negotiations to set mode to foo.  the default is none, none, ascii

if something has not been implemented or you don't understand
something you received and think the other side has a faulty
implementation, the correct response is:

x->y   : <some message>
y->x   : U <some message>
or
y->x   : U null
(basically says "I'm confused!")


x->y   : D is <description>
or
x->y   : D request
y->x   : D is <description>
or
y->x   : D null

x->y   : R <size> <data>
sends data to the remote either user or host


Right!  Time to start playing...

C->S   : G gamestr : REQUEST IS_OPEN
S->C   : G gamestr : SHARE <sharedtext>
S->C   : G gamestr : MODULO <m>
(optional: may be client supplied)
or
S->C   : G gamestr : FAIL HOST_UNAVAILABLE
S->C   : G gamestr : FAIL GAME_UNAVAILABLE 
S->C   : G gamestr : FAIL HOST_MESSAGE <message>

(if needs be, negotiate hash algorithm here)
C->S   : G gamestr : DIGEST <digest>
S->C   : G gamestr : ID <x>
S->C   : G gamestr : PARTICIPANTS <n>
C->S   : G gamestr : REQUEST DIGESTS <numselection>
eg
C->S   : G gamestr : REQUEST DIGESTS 0,5,7-9
S->C   : G gamestr : DIGEST <x> <digest>
S->C   : G gamestr : DIGEST <x> <digest>
C->S   : G gamestr : USERTEXT <usertext>
S->C   : G gamestr : OUTCOME <outcome>
C->S   : G gamestr : REQUEST USERTEXT <numselection>
eg
C->S   : G gamestr : REQUEST USERTEXT 0,5,7-9
S->C   : G gamestr : USERTEXT <x> <usertext>
S->C   : G gamestr : USERTEXT <x> <usertext>

C->S   : G gamestr : CLOSING
S->C   : G gamestr : CLOSED

(gamestr should include hoststr, ie the ipnum:port of the host)