Exemple #1
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;
    }
 public ECFieldElement multiplyPlusProduct(
     ECFieldElement b, ECFieldElement x, ECFieldElement y) {
   BigInteger ax = this.x, bx = b.toBigInteger(), xx = x.toBigInteger(), yx = y.toBigInteger();
   BigInteger ab = ax.multiply(bx);
   BigInteger xy = xx.multiply(yx);
   return new Fp(q, r, modReduce(ab.add(xy)));
 }
Exemple #3
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);
    }
Exemple #4
0
    /**
     * Decode a point on this curve from its ASN.1 encoding. The different encodings are taken
     * account of, including point compression for <code>F<sub>p</sub></code> (X9.62 s 4.2.1 pg 17).
     *
     * @return The decoded point.
     */
    public ECPoint decodePoint(byte[] encoded) {
      ECPoint p = null;

      switch (encoded[0]) {
          // infinity
        case 0x00:
          p = getInfinity();
          break;
          // compressed
        case 0x02:
        case 0x03:
          int ytilde = encoded[0] & 1;
          byte[] i = new byte[encoded.length - 1];

          System.arraycopy(encoded, 1, i, 0, i.length);

          ECFieldElement x = new ECFieldElement.Fp(this.q, new BigInteger(1, i));
          ECFieldElement alpha = x.multiply(x.square().add(a)).add(b);
          ECFieldElement beta = alpha.sqrt();

          //
          // if we can't find a sqrt we haven't got a point on the
          // curve - run!
          //
          if (beta == null) {
            throw new RuntimeException("Invalid point compression");
          }

          int bit0 = (beta.toBigInteger().testBit(0) ? 1 : 0);

          if (bit0 == ytilde) {
            p = new ECPoint.Fp(this, x, beta, true);
          } else {
            p =
                new ECPoint.Fp(
                    this, x, new ECFieldElement.Fp(this.q, q.subtract(beta.toBigInteger())), true);
          }
          break;
          // uncompressed
        case 0x04:
          // hybrid
        case 0x06:
        case 0x07:
          byte[] xEnc = new byte[(encoded.length - 1) / 2];
          byte[] yEnc = new byte[(encoded.length - 1) / 2];

          System.arraycopy(encoded, 1, xEnc, 0, xEnc.length);
          System.arraycopy(encoded, xEnc.length + 1, yEnc, 0, yEnc.length);

          p =
              new ECPoint.Fp(
                  this,
                  new ECFieldElement.Fp(this.q, new BigInteger(1, xEnc)),
                  new ECFieldElement.Fp(this.q, new BigInteger(1, yEnc)));
          break;
        default:
          throw new RuntimeException(
              "Invalid point encoding 0x" + Integer.toString(encoded[0], 16));
      }

      return p;
    }
 public ECFieldElement squarePlusProduct(ECFieldElement x, ECFieldElement y) {
   BigInteger ax = this.x, xx = x.toBigInteger(), yx = y.toBigInteger();
   BigInteger aa = ax.multiply(ax);
   BigInteger xy = xx.multiply(yx);
   return new Fp(q, r, modReduce(aa.add(xy)));
 }
 public ECFieldElement divide(ECFieldElement b) {
   return new Fp(q, r, modMult(x, modInverse(b.toBigInteger())));
 }
 public ECFieldElement subtract(ECFieldElement b) {
   return new Fp(q, r, modSubtract(x, b.toBigInteger()));
 }
 public ECFieldElement multiply(ECFieldElement b) {
   return new Fp(q, r, modMult(x, b.toBigInteger()));
 }
 public ECFieldElement add(ECFieldElement b) {
   return new Fp(q, r, modAdd(x, b.toBigInteger()));
 }
 public ECFieldElement divide(ECFieldElement b) {
   return new Fp(q, x.multiply(b.toBigInteger().modInverse(q)).mod(q));
 }
 public ECFieldElement multiply(ECFieldElement b) {
   return new Fp(q, x.multiply(b.toBigInteger()).mod(q));
 }
 public ECFieldElement subtract(ECFieldElement b) {
   return new Fp(q, x.subtract(b.toBigInteger()).mod(q));
 }
 public ECFieldElement add(ECFieldElement b) {
   return new Fp(q, x.add(b.toBigInteger()).mod(q));
 }