Yes, you can convert a 33-byte compressed public key into a 65-byte uncompressed public key in Java.
Here is the code to perform the operation. It is correct, robust, and only requires Java SE classes (no other libraries) - but I apologize for the implementation length.
import java.math.BigInteger; import java.util.Arrays; static final BigInteger MODULUS = new BigInteger("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", 16); static final BigInteger CURVE_A = new BigInteger("0"); static final BigInteger CURVE_B = new BigInteger("7"); // Given a 33-byte compressed public key, this returns a 65-byte uncompressed key. byte[] decompressPubkey(byte[] compKey) { // Check array length and type indicator byte if (compKey.length != 33 || compKey[0] != 2 && compKey[0] != 3) throw new IllegalArgumentException(); final byte[] xCoordBytes = Arrays.copyOfRange(compKey, 1, compKey.length); final BigInteger xCoord = new BigInteger(1, xCoordBytes); // Range [0, 2^256) BigInteger temp = xCoord.pow(2).add(CURVE_A); temp = sqrtMod(temp.add(CURVE_B)); boolean tempIsOdd = temp.testBit(0); boolean yShouldBeOdd = compKey[0] == 3; if (tempIsOdd != yShouldBeOdd) temp = temp.negate().mod(MODULUS); final BigInteger yCoord = temp; // Copy the x coordinate into the new // uncompressed key, and change the type byte byte[] result = Arrays.copyOf(compKey, 65); result[0] = 4; // Carefully copy the y coordinate into uncompressed key final byte[] yCoordBytes = yCoord.toByteArray(); for (int i = 0; i < 32 && i < yCoordBytes.length; i++) result[result.length - 1 - i] = yCoordBytes[yCoordBytes.length - 1 - i]; return result; } // Given x, this returns a value y such that y^2 % MODULUS == x. BigInteger sqrtMod(BigInteger value) { assert (MODULUS.intValue() & 3) == 3; BigInteger pow = MODULUS.add(BigInteger.ONE).shiftRight(2); BigInteger result = value.modPow(pow, MODULUS); assert result.pow(2).mod(MODULUS).equals(value); return result; }
My Bitcoin cryptography library does implement the modulo-prime field arithmetic, but it should add the functionality to decompress public keys as well...