public GroupElement[] transform(final GroupElement cloned) throws InvalidPatternException {
    // moved cloned to up
    // final GroupElement cloned = (GroupElement) and.clone();

    processTree(cloned);
    cloned.pack();

    GroupElement[] ands;
    // is top element an AND?
    if (cloned.isAnd()) {
      // Yes, so just return it
      ands = new GroupElement[] {cloned};
    } else if (cloned.isOr()) {
      // it is an OR, so each child is an AND branch
      ands = splitOr(cloned);
    } else {
      // no, so just wrap into an AND
      final GroupElement wrapper = GroupElementFactory.newAndInstance();
      wrapper.addChild(cloned);
      ands = new GroupElement[] {wrapper};
    }

    for (int i = 0; i < ands.length; i++) {
      // fix the cloned declarations
      this.fixClonedDeclarations(ands[i]);
      ands[i].setRoot(true);
    }

    return ands;
  }
 /** Test method for {@link GroupElement#cmov(GroupElement, int)}. */
 @Test
 public void testCmov() {
   GroupElement a = curve.getZero(GroupElement.Representation.PRECOMP);
   GroupElement b = GroupElement.precomp(curve, TWO, ZERO, TEN);
   assertThat(a.cmov(b, 0), is(equalTo(a)));
   assertThat(a.cmov(b, 1), is(equalTo(b)));
 }
 /**
  * Tests {@link GroupElement#GroupElement(Curve, byte[])} and {@link GroupElement#toByteArray()}
  * against valid public keys.
  */
 @Test
 public void testToAndFromByteArray() {
   GroupElement t;
   for (Ed25519TestVectors.TestTuple testCase : Ed25519TestVectors.testCases) {
     t = new GroupElement(curve, testCase.pk);
     assertThat(
         "Test case " + testCase.caseNum + " failed", t.toByteArray(), is(equalTo(testCase.pk)));
   }
 }
  @Test(expected = IllegalArgumentException.class)
  public void toCachedThrowsIfGroupElementHasP1P1Representation() {
    // Arrange:
    final GroupElement g =
        MathUtils.toRepresentation(
            MathUtils.getRandomGroupElement(), GroupElement.Representation.P1P1);

    // Assert:
    g.toCached();
  }
  @Test
  public void isOnCurveReturnsTrueForPointsOnTheCurve() {
    for (int i = 0; i < 100; i++) {
      // Arrange:
      final GroupElement g = MathUtils.getRandomGroupElement();

      // Assert:
      Assert.assertThat(g.isOnCurve(), IsEqual.equalTo(true));
    }
  }
  @Test(expected = IllegalArgumentException.class)
  public void toP3ThrowsIfGroupElementHasPrecompRepresentation() {
    // Arrange:
    final GroupElement g =
        MathUtils.toRepresentation(
            MathUtils.getRandomGroupElement(), GroupElement.Representation.PRECOMP);

    // Assert:
    g.toP3();
  }
  /**
   * Traverses a Tree, during the process it transforms Or nodes moving the upwards and it removes
   * duplicate logic statement, this does not include Not nodes.
   *
   * <p>Traversal involves three levels the graph for each iteration. The first level is the current
   * node, this node will not be transformed, instead what we are interested in are the children of
   * the current node (called the parent nodes) and the children of those parents (call the child
   * nodes).
   *
   * @param ce
   */
  protected void processTree(final GroupElement ce) throws InvalidPatternException {

    boolean hasChildOr = false;

    // first we elimininate any redundancy
    ce.pack();

    Object[] children = (Object[]) ce.getChildren().toArray();
    for (Object aChildren : children) {
      if (aChildren instanceof GroupElement) {
        final GroupElement child = (GroupElement) aChildren;

        processTree(child);
        if ((child.isOr() || child.isAnd()) && child.getType() == ce.getType()) {
          child.pack(ce);
        } else if (child.isOr()) {
          hasChildOr = true;
        }
      }
    }

    if (hasChildOr) {
      applyOrTransformation(ce);
    }
  }
Exemple #8
0
  /**
   * Traverses a Tree, during the process it transforms Or nodes moving the upwards and it removes
   * duplicate logic statement, this does not include Not nodes.
   *
   * <p>Traversal involves three levels the graph for each iteration. The first level is the current
   * node, this node will not be transformed, instead what we are interested in are the children of
   * the current node (called the parent nodes) and the children of those parents (call the child
   * nodes).
   */
  private void processTree(final GroupElement ce, boolean[] result) throws InvalidPatternException {
    boolean hasChildOr = false;

    // first we elimininate any redundancy
    ce.pack();

    for (Object child : ce.getChildren().toArray()) {
      if (child instanceof GroupElement) {
        final GroupElement group = (GroupElement) child;

        processTree(group, result);
        if ((group.isOr() || group.isAnd()) && group.getType() == ce.getType()) {
          group.pack(ce);
        } else if (group.isOr()) {
          hasChildOr = true;
        }
      } else if (child instanceof NamedConsequence) {
        result[0] = true;
      } else if (child instanceof Pattern && ((Pattern) child).getObjectType().isEvent()) {
        result[1] = true;
      }
    }

    if (hasChildOr) {
      applyOrTransformation(ce);
    }
  }
  @Test
  public void scalarMultiplyBasePointWithZeroReturnsNeutralElement() {
    // Arrange:
    final GroupElement basePoint = ed25519.getB();

    // Act:
    final GroupElement g = basePoint.scalarMultiply(curve.getField().ZERO.toByteArray());

    // Assert:
    Assert.assertThat(curve.getZero(GroupElement.Representation.P3), IsEqual.equalTo(g));
  }
Exemple #10
0
  void applyOrTransformation(final GroupElement parent) throws InvalidPatternException {
    final Transformation transformation = this.orTransformations.get(parent.getType());

    if (transformation == null) {
      throw new RuntimeException(
          "applyOrTransformation could not find transformation for parent '"
              + parent.getType()
              + "' and child 'OR'");
    }
    transformation.transform(parent);
  }
  @Test
  public void scalarMultiplyBasePointWithOneReturnsBasePoint() {
    // Arrange:
    final GroupElement basePoint = ed25519.getB();

    // Act:
    final GroupElement g = basePoint.scalarMultiply(curve.getField().ONE.toByteArray());

    // Assert:
    Assert.assertThat(basePoint, IsEqual.equalTo(g));
  }
    public void transform(final GroupElement parent) throws InvalidPatternException {
      final List orsList = new ArrayList();
      // must keep order, so, using array
      final Object[] others = new Object[parent.getChildren().size()];

      // first we split children as OR or not OR
      int permutations = 1;
      int index = 0;
      for (final RuleConditionElement child : parent.getChildren()) {
        if ((child instanceof GroupElement) && ((GroupElement) child).isOr()) {
          permutations *= ((GroupElement) child).getChildren().size();
          orsList.add(child);
        } else {
          others[index] = child;
        }
        index++;
      }

      // transform parent into an OR
      parent.setType(GroupElement.OR);
      parent.getChildren().clear();

      // prepare arrays and indexes to calculate permutation
      final GroupElement[] ors = (GroupElement[]) orsList.toArray(new GroupElement[orsList.size()]);
      final int[] indexes = new int[ors.length];

      // now we know how many permutations we will have, so create it
      for (int i = 1; i <= permutations; i++) {
        final GroupElement and = GroupElementFactory.newAndInstance();

        // create the actual permutations
        int mod = 1;
        for (int j = ors.length - 1; j >= 0; j--) {
          // we must insert at the beginning to keep the order
          and.getChildren().add(0, ors[j].getChildren().get(indexes[j]).clone());
          if ((i % mod) == 0) {
            indexes[j] = (indexes[j] + 1) % ors[j].getChildren().size();
          }
          mod *= ors[j].getChildren().size();
        }

        // elements originally outside OR will be in every permutation, so add them
        // in their original position
        for (int j = 0; j < others.length; j++) {
          if (others[j] != null) {
            // always add clone of them to avoid offset conflicts in declarations

            // HERE IS THE MESSY PROBLEM: need to change further references to the appropriate
            // cloned ref
            and.getChildren().add(j, ((RuleConditionElement) others[j]).clone());
          }
        }
        parent.addChild(and);
      }

      // remove duplications
      parent.pack();
    }
Exemple #13
0
 protected GroupElement[] splitOr(final GroupElement cloned) {
   GroupElement[] ands = new GroupElement[cloned.getChildren().size()];
   int i = 0;
   for (final RuleConditionElement branch : cloned.getChildren()) {
     if ((branch instanceof GroupElement) && (((GroupElement) branch).isAnd())) {
       ands[i++] = (GroupElement) branch;
     } else {
       ands[i] = GroupElementFactory.newAndInstance();
       ands[i].addChild(branch);
       i++;
     }
   }
   return ands;
 }
  @Test
  public void dblReturnsExpectedResult() {
    for (int i = 0; i < 1000; i++) {
      // Arrange:
      final GroupElement g = MathUtils.getRandomGroupElement();

      // Act:
      final GroupElement h1 = g.dbl();
      final GroupElement h2 = MathUtils.doubleGroupElement(g);

      // Assert:
      Assert.assertThat(h2, IsEqual.equalTo(h1));
    }
  }
  @Test
  public void subReturnsExpectedResult() {
    for (int i = 0; i < 1000; i++) {
      // Arrange:
      final GroupElement g1 = MathUtils.getRandomGroupElement();
      final GroupElement g2 = MathUtils.getRandomGroupElement();

      // Act:
      final GroupElement h1 = g1.sub(g2.toCached());
      final GroupElement h2 = MathUtils.addGroupElements(g1, MathUtils.negateGroupElement(g2));

      // Assert:
      Assert.assertThat(h2, IsEqual.equalTo(h1));
    }
  }
  @Test
  public void constructorUsingByteArrayReturnsExpectedResult() {
    for (int i = 0; i < 100; i++) {
      // Arrange:
      final GroupElement g = MathUtils.getRandomGroupElement();
      final byte[] bytes = g.toByteArray();

      // Act:
      final GroupElement h1 = new GroupElement(curve, bytes);
      final GroupElement h2 = MathUtils.toGroupElement(bytes);

      // Assert:
      Assert.assertThat(h1, IsEqual.equalTo(h2));
    }
  }
  // This test is slow (~6s) due to math utils using an inferior algorithm to calculate the result.
  @Test
  public void scalarMultiplyBasePointReturnsExpectedResult() {
    for (int i = 0; i < 100; i++) {
      // Arrange:
      final GroupElement basePoint = ed25519.getB();
      final FieldElement f = MathUtils.getRandomFieldElement();

      // Act:
      final GroupElement g = basePoint.scalarMultiply(f.toByteArray());
      final GroupElement h = MathUtils.scalarMultiplyGroupElement(basePoint, f);

      // Assert:
      Assert.assertThat(g, IsEqual.equalTo(h));
    }
  }
  @Test
  public void toByteArrayReturnsExpectedResult() {
    for (int i = 0; i < 100; i++) {
      // Arrange:
      final GroupElement g = MathUtils.getRandomGroupElement();

      // Act:
      final byte[] gBytes = g.toByteArray();
      final byte[] bytes = MathUtils.toByteArray(MathUtils.toBigInteger(g.getY()));
      if (MathUtils.toBigInteger(g.getX()).mod(new BigInteger("2")).equals(BigInteger.ONE)) {
        bytes[31] |= 0x80;
      }

      // Assert:
      Assert.assertThat(Arrays.equals(gBytes, bytes), IsEqual.equalTo(true));
    }
  }
Exemple #19
0
  private GroupElement getExtendedLhs(Rule rule, GroupElement fromChild) {
    // combine rules LHS with Parent "Extends"
    final GroupElement lhs = rule.lhsRoot.cloneOnlyGroup();
    // use the children passed from prior child rules, and combine with current LHS (at the end)
    if (null != fromChild) {
      // Have GroupElement from a child rule, so combine it
      lhs.getChildren().addAll(fromChild.getChildren());
    }
    // move recursively up the tree
    if (rule.parent != null) {
      return getExtendedLhs(rule.parent, lhs);
    }
    // at the top of the tree, return combined LHS
    // TODO Merge LHS for performace

    return lhs;
  }
Exemple #20
0
  public GroupElement[] transform(final GroupElement cloned, Map<String, Class<?>> globals)
      throws InvalidPatternException {
    // moved cloned to up
    // final GroupElement cloned = (GroupElement) and.clone();

    boolean hasNamedConsequenceAndIsStream = processTree(cloned);
    cloned.pack();

    GroupElement[] ands;
    // is top element an AND?
    if (cloned.isAnd()) {
      // Yes, so just return it
      ands = new GroupElement[] {cloned};
    } else if (cloned.isOr()) {
      // it is an OR, so each child is an AND branch
      ands = splitOr(cloned);
    } else {
      // no, so just wrap into an AND
      final GroupElement wrapper = GroupElementFactory.newAndInstance();
      wrapper.addChild(cloned);
      ands = new GroupElement[] {wrapper};
    }

    for (GroupElement and : ands) {
      // fix the cloned declarations
      this.fixClonedDeclarations(and, globals);
      and.setRoot(true);
    }

    return hasNamedConsequenceAndIsStream ? processNamedConsequences(ands) : ands;
  }
  /** Test method for {@link GroupElement#toP2()}. */
  @Test
  public void testToP2() {
    GroupElement p3zero = curve.getZero(GroupElement.Representation.P3);
    GroupElement t = p3zero.toP2();
    assertThat(t.repr, is(GroupElement.Representation.P2));
    assertThat(t.X, is(p3zero.X));
    assertThat(t.Y, is(p3zero.Y));
    assertThat(t.Z, is(p3zero.Z));
    assertThat(t.T, is((FieldElement) null));

    GroupElement B = ed25519.getB();
    t = B.toP2();
    assertThat(t.repr, is(GroupElement.Representation.P2));
    assertThat(t.X, is(B.X));
    assertThat(t.Y, is(B.Y));
    assertThat(t.Z, is(B.Z));
    assertThat(t.T, is((FieldElement) null));
  }
 /** Test method for {@link GroupElement#p2(Curve, FieldElement, FieldElement, FieldElement)}. */
 @Test
 public void testP2() {
   final GroupElement t = GroupElement.p2(curve, ZERO, ONE, ONE);
   assertThat(t.curve, is(equalTo(curve)));
   assertThat(t.repr, is(GroupElement.Representation.P2));
   assertThat(t.X, is(ZERO));
   assertThat(t.Y, is(ONE));
   assertThat(t.Z, is(ONE));
   assertThat(t.T, is((FieldElement) null));
 }
 /**
  * Test method for {@link GroupElement#cached(Curve, FieldElement, FieldElement, FieldElement,
  * FieldElement)}.
  */
 @Test
 public void testCached() {
   final GroupElement t = GroupElement.cached(curve, ONE, ONE, ONE, ZERO);
   assertThat(t.curve, is(equalTo(curve)));
   assertThat(t.repr, is(GroupElement.Representation.CACHED));
   assertThat(t.X, is(ONE));
   assertThat(t.Y, is(ONE));
   assertThat(t.Z, is(ONE));
   assertThat(t.T, is(ZERO));
 }
 /**
  * Test method for {@link GroupElement#p1p1(Curve, FieldElement, FieldElement, FieldElement,
  * FieldElement)}.
  */
 @Test
 public void testP1p1() {
   final GroupElement t = GroupElement.p1p1(curve, ZERO, ONE, ONE, ONE);
   assertThat(t.curve, is(equalTo(curve)));
   assertThat(t.repr, is(GroupElement.Representation.P1P1));
   assertThat(t.X, is(ZERO));
   assertThat(t.Y, is(ONE));
   assertThat(t.Z, is(ONE));
   assertThat(t.T, is(ONE));
 }
  // This test is slow (~6s) due to math utils using an inferior algorithm to calculate the result.
  @Test
  public void doubleScalarMultiplyVariableTimeReturnsExpectedResult() {
    for (int i = 0; i < 50; i++) {
      // Arrange:
      final GroupElement basePoint = ed25519.getB();
      final GroupElement g = MathUtils.getRandomGroupElement();
      g.precompute(false);
      final FieldElement f1 = MathUtils.getRandomFieldElement();
      final FieldElement f2 = MathUtils.getRandomFieldElement();

      // Act:
      final GroupElement h1 =
          basePoint.doubleScalarMultiplyVariableTime(g, f2.toByteArray(), f1.toByteArray());
      final GroupElement h2 = MathUtils.doubleScalarMultiplyGroupElements(basePoint, f1, g, f2);

      // Assert:
      Assert.assertThat(h1, IsEqual.equalTo(h2));
    }
  }
Exemple #26
0
 private int getSpecifity(final GroupElement ce) {
   int specificity = 0;
   for (final RuleConditionElement object : ce.getChildren()) {
     if (object instanceof Pattern) {
       specificity += getSpecifity((Pattern) object);
     } else if (object instanceof GroupElement) {
       specificity += getSpecifity((GroupElement) object);
     }
   }
   return specificity;
 }
  /** Test method for {@link GroupElement#toRadix16(byte[])}. */
  @Test
  public void testToRadix16() {
    assertThat(GroupElement.toRadix16(BYTES_ZERO), is(RADIX16_ZERO));
    assertThat(GroupElement.toRadix16(BYTES_ONE), is(RADIX16_ONE));
    assertThat(GroupElement.toRadix16(BYTES_42), is(RADIX16_42));

    byte[] from1234567890 = GroupElement.toRadix16(BYTES_1234567890);
    int total = 0;
    for (int i = 0; i < from1234567890.length; i++) {
      assertThat(from1234567890[i], is(greaterThanOrEqualTo((byte) -8)));
      assertThat(from1234567890[i], is(lessThanOrEqualTo((byte) 8)));
      total += from1234567890[i] * Math.pow(16, i);
    }
    assertThat(total, is(1234567890));

    byte[] pkrR16 = GroupElement.toRadix16(BYTES_PKR);
    for (int i = 0; i < pkrR16.length; i++) {
      assertThat(pkrR16[i], is(greaterThanOrEqualTo((byte) -8)));
      assertThat(pkrR16[i], is(lessThanOrEqualTo((byte) 8)));
    }
  }
  /**
   * Test method for {@link GroupElement#toByteArray()}. TODO 20141001 BR: why test with points
   * which are not on the curve?
   */
  @Test
  public void testToByteArray() {
    byte[] zerozero = GroupElement.p2(curve, ZERO, ZERO, ONE).toByteArray();
    assertThat(zerozero.length, is(equalTo(BYTES_ZEROZERO.length)));
    assertThat(zerozero, is(equalTo(BYTES_ZEROZERO)));

    byte[] oneone = GroupElement.p2(curve, ONE, ONE, ONE).toByteArray();
    assertThat(oneone.length, is(equalTo(BYTES_ONEONE.length)));
    assertThat(oneone, is(equalTo(BYTES_ONEONE)));

    byte[] tenzero = GroupElement.p2(curve, TEN, ZERO, ONE).toByteArray();
    assertThat(tenzero.length, is(equalTo(BYTES_TENZERO.length)));
    assertThat(tenzero, is(equalTo(BYTES_TENZERO)));

    byte[] oneten = GroupElement.p2(curve, ONE, TEN, ONE).toByteArray();
    assertThat(oneten.length, is(equalTo(BYTES_ONETEN.length)));
    assertThat(oneten, is(equalTo(BYTES_ONETEN)));

    byte[] pkr = GroupElement.p2(curve, PKR[0], PKR[1], ONE).toByteArray();
    assertThat(pkr.length, is(equalTo(BYTES_PKR.length)));
    assertThat(pkr, is(equalTo(BYTES_PKR)));
  }
  @Test
  public void isOnCurveReturnsFalseForPointsNotOnTheCurve() {
    for (int i = 0; i < 100; i++) {
      // Arrange:
      final GroupElement g = MathUtils.getRandomGroupElement();
      final GroupElement h =
          GroupElement.p2(curve, g.getX(), g.getY(), g.getZ().multiply(curve.getField().TWO));

      // Assert (can only fail for 5*Z^2=1):
      Assert.assertThat(h.isOnCurve(), IsEqual.equalTo(false));
    }
  }
Exemple #30
0
  private GroupElement[] processNamedConsequences(GroupElement[] ands) {
    List<GroupElement> result = new ArrayList<GroupElement>();

    for (GroupElement and : ands) {
      List<RuleConditionElement> children = and.getChildren();
      for (int i = 0; i < children.size(); i++) {
        RuleConditionElement child = children.get(i);
        if (child instanceof NamedConsequence) {
          GroupElement clonedAnd = GroupElementFactory.newAndInstance();
          for (int j = 0; j < i; j++) {
            clonedAnd.addChild(children.get(j).clone());
          }
          ((NamedConsequence) child).setTerminal(true);
          clonedAnd.addChild(child);
          children.remove(i--);
          result.add(clonedAnd);
        }
      }
      result.add(and);
    }

    return result.toArray(new GroupElement[result.size()]);
  }