Ejemplo n.º 1
0
    /**
     * Decompresses a compressed point P = (xp, yp) (X9.62 s 4.2.2).
     *
     * @param xEnc The encoding of field element xp.
     * @param ypBit ~yp, an indication bit for the decompression of yp.
     * @return the decompressed point.
     */
    private ECPoint decompressPoint(byte[] xEnc, int ypBit) {
      ECFieldElement xp =
          new ECFieldElement.F2m(this.m, this.k1, this.k2, this.k3, new BigInteger(1, xEnc));
      ECFieldElement yp = null;
      if (xp.toBigInteger().equals(ECConstants.ZERO)) {
        yp = (ECFieldElement.F2m) b;
        for (int i = 0; i < m - 1; i++) {
          yp = yp.square();
        }
      } else {
        ECFieldElement beta = xp.add(a).add(b.multiply(xp.square().invert()));
        ECFieldElement z = solveQuadradicEquation(beta);
        if (z == null) {
          throw new RuntimeException("Invalid point compression");
        }
        int zBit = 0;
        if (z.toBigInteger().testBit(0)) {
          zBit = 1;
        }
        if (zBit != ypBit) {
          z = z.add(new ECFieldElement.F2m(this.m, this.k1, this.k2, this.k3, ECConstants.ONE));
        }
        yp = xp.multiply(z);
      }

      return new ECPoint.F2m(this, xp, yp);
    }
Ejemplo n.º 2
0
    /**
     * Solves a quadratic equation <code>z<sup>2</sup> + z = beta</code>(X9.62 D.1.6) The other
     * solution is <code>z + 1</code>.
     *
     * @param beta The value to solve the qradratic equation for.
     * @return the solution for <code>z<sup>2</sup> + z = beta</code> or <code>null</code> if no
     *     solution exists.
     */
    private ECFieldElement solveQuadradicEquation(ECFieldElement beta) {
      ECFieldElement zeroElement =
          new ECFieldElement.F2m(this.m, this.k1, this.k2, this.k3, ECConstants.ZERO);

      if (beta.toBigInteger().equals(ECConstants.ZERO)) {
        return zeroElement;
      }

      ECFieldElement z = null;
      ECFieldElement gamma = zeroElement;

      Random rand = new Random();
      do {
        ECFieldElement t =
            new ECFieldElement.F2m(this.m, this.k1, this.k2, this.k3, new BigInteger(m, rand));
        z = zeroElement;
        ECFieldElement w = beta;
        for (int i = 1; i <= m - 1; i++) {
          ECFieldElement w2 = w.square();
          z = z.square().add(w2.multiply(t));
          w = w2.add(beta);
        }
        if (!w.toBigInteger().equals(ECConstants.ZERO)) {
          return null;
        }
        gamma = z.square().add(z);
      } while (gamma.toBigInteger().equals(ECConstants.ZERO));

      return z;
    }
Ejemplo n.º 3
0
    /**
     * Solves a quadratic equation <code>z<sup>2</sup> + z = beta</code>(X9.62 D.1.6) The other
     * solution is <code>z + 1</code>.
     *
     * @param beta The value to solve the quadratic equation for.
     * @return the solution for <code>z<sup>2</sup> + z = beta</code> or <code>null</code> if no
     *     solution exists.
     */
    private ECFieldElement solveQuadraticEquation(ECFieldElement beta) {
      if (beta.isZero()) {
        return beta;
      }

      ECFieldElement zeroElement = fromBigInteger(ECConstants.ZERO);

      ECFieldElement z = null;
      ECFieldElement gamma = null;

      Random rand = new Random();
      do {
        ECFieldElement t = fromBigInteger(new BigInteger(m, rand));
        z = zeroElement;
        ECFieldElement w = beta;
        for (int i = 1; i <= m - 1; i++) {
          ECFieldElement w2 = w.square();
          z = z.square().add(w2.multiply(t));
          w = w2.add(beta);
        }
        if (!w.isZero()) {
          return null;
        }
        gamma = z.square().add(z);
      } while (gamma.isZero());

      return z;
    }
 protected ECFieldElement doubleProductFromSquares(
     ECFieldElement a, ECFieldElement b, ECFieldElement aSquared, ECFieldElement bSquared) {
   /*
    * NOTE: If squaring in the field is faster than multiplication, then this is a quicker
    * way to calculate 2.A.B, if A^2 and B^2 are already known.
    */
   return a.add(b).square().subtract(aSquared).subtract(bSquared);
 }
Ejemplo n.º 5
0
    /**
     * Decompresses a compressed point P = (xp, yp) (X9.62 s 4.2.2).
     *
     * @param yTilde ~yp, an indication bit for the decompression of yp.
     * @param X1 The field element xp.
     * @return the decompressed point.
     */
    protected ECPoint decompressPoint(int yTilde, BigInteger X1) {
      ECFieldElement xp = fromBigInteger(X1);
      ECFieldElement yp = null;
      if (xp.isZero()) {
        yp = (ECFieldElement.F2m) b;
        for (int i = 0; i < m - 1; i++) {
          yp = yp.square();
        }
      } else {
        ECFieldElement beta = xp.add(a).add(b.multiply(xp.square().invert()));
        ECFieldElement z = solveQuadraticEquation(beta);
        if (z == null) {
          throw new IllegalArgumentException("Invalid point compression");
        }
        if (z.testBitZero() != (yTilde == 1)) {
          z = z.addOne();
        }

        yp = xp.multiply(z);

        switch (this.getCoordinateSystem()) {
          case COORD_LAMBDA_AFFINE:
          case COORD_LAMBDA_PROJECTIVE:
            {
              yp = yp.divide(xp).add(xp);
              break;
            }
          default:
            {
              break;
            }
        }
      }

      return new ECPoint.F2m(this, xp, yp, true);
    }
 protected ECFieldElement two(ECFieldElement x) {
   return x.add(x);
 }