/** * Constant-time conditional move. * <p> * Replaces this with u if b == 1.<br> * Replaces this with this if b == 0. * <p> * Method is package private only so that tests run. * * @param u The group element to return if b == 1. * @param b in {0, 1} * @return u if b == 1; this if b == 0; Results undefined if b is not in {0, 1}. */ GroupElement cmov(final GroupElement u, final int b) { return precomp(curve, X.cmov(u.X, b), Y.cmov(u.Y, b), Z.cmov(u.Z, b)); }
public Curve(Field f, byte[] d, FieldElement I) { this.f = f; this.d = f.fromByteArray(d); this.d2 = this.d.add(this.d); this.I = I; FieldElement zero = f.ZERO; FieldElement one = f.ONE; zeroP2 = GroupElement.p2(this, zero, one, one); zeroP3 = GroupElement.p3(this, zero, one, one, zero, false); zeroP3PrecomputedDouble = GroupElement.p3(this, zero, one, one, zero, true); zeroPrecomp = GroupElement.precomp(this, one, one, zero); }
/** * Test method for {@link GroupElement#precomp(Curve, FieldElement, FieldElement, FieldElement)}. */ @Test public void testPrecomp() { final GroupElement t = GroupElement.precomp(curve, ONE, ONE, ZERO); assertThat(t.curve, is(equalTo(curve))); assertThat(t.repr, is(GroupElement.Representation.PRECOMP)); assertThat(t.X, is(ONE)); assertThat(t.Y, is(ONE)); assertThat(t.Z, is(ZERO)); assertThat(t.T, is((FieldElement) null)); }
/** * 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))); }
FieldElement xy2d = field.fromByteArray( Utils.hexToBytes(xy2dStr)); precmp[row][col] = GroupElement.precomp(curve, ypx, ymx, xy2d);
FieldElement xy2d = field.fromByteArray( Utils.hexToBytes(xy2dStr)); dblPrecmp[row] = GroupElement.precomp(curve, ypx, ymx, xy2d);
/** * 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))); } } }
switch (repr) { case PRECOMP: return precomp(this.curve, this.X, this.Y, this.Z); default: throw new IllegalArgumentException();
toFieldElement(d.multiply(new BigInteger("2")).multiply(x).multiply(y).mod(getQ()))); case PRECOMP: return GroupElement.precomp( curve, toFieldElement(y.add(x).mod(getQ())),
/** * 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; }
.cmov(this.precmp[pos][7], Utils.equal(babs, 8)); final GroupElement tminus = precomp(curve, t.Y, t.X, t.Z.negate());
/** * Constant-time conditional move. * <p> * Replaces this with $u$ if $b == 1$.<br> * Replaces this with this if $b == 0$. * <p> * Method is package private only so that tests run. * * @param u The group element to return if $b == 1$. * @param b in $\{0, 1\}$ * @return $u$ if $b == 1$; this if $b == 0$. Results undefined if $b$ is not in $\{0, 1\}$. */ GroupElement cmov(final GroupElement u, final int b) { return precomp(curve, X.cmov(u.X, b), Y.cmov(u.Y, b), Z.cmov(u.Z, b)); }
public Curve(Field f, byte[] d, FieldElement I) { this.f = f; this.d = f.fromByteArray(d); this.d2 = this.d.add(this.d); this.I = I; FieldElement zero = f.ZERO; FieldElement one = f.ONE; zeroP2 = GroupElement.p2(this, zero, one, one); zeroP3 = GroupElement.p3(this, zero, one, one, zero, false); zeroP3PrecomputedDouble = GroupElement.p3(this, zero, one, one, zero, true); zeroPrecomp = GroupElement.precomp(this, one, one, zero); }
switch (repr) { case PRECOMP: return precomp(this.curve, this.X, this.Y, this.Z); 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; }
.cmov(this.precmp[pos][7], Utils.equal(babs, 8)); final GroupElement tminus = precomp(curve, t.Y, t.X, t.Z.negate());