Next: , Previous: , Up: Examples   [Contents][Index]

3.3 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 \kappa which upper-bounds the cheating probability by 2^{-\kappa}. 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.14 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);

In our example 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 as a common refrence. In our case P_0 will be the session leader. First, he executes the constructor of the class BarnettSmartVTMF_dlog that may take some time.

BarnettSmartVTMF_dlog *vtmf = new BarnettSmartVTMF_dlog();

Afterwards he checks the generated group G and sends the public parameters to all other players (their 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++)

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 private key material is stored internally and will never be exposed.


Then every player P_j sends the public part of his VTMF key along with a non-interactive zero-knowledge proof of knowledge (NIZK) 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 the same group G is eventually used again. It is even better to generate a fresh group (common reference) and key for each new game session.

for (size_t i = 0; i < 5; i++)
  if (i != j)

After sending, P_j receives the public keys of the other players. Of course she checks, whether these keys are correctly generated, and she 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.


For some sophisticated parts of LibTMCG a distributed coin flipping protocol is neccesary. It protects the honest-verifier zero-knowledge proofs or arguments against malicious verifiers. So, all players should execute as an initialization procedure:

JareckiLysyanskayaEDCF *edcf;
edcf = new JareckiLysyanskayaEDCF(5, 5, vtmf->p, vtmf->q, vtmf->g, vtmf->h);
if (!edcf->CheckGroup())
  std::cerr << "Group G was not correctly generated!" << std::endl;

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, because this value is checked within.

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++)

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;

Last but not least the setup of some internal generators must be accomplished by all players in a verifiable way (see GrothVSSHE).15

std::stringstream err_log;
if (!vsshe->SetupGenerators_publiccoin(whoami, aiou, rbc, edcf, err_log))
  std::cerr << "VSSHE: SetupGenerators_publiccoin() failed!" << std::endl;
// synchronize



If we use the encoding scheme of Barnett and Smart and only Groth’s shuffle protocol during the game, then the error probability is even smaller, because the security parameters of them are fixed within LibTMCG (see Preprocessor Defined Global Symbols).


There is also the possibility to use the simple variant of SetupGenerators_publiccoin with the already generated public key h as a common random value. However, this value should be refreshed periodically.

Next: , Previous: , Up: Examples   [Contents][Index]