Electric Communities: E Programming Language 

Rolling Dice


This chapter presents the Rolling Dice tutorial. In these example programs, two E-objects work together to create a random number. They demonstrate how easy it is in E to exchange information between two participants that do not necessarily trust each other, and guarantee the authenticity of the original information.

Both sample programs use a one-way hash function to guarantee the authenticity of each player's original number X. A one-way hash function works in one direction-it is easy to compute a hash value from a pre-image, but nearly impossible to generate the pre-image from that hash value.

This ensures "bit commitment"-by handing the opponent the hash value that verifies the original number, each object "commits" to its original number X, and cannot cheat by substituting another number X later on.


Sample program 1

This first example uses the following protocol:

  1. The two E-objects, First and Second, each a select random number called X. The two Xs will later be combined to create a random result.
  2. Using an agreed-upon one-way hashing algorithm, both objects generate a hash value of their numbers X.
  3. First reveals a one way hash of its X.
  4. Second reveals its X.
  5. First reveals its X.
  6. The Xs are combined to produce the final result.
  7. Second recomputes the one way hash of First's X to verify that First did not change its X when it learned Second's X. That would be cheating.

A potential problem in this protocol is that First receives Second's X value. This means that First knows the result before Second does. If First is unhappy about the result, it could do something toprevent the conclusion of the protocol, such as cause a network failure.

  /*
  Die Rolling Example
  Copyright 1996 Electric Communities
  All Rights Reserved Worldwide.
  */  

  import java.util.Random;
  import ec.e.lang.EInteger;

  public class DieRolling
  {
/*1*/ public static void main(String args[])
      {
        DieRoller First = new DieRoller();
        DieRoller Second = new DieRoller();

/*2*/   First <- dieRollStart(Second);
      }
   }

  eclass DieRoller 
  {
     Random randomGenerator = new Random();

/*3*/ emethod dieRollStart(DieRoller secondRoller)
     {
/*4*/  long X = randomGenerator.nextLong();
    
/*5*/  EInteger concealedX, secondX;
        secondRoller <- dieRollFinish(OneWayHash(X), 
         concealedX, &secondX);
    
/* 6 */  ewhen secondX (long otherX)
/* 11 */ {
/* 12 */ long finalResult = Combine(X, otherX);
         System.out.println("Roll result = " + finalResult);
/* 13 */ &concealedX <- forward(new EInteger(X));
         }
       }

/* 7*/ emethod dieRollFinish (long otherHash,
          EInteger firstX, EDistributor myX)
      {
/*8*/    long X = randomGenerator.nextLong();

/* 9 */  myX <- forward(new EInteger(X));

/* 10 */ ewhen firstX (long otherX)
/* 14 */ {
/* 15 */   long finalResult = Combine(otherX, X);
           System.out.println("Roll result = " + finalResult);

/* 16 */   if (OneWayHash(otherX) != otherHash) {
             System.out.println("There was cheating.");
           }
         }
       }

      long OneWayHash(long a) /* Placeholder function */
      {
        return (a); 
      }

      long Combine(long a, long b)
      {
        return (((a ^ b) % 6) + 1); /* 1..6 */
      }
    }

The Walkthrough

  1. main declares First and Second, both of E-class DieRoller. In this example, First and Second will both be running in the same machine. However, First and Second could easily be on different machines connected by a network.
  2. main sends the message dieRollStart to First, passing it a reference to Second.
  3. First executes the E-method dieRollStart in response to receiving the message sent in step 2.
  4. First chooses a random number X.
  5. First sends the message dieRollFinish to Second, passing a hashed X, the uninitialized EInteger concealedX, and the distributor for the channel representing the uninitialized EInteger secondX.
  6. First executes an ewhen statement that says, "When secondX gets a value, assign its value to otherX and execute the following code block." dieRollStart terminates.
  7. Suddenly, Second executes the E-method dieRollFinish in response to receiving the message sent in step 5.
  8. Second chooses a random number X.
  9. Second reveals its X by forwarding it to myX.
  10. Second executes an ewhen statement that says, "When firstX gets a value, assign its value to otherX and execute the following code block." dieRollFinish terminates.
  11. Suddenly, secondX has a value (as a result of step 9), so First begins execution of the code in the ewhen block (as a result of line 6).
  12. First computes the finalResult by combining its X and Second's X.
  13. First forwards the value of its X to concealedX, completing its half of the protocol. The block terminates.
  14. Suddenly, firstX has a value (as a result of step 13), so Second begins execution of the code in the ewhen block (as a result of step 10).
  15. Second computes the finalResult by combining its X and First's X.
  16. Second verifies the otherHash value it received from First in step 7. The block terminates. The protocol has been completed.


Sample program 2

In the previous example, there were two E-methods, dieRollStart and dieRollFinish. In this example, there is a single method, doDieRoll. This example also uses nested ewhen statements. This is a more elegant solution than the previous program.

Note that in this example, either DieRoller can go first.

Both sides use this protocol:

  1. Select a random number X.
  2. Reveal the one way hash of X.
  3. After receiving the other's hash, reveal X.
  4. After receiving the other's X, combine the Xs to produce the final result.
  5. Verify that there was no cheating.

This protocol is more secure than the previous example, since each object reveals its hash value before the original number X. This means that neither can know the result before the other, and possibly stop the process before the other side knows the final result.

  /*
  Die Rolling Example II
  Copyright 1996 Electric Communities
  All Rights Reserved Worldwide.
  */

      import ec.e.lang.EInteger;
      import java.util.Random;

      public class DieRolling
      {
/*1*/   public static void main(String args[])
       {
         DieRoller rollerOne = new DieRoller();
         DieRoller rollerTwo = new DieRoller();

         EInteger rollerOneHash, rollerOneX;
         EInteger rollerTwoHash, rollerTwoX;

/*2*/    rollerOne <- doDieRoll(&rollerOneHash, &rollerOneX,
          rollerTwoHash, rollerTwoX);

         rollerTwo <- doDieRoll(&rollerTwoHash, &rollerTwoX,
           rollerOneHash, rollerOneX);
       }
      }

      eclass DieRoller
      {
      Random randomGenerator = new Random();

/*3,7*/ emethod doDieRoll(EDistributor myHash, EDistributor myX,
         EInteger hisHash, EInteger hisX) {

/*4-8*/   long X = randomGenerator.nextLong();

/* 5 9 */ myHash <- forward(new EInteger(OneWayHash(X)));

/* 6 10 */ ewhen hisHash (long otherHash) {
/* 11 13 */   myX <- forward(new EInteger(X));

/* 12 14 */   ewhen hisX (long otherX) {
/* 15 17 */      long finalResult = Combine(X, otherX);

               System.out.println("Roll result = " + finalResult);

/* 16 18 */     if (OneWayHash(otherX) != otherHash) {
                  System.out.println("There was cheating.");
                }
              }
            }
          }

        long OneWayHash(long a) /* Placeholder function */
        {
          return (a);
        }

        long Combine(long a, long b)
        {
          return (((a ^ b) % 6) + 1);
        }
      }

The Walkthrough

  1. main declares rollerOne and rollerTwo, both of eclass DieRoller. In this example, rollerOne and rollerTwo will both be running on the same machine, but could easily be on different machines.
  2. main sends the message doDieRoll to rollerOne and rollerTwo. The first two parameters are used to reveal information to the other. The last two parameters will reveal the other's information.
  3. The order of the delivery of the messages in step 2 is not guaranteed, so either could get it first, or they could be delivered at the same time. To simplify this walkthrough, assume that suddenly rollerOne executes the E-method doDieRoll in response a message sent in step 2.
  4. rollerOne chooses a random number X.
  5. rollerOne reveals the hash of its X by forwarding it to myHash.
  6. rollerOne executes an ewhen statement that says, "When hisHash gets a value, assign its value to otherHash and execute the following code block." rollerOne's execution of doDieRoll terminates.
  7. Suddenly rollerTwo executes the E-method doDieRoll in response to a message from step 2.
  8. rollerTwo chooses a random number X.
  9. rollerTwo reveals the hash of its X by forwarding it to myHash.
  10. rollerTwo executes an ewhen statement that says, "When hisHash gets a value, assign its value to otherHash and execute the following code block." rollerTwo's execution of doDieRoll terminates.
  11. Suddenly, rollerTwo's hisHash has a value (as a result of step 5). That value is assigned to otherHash and execution of the code in the ewhen block begins (as a result of step 10). rollerTwo reveals its X by forwarding it to myX.
  12. rollerTwo executes an ewhen statement that says, "When hisX gets a value, assign its value to otherX and execute the following code block." rollerTwo's execution of the current ewhen code block terminates.
  13. Suddenly, rollerOne's hisHash has a value (as a result of step 9). That value is assigned to otherHash and execution of the code in the ewhen block begins (as a result of step 6). rollerOne reveals its X by forwarding it to myX.
  14. rollerOne executes an ewhen statement that says, "When hisX gets a value, assign its value to otherX and execute the following code block." rollerOne's execution of the current ewhen code block terminates.
  15. Suddenly, rollerOne's hisX has a value (as a result of step 11). That value is assigned to otherX and execution of the code in the ewhen block begins (as a result of step 14). rollerOne computes the final result.
  16. rollerOne verifies hisHash with hisX to determine that there was no cheating, completing its half of the protocol. The block terminates.
  17. Suddenly, rollerTwo's hisX has a value (as a result of step 13). That value is assigned to otherX and execution of the code in the ewhen block begins (as a result of step 12). rollerTwo computes the final result.
  18. rollerTwo verifies hisHash with hisX to determine that there was no cheating. The block terminates. The protocol has been completed.


Compiling and Running

To compile source code for the E runtime, use the ecomp compiler:

  ecomp filename

The ecomp command compiles E and Java source files directly into Java bytecodes. You can then run your compiled program with the E Java interpreter (the javaec command):

  javaec filename

For more information on these commands, see the E Tools and Utilities section in the E Programmer's Guide.


Copyright (c) 1996 Electric Communities. All rights reserved worldwide.
Most recent update: 5/29/96