Skip to content

Instantly share code, notes, and snippets.

@sander
Created April 22, 2023 14:54
Show Gist options
  • Save sander/16ef9c81db9906ae2c4e12e8fc1b67ec to your computer and use it in GitHub Desktop.
Save sander/16ef9c81db9906ae2c4e12e8fc1b67ec to your computer and use it in GitHub Desktop.
Choosing base points with ECDSA
import org.bouncycastle.jce.ECNamedCurveTable;
import org.bouncycastle.jce.interfaces.ECPublicKey;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.jce.spec.ECParameterSpec;
import org.bouncycastle.jce.spec.ECPublicKeySpec;
import org.bouncycastle.math.ec.ECPoint;
import java.security.*;
import java.util.Base64;
public class ChoosingBasePointsWithECDSA {
static final ECParameterSpec P256 = ECNamedCurveTable.getParameterSpec("prime256v1");
static {
Security.addProvider(new BouncyCastleProvider());
}
static ECParameterSpec parameterSpec(ECPoint basePoint) {
return new ECParameterSpec(P256.getCurve(), basePoint, P256.getN());
}
static ECPoint point(PublicKey publicKey) {
return ((ECPublicKey) publicKey).getQ();
}
public static void main(String[] args) throws Exception {
var message = "Message to be signed".getBytes();
var generator = KeyPairGenerator.getInstance("EC", "BC");
generator.initialize(P256);
var root = generator.generateKeyPair();
generator.initialize(parameterSpec(point(root.getPublic())));
var pair = generator.generateKeyPair();
var signature = Signature.getInstance("SHA256withECDSA");
signature.initSign(pair.getPrivate());
signature.update(message);
var result = signature.sign();
signature.initVerify(pair.getPublic());
signature.update(message);
if (!signature.verify(result)) {
throw new AssertionError("signature verification failed");
}
var key = KeyFactory.getInstance("EC").generatePublic(
new ECPublicKeySpec(point(pair.getPublic()), parameterSpec(point(root.getPublic())))
);
if (!key.equals(pair.getPublic())) {
throw new AssertionError("could not reconstruct public key");
}
var encoder = Base64.getEncoder();
System.out.println("Generator: " + encoder.encodeToString(point(root.getPublic()).getEncoded(false)));
System.out.println("Public key: " + encoder.encodeToString(point(pair.getPublic()).getEncoded(false)));
System.out.println("Signature: " + encoder.encodeToString(result));
}
}
@sander
Copy link
Author

sander commented Apr 22, 2023

Example outputs:

Generator: BKvk3LSdA8wobL/3+42Pg+rrNdRpx1FTlR1+jT7hZDEZtwwfkXuV6yQ04WwGXIg1e/ZD1tamGBOMjUbGRCvg0qc=
Public key: BNxVvO5EQwfvUi/wPWrUTOnXGmddPFCd84NanqQCaHFJKu6Nx8hnCfvul5Uofoattq23S6z9+Y5WLLs+LmGXF9E=
Signature: MEUCIQDNx0B+frXy+R6Gln4C49VgKZ14IX8S2GN4tgxwwbtV7wIgPyjV6RY8SiMdSESBppgvK2eAitKkZ3jysRw7JIRi/wA=
Generator: BGo/456UyRJCNJ+zW2dunXf9VVNFHMpebAMAKTUMFhyvr3tsc8XvVHYURx5yHKC2j97jr0bfu4EfbrUxlTSsgqc=
Public key: BH0e5w/ZkSDiNUS2sdPviAl9iy5JSk9K5R1F+Ur+DeYKvig/FjIpO8bse7D+wvWsXgUAX+3MofKK5+ycIVCv0R0=
Signature: MEUCIECWmtfUPOCTT3zk59DQJ2m+hWQaM7c54pUMWrW+btdBAiEAoCESTnCwbmzKJNcL9LdDUA+P2jEomW+KR14J4qpDaK8=

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment