Next: , Previous: Library Initialization, Up: Examples



3.2 Session Initialization and Key Generation

In the next step we create an instance of the class SchindelhauerTMCG. The first parameter determines the number of protocol iterations t which upper-bounds the cheating probability by 2^-t. In our example the used value 64 defines a maximum cheating probability of 5.421010862\cdot 10^-20 which is reasonable small for our purposes. The second parameter passes the number of players to the instance which is simply 5 in our case. The last argument defines the number of bits that are necessary to encode all card types in a binary representation. The given value 6 allows the encoding of 2^6 = 64 different card types at maximum. This is enough to form our deck of 52 cards.

     SchindelhauerTMCG *tmcg = new SchindelhauerTMCG(64, 5, 6);
We would like to use the more efficient encoding scheme of Barnett and Smart, thus we create an instance of BarnettSmartVTMF_dlog. However, a particular player has to act as a leader who performs the generation of the group G. In our case P_0 will be the session leader. First, he executes the constructor of BarnettSmartVTMF_dlog.

     BarnettSmartVTMF_dlog *vtmf = new BarnettSmartVTMF_dlog();
Afterwards he checks the generated group G and sends the public parameters to all other players (corresponding stream indices are 1, 2, 3, and 4, respectively).

     if (!vtmf->CheckGroup())
       std::cerr << "Group G was not correctly generated!" << std::endl;
     for (size_t i = 1; i < 5; i++)
       vtmf->PublishGroup(output_stream[i]);
The other players receive the group parameters from P_0 and use them to initialize their corresponding instances of BarnettSmartVTMF_dlog. It is very important that they also check, whether the group G was correctly generated by the leader.

     BarnettSmartVTMF_dlog *vtmf =
       new BarnettSmartVTMF_dlog(input_stream[0]);
     if (!vtmf->CheckGroup())
       std::cerr << "Group G was not correctly generated!" << std::endl;
Afterwards the key generation protocol is carried out. First, every player generates his own VTMF key. The secret key material is stored internally and will never be exposed.

     vtmf->KeyGenerationProtocol_GenerateKey();
Then every player P_j sends the public part of his VTMF key along with a non-interactive zero-knowledge proof of knowledge to each other player. The appended proof shows that he indeed knows the corresponding secret key. However, due to the non-interactive nature of this proof we have to be careful, if same group G is used again.

     for (size_t i = 0; i < 5; i++)
     {
       if (i != j)
         vtmf->KeyGenerationProtocol_PublishKey(output_stream[i]);
     }
After sending P_j receives the public keys. Simultaneously he checks, whether the keys are correctly generated, and updates the common public key h.

     for (size_t i = 0; i < 5; i++)
     {
       if (i != j)
       {
         if (!vtmf->KeyGenerationProtocol_UpdateKey(input_stream[i]))
           std::cerr << "Public key was not correctly generated!" << std::endl;
       }
     }
Finally, every player must finalize the key generation protocol.

     vtmf->KeyGenerationProtocol_Finalize();
If we want to use the more efficient shuffle verification protocol of Groth, then P_0 must also create an instance of GrothVSSHE. The first argument determines the maximum stack size of which the correctness of a shuffle will be proven. The other parameters are obtained from the former created VTMF instance vtmf. It is important that the key generation protocol has been finalized before the common public key h (i.e. vtmf->h) is passed.

     GrothVSSHE *vsshe = new GrothVSSHE(52, vtmf->p, vtmf->q, vtmf->k,
       vtmf->g, vtmf->h);
Again, P_0 will send the public parameters of the VSSHE instance to all other players.

     for (size_t i = 1; i < 5; i++)
       vsshe->PublishGroup(output_stream[i]);
The other players receive these parameters from the leader and use them to initialize their corresponding instances of GrothVSSHE. Again, it is important to check, whether the parameters were correctly chosen by the leader.

     GrothVSSHE *vsshe = new GrothVSSHE(52, input_stream[0]);
     if (!vsshe->CheckGroup())
       std::cerr << "VSSHE was not correctly generated!" << std::endl;
     if (mpz_cmp(vtmf->h, vsshe->com->h))
       std::cerr << "VSSHE: Common public key does not match!" << std::endl;
     if (mpz_cmp(vtmf->q, vsshe->com->q))
       std::cerr << "VSSHE: Subgroup order does not match!" << std::endl;
     if (mpz_cmp(vtmf->p, vsshe->p) || mpz_cmp(vtmf->q, vsshe->q) ||
       mpz_cmp(vtmf->g, vsshe->g) || mpz_cmp(vtmf->h, vsshe->h))
         std::cerr << "VSSHE: Encryption scheme does not match!" << std::endl;