return p3(this.curve, this.X, this.Y, this.Z, this.T); case CACHED: return cached(this.curve, this.Y.add(this.X), this.Y.subtract(this.X), this.Z, this.T.multiply(this.curve.get2D())); default: throw new IllegalArgumentException();
@Test public void toCachedReturnsExpectedResultIfGroupElementHasP3Representation() { for (int i=0; i<10; i++) { // Arrange: final GroupElement g = MathUtils.getRandomGroupElement(); // Act: final GroupElement h1 = g.toCached(); final GroupElement h2 = MathUtils.toRepresentation(g, GroupElement.Representation.CACHED); // Assert: Assert.assertThat(h1, IsEqual.equalTo(h2)); Assert.assertThat(h1.getRepresentation(), IsEqual.equalTo(GroupElement.Representation.CACHED)); Assert.assertThat(h1, IsEqual.equalTo(g)); Assert.assertThat(h1.getX(), IsEqual.equalTo(g.getY().add(g.getX()))); Assert.assertThat(h1.getY(), IsEqual.equalTo(g.getY().subtract(g.getX()))); Assert.assertThat(h1.getZ(), IsEqual.equalTo(g.getZ())); Assert.assertThat(h1.getT(), IsEqual.equalTo(g.getT().multiply(curve.get2D()))); } }
/** * Precomputes table for {@link #doubleScalarMultiplyVariableTime(GroupElement, byte[], byte[])}. * @since 0.9.36 split out from precompute() */ private GroupElement[] precomputeDouble() { // Precomputation for double scalar multiplication. // P,3P,5P,7P,9P,11P,13P,15P GroupElement[] dblPrecmp = new GroupElement[8]; GroupElement Bi = this; for (int i = 0; i < 8; i++) { final FieldElement recip = Bi.Z.invert(); final FieldElement x = Bi.X.multiply(recip); final FieldElement y = Bi.Y.multiply(recip); dblPrecmp[i] = precomp(this.curve, y.add(x), y.subtract(x), x.multiply(y).multiply(this.curve.get2D())); // Bi = edwards(B,edwards(B,Bi)) Bi = this.add(this.add(Bi.toCached()).toP3().toCached()).toP3(); } return dblPrecmp; }
/** * Precomputes table for {@link #scalarMultiply(byte[])}. * @since 0.9.36 split out from precompute() */ private GroupElement[][] precomputeSingle() { // Precomputation for single scalar multiplication. GroupElement[][] precmp = new GroupElement[32][8]; // TODO-CR BR: check that this == base point when the method is called. GroupElement Bi = this; for (int i = 0; i < 32; i++) { GroupElement Bij = Bi; for (int j = 0; j < 8; j++) { final FieldElement recip = Bij.Z.invert(); final FieldElement x = Bij.X.multiply(recip); final FieldElement y = Bij.Y.multiply(recip); precmp[i][j] = precomp(this.curve, y.add(x), y.subtract(x), x.multiply(y).multiply(this.curve.get2D())); Bij = Bij.add(Bi.toCached()).toP3(); } // Only every second summand is precomputed (16^2 = 256) for (int k = 0; k < 8; k++) { Bi = Bi.add(Bi.toCached()).toP3(); } } return precmp; }
return p3(this.curve, this.X, this.Y, this.Z, this.T); case CACHED: return cached(this.curve, this.Y.add(this.X), this.Y.subtract(this.X), this.Z, this.T.multiply(this.curve.get2D())); default: throw new IllegalArgumentException();
/** * Precomputes table for {@link #doubleScalarMultiplyVariableTime(GroupElement, byte[], byte[])}. */ private GroupElement[] precomputeDouble() { // Precomputation for double scalar multiplication. // P,3P,5P,7P,9P,11P,13P,15P GroupElement[] dblPrecmp = new GroupElement[8]; GroupElement Bi = this; for (int i = 0; i < 8; i++) { final FieldElement recip = Bi.Z.invert(); final FieldElement x = Bi.X.multiply(recip); final FieldElement y = Bi.Y.multiply(recip); dblPrecmp[i] = precomp(this.curve, y.add(x), y.subtract(x), x.multiply(y).multiply(this.curve.get2D())); // Bi = edwards(B,edwards(B,Bi)) Bi = this.add(this.add(Bi.toCached()).toP3().toCached()).toP3(); } return dblPrecmp; }
/** * Precomputes table for {@link #scalarMultiply(byte[])}. */ private GroupElement[][] precomputeSingle() { // Precomputation for single scalar multiplication. GroupElement[][] precmp = new GroupElement[32][8]; // TODO-CR BR: check that this == base point when the method is called. GroupElement Bi = this; for (int i = 0; i < 32; i++) { GroupElement Bij = Bi; for (int j = 0; j < 8; j++) { final FieldElement recip = Bij.Z.invert(); final FieldElement x = Bij.X.multiply(recip); final FieldElement y = Bij.Y.multiply(recip); precmp[i][j] = precomp(this.curve, y.add(x), y.subtract(x), x.multiply(y).multiply(this.curve.get2D())); Bij = Bij.add(Bi.toCached()).toP3(); } // Only every second summand is precomputed (16^2 = 256) for (int k = 0; k < 8; k++) { Bi = Bi.add(Bi.toCached()).toP3(); } } return precmp; }