protected ECPoint decompressPoint(int yTilde, BigInteger X1) { ECFieldElement x = fromBigInteger(X1); ECFieldElement alpha = x.square().add(a).multiply(x).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"); } if (beta.testBitZero() != (yTilde == 1)) { // Use the other root beta = beta.negate(); } return new ECPoint.Fp(this, x, beta, true); }
/** * 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); }