content: package dk.alexandra.fresco.suite.tinytables.datatypes;
  
  import dk.alexandra.fresco.framework.util.Pair;
  import java.io.Serializable;
  import java.util.List;
  
  /**
   * Instances of this class represents an additive share of a boolean value.
   */
  public class TinyTablesElement implements Serializable {
  
    /**
     *
     */
    private static final long serialVersionUID = 6089268176798696542L;
    private final boolean share;
    private static final TinyTablesElement TRUE = new TinyTablesElement(true);
    private static final TinyTablesElement FALSE = new TinyTablesElement(false);
  
  
    private TinyTablesElement(boolean share) {
      this.share = share;
    }
  
    public boolean getShare() {
      return share;
    }
  
    public static boolean open(List<TinyTablesElement> allShares) {
      boolean res = false;
      for (TinyTablesElement share : allShares) {
        res ^= share.share;
      }
      return res;
    }
  
    /**
     * Returns a share of <i>a + b</i> assuming that the given parameter
     * represents a share of <i>a</i>.
     *
     * @param b
     * @return
     */
    public TinyTablesElement add(TinyTablesElement b) {
      return getInstance(this.share ^ b.share);
    }
  
    /**
     * Returns a share of this with a known boolean s.
     *
     * @param s
     * @return
     */
    public TinyTablesElement multiply(boolean s) {
      return getInstance(s & this.share);
    }
  
    public TinyTablesElement not(int playerId) {
      if (playerId == 1) {
        return flip();
      }
      return getInstance(this.share);
    }
  
    /**
     * Flips this share. Note that if both (or more precisely, an even number
     * of) parties does this, the shared value is not changed.
     *
     * @return
     */
    public TinyTablesElement flip() {
      return getInstance(!this.share);
    }
  
    /**
     * Perform the first round of a multiplication of two additively shared
     * values (this and other). A {@link TinyTablesTriple}, <i>(a,b,c)</i>
     * should be provided, and this method will in turn return shares of two
     * values, <i>e = this - a</i> and <i>d = other - b</i>.
     *
     * In order to finialize this, the opened values of e and d should be
     * provided along with the used triple to {@link TinyTablesElement#finalizeMultiplication(boolean, boolean, TinyTablesTriple, int)}
     * in order to get the result.
     *
     * @param other
     * @param triple
     * @return
     */
    public Pair<TinyTablesElement, TinyTablesElement> multiply(TinyTablesElement other,
        TinyTablesTriple triple) {
      TinyTablesElement e = this.add(triple.getA());
      TinyTablesElement d = other.add(triple.getB());
      return new Pair<>(e, d);
    }
  
    /**
     * Finalize a multiplication started by a call to {@link TinyTablesElement#multiply(boolean)}.
     *
     * @param e
     *            The opened value of the first element returned by
     *            {@link #multiply(TinyTablesElement, TinyTablesTriple)}.
     * @param d
     *            The opened value of the second element returned by
     *            {@link #multiply(TinyTablesElement, TinyTablesTriple)}.
     * @param triple
     *            The triple used in
     *            {@link #multiply(TinyTablesElement, TinyTablesTriple)}.
     * @param playerId
     * @return
     */
    public static TinyTablesElement finalizeMultiplication(boolean e, boolean d,
        TinyTablesTriple triple, int playerId) {
      TinyTablesElement product = triple.getC().add(triple.getB().multiply(e))
          .add(triple.getA().multiply(d));
      if (playerId == 1) {
        product = product.add(getInstance(e & d));
      }
      return product;
    }
  
    public static TinyTablesElement getInstance(boolean share) {
      return share ? TRUE : FALSE;
    }
  
    @Override
    public String toString() {
      return "TinyTablesElement[share=" + this.share + "]";
    }
  
  }
  