Skip to content

Instantly share code, notes, and snippets.

@nakov
Last active July 21, 2023 09:37
Show Gist options
  • Star 22 You must be signed in to star a gist
  • Fork 11 You must be signed in to fork a gist
  • Save nakov/b01f9434df3350bc9b1cbf9b04ddb605 to your computer and use it in GitHub Desktop.
Save nakov/b01f9434df3350bc9b1cbf9b04ddb605 to your computer and use it in GitHub Desktop.
ECDSA with secp256k1 in Java: generate ECC keys, sign, verify
import org.bouncycastle.util.encoders.Hex;
import org.web3j.crypto.*;
import java.math.BigInteger;
public class ECCExample {
public static String compressPubKey(BigInteger pubKey) {
String pubKeyYPrefix = pubKey.testBit(0) ? "03" : "02";
String pubKeyHex = pubKey.toString(16);
String pubKeyX = pubKeyHex.substring(0, 64);
return pubKeyYPrefix + pubKeyX;
}
public static void main(String[] args) throws Exception {
//BigInteger privKey = Keys.createEcKeyPair().getPrivateKey();
BigInteger privKey = new BigInteger("97ddae0f3a25b92268175400149d65d6887b9cefaf28ea2c078e05cdc15a3c0a", 16);
BigInteger pubKey = Sign.publicKeyFromPrivate(privKey);
ECKeyPair keyPair = new ECKeyPair(privKey, pubKey);
System.out.println("Private key: " + privKey.toString(16));
System.out.println("Public key: " + pubKey.toString(16));
System.out.println("Public key (compressed): " + compressPubKey(pubKey));
String msg = "Message for signing";
byte[] msgHash = Hash.sha3(msg.getBytes());
Sign.SignatureData signature = Sign.signMessage(msgHash, keyPair, false);
System.out.println("Msg: " + msg);
System.out.println("Msg hash: " + Hex.toHexString(msgHash));
System.out.printf("Signature: [v = %d, r = %s, s = %s]\n",
signature.getV() - 27,
Hex.toHexString(signature.getR()),
Hex.toHexString(signature.getS()));
System.out.println();
BigInteger pubKeyRecovered = Sign.signedMessageToKey(msg.getBytes(), signature);
System.out.println("Recovered public key: " + pubKeyRecovered.toString(16));
boolean validSig = pubKey.equals(pubKeyRecovered);
System.out.println("Signature valid? " + validSig);
}
}
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>bc-examples</groupId>
<artifactId>bc-examples</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.web3j</groupId>
<artifactId>crypto</artifactId>
<version>3.3.1</version>
</dependency>
</dependencies>
</project>
@d3ep4k
Copy link

d3ep4k commented Sep 16, 2018

java.security package contains ECDSA classes for generating the key pair, signing and verifying signatures.

https://metamug.com/article/sign-verify-digital-signature-ecdsa-java.html

@dblevins
Copy link

java.security package contains ECDSA classes for generating the key pair, signing and verifying signatures.

https://metamug.com/article/sign-verify-digital-signature-ecdsa-java.html

Java 16 removed everything but secp256r1, secp384r1, secp521r1, x25519, x448, ed25519, and ed44

@nakov
Copy link
Author

nakov commented Sep 28, 2021

I still prefer the Ethereum web3j library when I interact with Ethereum-compatible blockchains.

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