@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); } }
@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 scalarMultiplyBasePointWithOneReturnsBasePoint() { // Arrange: final GroupElement basePoint = ed25519.getB(); // Act: final GroupElement g = basePoint.scalarMultiply(curve.getField().ONE.toByteArray()); // Assert: Assert.assertThat(basePoint, IsEqual.equalTo(g)); }
@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)); }
/** * Test method for {@link GroupElement#scalarMultiply(byte[])}. Test values generated with Python * Ed25519 implementation. */ @Test public void testScalarMultiplyByteArray() { // Little-endian byte[] zero = Utils.hexToBytes("0000000000000000000000000000000000000000000000000000000000000000"); byte[] one = Utils.hexToBytes("0100000000000000000000000000000000000000000000000000000000000000"); byte[] two = Utils.hexToBytes("0200000000000000000000000000000000000000000000000000000000000000"); byte[] a = Utils.hexToBytes("d072f8dd9c07fa7bc8d22a4b325d26301ee9202f6db89aa7c3731529e37e437c"); GroupElement A = new GroupElement( curve, Utils.hexToBytes("d4cf8595571830644bd14af416954d09ab7159751ad9e0f7a6cbd92379e71a66")); assertThat( "scalarMultiply(0) failed", ed25519.getB().scalarMultiply(zero), is(equalTo(curve.getZero(GroupElement.Representation.P3)))); assertThat( "scalarMultiply(1) failed", ed25519.getB().scalarMultiply(one), is(equalTo(ed25519.getB()))); assertThat( "scalarMultiply(2) failed", ed25519.getB().scalarMultiply(two), is(equalTo(ed25519.getB().dbl()))); assertThat("scalarMultiply(a) failed", ed25519.getB().scalarMultiply(a), is(equalTo(A))); }
// 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 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)); }
// 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)); } }
@Test public void testDoubleScalarMultiplyVariableTime() { // Little-endian byte[] zero = Utils.hexToBytes("0000000000000000000000000000000000000000000000000000000000000000"); byte[] one = Utils.hexToBytes("0100000000000000000000000000000000000000000000000000000000000000"); byte[] two = Utils.hexToBytes("0200000000000000000000000000000000000000000000000000000000000000"); byte[] a = Utils.hexToBytes("d072f8dd9c07fa7bc8d22a4b325d26301ee9202f6db89aa7c3731529e37e437c"); GroupElement A = new GroupElement( curve, Utils.hexToBytes("d4cf8595571830644bd14af416954d09ab7159751ad9e0f7a6cbd92379e71a66")); GroupElement B = ed25519.getB(); GroupElement geZero = curve.getZero(GroupElement.Representation.P3); geZero.precompute(false); // 0 * GE(0) + 0 * GE(0) = GE(0) assertThat(geZero.doubleScalarMultiplyVariableTime(geZero, zero, zero), is(equalTo(geZero))); // 0 * GE(0) + 0 * B = GE(0) assertThat(B.doubleScalarMultiplyVariableTime(geZero, zero, zero), is(equalTo(geZero))); // 1 * GE(0) + 0 * B = GE(0) assertThat(B.doubleScalarMultiplyVariableTime(geZero, one, zero), is(equalTo(geZero))); // 1 * GE(0) + 1 * B = B assertThat(B.doubleScalarMultiplyVariableTime(geZero, one, one), is(equalTo(B))); // 1 * B + 1 * B = 2 * B assertThat(B.doubleScalarMultiplyVariableTime(B, one, one), is(equalTo(B.dbl()))); // 1 * B + 2 * B = 3 * B assertThat( B.doubleScalarMultiplyVariableTime(B, one, two), is(equalTo(B.dbl().toP3().add(B.toCached())))); // 2 * B + 2 * B = 4 * B assertThat(B.doubleScalarMultiplyVariableTime(B, two, two), is(equalTo(B.dbl().toP3().dbl()))); // 0 * B + a * B = A assertThat(B.doubleScalarMultiplyVariableTime(B, zero, a), is(equalTo(A))); // a * B + 0 * B = A assertThat(B.doubleScalarMultiplyVariableTime(B, a, zero), is(equalTo(A))); // a * B + a * B = 2 * A assertThat(B.doubleScalarMultiplyVariableTime(B, a, a), is(equalTo(A.dbl()))); }
/** Test method for {@link GroupElement#select(int, int)}. */ @Test public void testSelect() { GroupElement B = ed25519.getB(); for (int i = 0; i < 32; i++) { // 16^i 0 B assertThat( i + ",0", B.select(i, 0), is(equalTo(GroupElement.precomp(curve, ONE, ONE, ZERO)))); for (int j = 1; j < 8; j++) { // 16^i r_i B GroupElement t = B.select(i, j); assertThat(i + "," + j, t, is(equalTo(B.precmp[i][j - 1]))); // -16^i r_i B t = B.select(i, -j); GroupElement neg = GroupElement.precomp( curve, B.precmp[i][j - 1].Y, B.precmp[i][j - 1].X, B.precmp[i][j - 1].Z.negate()); assertThat(i + "," + -j, t, is(equalTo(neg))); } } }
/** Test method for {@link GroupElement#dbl()}. */ @Test public void testDbl() { GroupElement B = ed25519.getB(); // 2 * B = B + B assertThat(B.dbl(), is(equalTo(B.add(B.toCached())))); }
/** Test method for {@link GroupElement#precompute(boolean)}. */ @Test public void testPrecompute() { GroupElement B = ed25519.getB(); assertThat(B.precmp, is(equalTo(PrecomputationTestVectors.testPrecmp))); assertThat(B.dblPrecmp, is(equalTo(PrecomputationTestVectors.testDblPrecmp))); }