TODO: describe betting.

Request:

<iq type='set' to='a@b.c' id='id1'>
    <create xmlns='games:cards' id='123' type='poker:th:1' deal='true'>
        <feature xmlns='http://jabber.org/protocol/feature-neg'>
            <x type='form' xmlns='jabber:x:data'>
                <field type='hidden' var='FORM_TYPE'>
                    <value>games:cards:dn</value>
                </field>
                <field type='list-single' var='modp'>
                    <value>5</value>
                    <value>14</value>
                    <value>2</value>
                    <value>1</value>
                </field>
            </x>
        </feature>
    </create>
</iq>

Here, the form contains the only field: the list of Modular Exponential
(MODP) group numbers (as specified in RFC 2409 or RFC 352) which can be used
for encrypting cards dealing. The only required group is 1 (it is the only
group which is supported currently).

Positive response:

<iq type='result' to='x@y.z' id='id1'>
    <create xmlns='games:cards' id='123' type='poker:th:1'>
        <feature xmlns='http://jabber.org/protocol/feature-neg'>
            <x type='submit' xmlns='jabber:x:data'>
                <field type='hidden' var='FORM_TYPE'>
                    <value>games:cards:dn</value>
                </field>
                <field type='list-single' var='modp'>
                    <value>1</value>
                </field>
            </x>
        </feature>
    </create>
</iq>

After the MODP group is chosen, both parties generate random keys (key1 and
key2).

After that the dealer must shuffle the deck, encode cards in the following way:
2C -> 0
2D -> 1
2H -> 2
2S -> 3
3C -> 4
3D -> 5
3H -> 6
3S -> 7
4C -> 8
...
KS -> 47
AC -> 48
AD -> 49
AH -> 50
AS -> 51
and encrypts the shuffled deck using the following 2 stage algorithm:

Stage1

For every card C0--C51 a new random number R0--R51 is generated and forms the
message to encrypt: Mi = ((Ri & ~0x3F) | Ci). Then the encrypted message
MSGi = Mi * g^key1 (here * and ^ are operations in a chosen groups, and g is a
group generator) is generated.

Then the encrypted deck is sent to the other player encoded in hexadecimal
notation to save a bit of bandwidth:

<iq type='set' to='a@b.c' id='id2'>
    <deck xmlns='games:cards' type='poker:th:1' id='123'>
        <card msg='3ebe9d6974e3a2815271553605b3d3b74008e8d4'/>
        <card msg='abc4481f0927f3c4a004314dc9c43999ed14d4f6'/>
        <card msg='7f1afdcdad4c980952580f85e35c21b6d7ba13ca'/>
        <card msg='4e14237c1458cfb3e755e30ff99bfab9dd883752'/>
        ...
        <card msg='97e471491d08463424b97ea495218a67cfc339ca'/>
        ...
        <card msg='79a2cecfcda630a268e955ccc3f60edec952b375'/>
    </deck>
</iq>

The player who received the list encrypted messages (each of which corresponds
to some card) shuffles them and encrypts again using its key key2:
MSG2i = MSGi * g^key2 (here * and ^ are operations in a chosen groups, and
g is a group generator). The doubly encrypted messages are returned in
IQ result stanza:

<iq type='result' to='a@b.c' id='id2'>
    <deck xmlns='games:cards' type='poker:th:1' id='123'>
        <card msg='3ebe9d6974e3a2815271553605b3d3b74008e8d4'/>
        <card msg='abc4481f0927f3c4a004314dc9c43999ed14d4f6'/>
        <card msg='7f1afdcdad4c980952580f85e35c21b6d7ba13ca'/>
        <card msg='4e14237c1458cfb3e755e30ff99bfab9dd883752'/>
        ...
        <card msg='97e471491d08463424b97ea495218a67cfc339ca'/>
        ...
        <card msg='79a2cecfcda630a268e955ccc3f60edec952b375'/>
    </deck>
<iq>

Stage2

For every shuffled and doubly encrypted card C0--C51 a new random key KA0--KA51
is generated and the encrypted message MSG3i = MSG2i * g^KAi *g^(-key1) (here
* and ^ are operations in a chosen groups, and g is a group generator) is
generated.

Then the reencrypted deck is sent to the other player encoded in hexadecimal
notation:

<iq type='set' to='a@b.c' id='id3'>
    <redeck xmlns='games:cards' type='poker:th:1' id='123'>
        <card msg='3ebe9d6974e3a2815271553605b3d3b74008e8d4'/>
        <card msg='abc4481f0927f3c4a004314dc9c43999ed14d4f6'/>
        <card msg='7f1afdcdad4c980952580f85e35c21b6d7ba13ca'/>
        <card msg='4e14237c1458cfb3e755e30ff99bfab9dd883752'/>
        ...
        <card msg='97e471491d08463424b97ea495218a67cfc339ca'/>
        ...
        <card msg='79a2cecfcda630a268e955ccc3f60edec952b375'/>
    </redeck>
</iq>

The player who received the list encrypted messages (each of which corresponds
to some card) generates a new set of keys KB0--KB51 and encrypts the messages
again using individual keys and key2: MSG4i = MSG3i * g^KBi * g^(-key2) (here
* and ^ are operations in a chosen groups, and g is a group generator). The
messages, which are now doubly encrypted with individual keys, are returned in
IQ result stanza:

<iq type='result' to='a@b.c' id='id3'>
    <redeck xmlns='games:cards' type='poker:th:1' id='123'>
        <card msg='3ebe9d6974e3a2815271553605b3d3b74008e8d4'/>
        <card msg='abc4481f0927f3c4a004314dc9c43999ed14d4f6'/>
        <card msg='7f1afdcdad4c980952580f85e35c21b6d7ba13ca'/>
        <card msg='4e14237c1458cfb3e755e30ff99bfab9dd883752'/>
        ...
        <card msg='97e471491d08463424b97ea495218a67cfc339ca'/>
        ...
        <card msg='79a2cecfcda630a268e955ccc3f60edec952b375'/>
    </redeck>
<iq>

When dealing hole cards the dealer chooses 4 doubly encrypted card messages,
decrypts two of them using his individual keys (MSG3i = MSG2i * g^(-KAi)) and
sends all four cards to the other player:

<iq type='set' to='x@y.z' id='id4'>
  <deal xmlns='games:cards' type='poker:th:1' id='123'>
    <card seq='1' hold='true' msg='3ebe9d6974e3a2815271553605b3d3b74008e8d4'/>
    <card seq='2' hold='true' msg='abc4481f0927f3c4a004314dc9c43999ed14d4f6'/>
    <card seq='3' hold='false' msg='7f1afdcdad4c980952580f85e35c21b6d7ba13ca'/>
    <card seq='4' hold='false' msg='4e14237c1458cfb3e755e30ff99bfab9dd883752'/>
  </deal>
</iq>

Then the player who received the cards deciphers all 4 cards using the
corresponding keys KBi, keeps 6 least significant bits for cards with
hold='true' and returns the other two to the dealer:

<iq type='result' to='a@b.c' id='id4'>
    <deal xmlns='games:cards' type='poker:th:1' id='123'>
        <card seq='3' msg='3ebe9d6974e3a2815271553605b3d3b74008e8d4'/>
        <card seq='4' msg='abc4481f0927f3c4a004314dc9c43999ed14d4f6'/>
    </deal>
<iq>

The dealer decrypts them using keys KAi and keeps 6 lowest bits as card
numbers. This way all parties have their cards and no party knows the other
player's cards. The cipher commutativity was used to achieve the goal.

If it's necessary to deal community cards then they are dealt with
community='true', and the dealer decrypts the messages before sending a
message. The other player decrypts and returns them, so, both parties know
the cards:

<iq type='set' to='x@y.z' id='id5'>
    <deal xmlns='games:cards' type='poker:th:1' id='123'>
        <card seq='5' community='true'
              msg='7f1afdcdad4c980952580f85e35c21b6d7ba13ca'/>
        <card seq='6' community='true'
              msg='4e14237c1458cfb3e755e30ff99bfab9dd883752'/>
    </deal>
</iq>

<iq type='result' to='a@b.c' id='id5'>
    <deal xmlns='games:cards' type='poker:th:1' id='123'>
        <card seq='5' msg='3ebe9d6974e3a2815271553605b3d3b74008e8d4'/>
        <card seq='6' msg='abc4481f0927f3c4a004314dc9c43999ed14d4f6'/>
    </deal>
<iq>

The following examples give possible bets.

1) Check:

<iq type='set' to='x@y.z' id='id6'>
    <bet xmlns='games:cards' type='poker:th:1' id='123'>
        <check/>
    </bet>
</iq>

2) Call:

<iq type='set' to='x@y.z' id='id6'>
    <bet xmlns='games:cards' type='poker:th:1' id='123'>
        <call/>
    </bet>
</iq>

3) Bet:

<iq type='set' to='x@y.z' id='id6'>
    <bet xmlns='games:cards' type='poker:th:1' id='123'>
        <bet amount='100'/>
    </bet>
</iq>

4) Raise:

<iq type='set' to='x@y.z' id='id6'>
    <bet xmlns='games:cards' type='poker:th:1' id='123'>
        <raise amount='100'/>
    </bet>
</iq>

5) All-in:

<iq type='set' to='x@y.z' id='id6'>
    <bet xmlns='games:cards' type='poker:th:1' id='123'>
        <allin/>
    </bet>
</iq>

If the bet is illegal (e.g. amount is insufficient) the opponent returns
an error, otherwise he returns a simple IQ result stanza.

If a player wants (or have to) show his pocket cards to the opponent he
should use the following stanza:

<iq type='set' to='x@y.z' id='id6'>
    <open xmlns='games:cards' type='poker:th:1' id='123'>
        <card msg='3ebe9d6974e3a2815271553605b3d3b74008e8d4'/>
        <card msg='abc4481f0927f3c4a004314dc9c43999ed14d4f6'/>
    </open>
</iq>

where msg attribute contains UNENCRYPTED card values.

After the deal play is finished, the dealer takes all cards which weren't shown
to him, also decrypts all cards which weren't shown to the other player and
send both bunches to him to perform consistency check:

<iq type='set' to='x@y.z' id='id6'>
    <check xmlns='games:cards' type='poker:th:1' id='123'>
        <card seq='10' msg='3ebe9d6974e3a2815271553605b3d3b74008e8d4'/>
        <card seq='11' msg='abc4481f0927f3c4a004314dc9c43999ed14d4f6'/>
        ...
        <card seq='52' msg='79a2cecfcda630a268e955ccc3f60edec952b375'/>
    </check>
</iq>

The other player decrypts all of them and checks if the all cards are present
and present only once. If the check is successful then the result is returned,
including the decyphered cards (with hold='false'):

<iq type='result' to='a@b.c' id='id6'>
    <check xmlns='games:cards' type='poker:th:1' id='123'>
        <card seq='10' msg='3ebe9d6974e3a2815271553605b3d3b74008e8d4'/>
        <card seq='11' msg='abc4481f0927f3c4a004314dc9c43999ed14d4f6'/>
        ...
        <card seq='52' msg='79a2cecfcda630a268e955ccc3f60edec952b375'/>
    </check>
</iq>

and the next deal may be played. Otherwise the error is returned:

<iq type='error' to='a@b.c' id='id6'>
    <error type='cancel'>
        <not-acceptable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
    </error>
</iq>

and since dealer is considered to be a cheater the game is stopped.

If the dealer finds cheating then it responds by error to the next
deck, and the game is stopped.

Both players are allowed to stop the game at any moment. To do that
the following stanza is to be sent:

<iq type='set' to='x@y.z' id='id6'>
    <stop xmlns='games:cards' type='poker:th:1' id='123'/>
</iq>

After this stanza current game must be terminated and the usual
deck checking procedure is to be performed.
