/** * Doubles a group element and returns the result in P3 representation. * It uses BigInteger arithmetic and the affine representation. * This method is a helper used to test the projective group doubling formula in GroupElement. * * @param g The group element. * @return g+g. */ public static GroupElement doubleGroupElement(final GroupElement g) { return addGroupElements(g, g); }
@Test public void dblPrecomputedTableContainsExpectedGroupElements() { // Arrange: GroupElement g = ed25519.getB(); GroupElement h = MathUtils.addGroupElements(g, g); // Act + Assert: for (int i=0; i<8; i++) { Assert.assertThat(MathUtils.toRepresentation(g, GroupElement.Representation.PRECOMP), IsEqual.equalTo(ed25519.getB().dblPrecmp[i])); g = MathUtils.addGroupElements(g, h); } }
/** * Calculates f1 * g1 + f2 * g2. * * @param g1 The first group element. * @param f1 The first multiplier. * @param g2 The second group element. * @param f2 The second multiplier. * @return The resulting group element. */ public static GroupElement doubleScalarMultiplyGroupElements( final GroupElement g1, final FieldElement f1, final GroupElement g2, final FieldElement f2) { final GroupElement h1 = scalarMultiplyGroupElement(g1, f1); final GroupElement h2 = scalarMultiplyGroupElement(g2, f2); return addGroupElements(h1, h2); }
@Test public void precomputedTableContainsExpectedGroupElements() { // Arrange: GroupElement g = ed25519.getB(); // Act + Assert: for (int i = 0; i < 32; i++) { GroupElement h = g; for (int j = 0; j < 8; j++) { Assert.assertThat(MathUtils.toRepresentation(h, GroupElement.Representation.PRECOMP), IsEqual.equalTo(ed25519.getB().precmp[i][j])); h = MathUtils.addGroupElements(h, g); } for (int k = 0; k < 8; k++) { g = MathUtils.addGroupElements(g, g); } } }
@Test public void addReturnsExpectedResult() { for (int i=0; i<1000; i++) { // Arrange: final GroupElement g1 = MathUtils.getRandomGroupElement(); final GroupElement g2 = MathUtils.getRandomGroupElement(); // Act: final GroupElement h1 = g1.add(g2.toCached()); final GroupElement h2 = MathUtils.addGroupElements(g1, g2); // Assert: Assert.assertThat(h2, IsEqual.equalTo(h1)); } }
/** * Scalar multiply the group element by the field element. * * @param g The group element. * @param f The field element. * @return The resulting group element. */ public static GroupElement scalarMultiplyGroupElement(final GroupElement g, final FieldElement f) { final byte[] bytes = f.toByteArray(); GroupElement h = curve.getZero(GroupElement.Representation.P3); for (int i=254; i>=0; i--) { h = doubleGroupElement(h); if (Utils.bit(bytes, i) == 1) { h = addGroupElements(h, g); } } return h; }
@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)); } }
final GroupElement h1 = addGroupElements(g, neutral); final GroupElement h2 = addGroupElements(neutral, g);