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>
@nakov
Copy link
Author

nakov commented Apr 5, 2018

The expected output is as follows:

Private key: 97ddae0f3a25b92268175400149d65d6887b9cefaf28ea2c078e05cdc15a3c0a
Public key: 7b83ad6afb1209f3c82ebeb08c0c5fa9bf6724548506f2fb4f991e2287a77090177316ca82b0bdf70cd9dee145c3002c0da1d92626449875972a27807b73b42e
Public key (compressed): 027b83ad6afb1209f3c82ebeb08c0c5fa9bf6724548506f2fb4f991e2287a77090
Msg: Message for signing
Msg hash: ce7df6b1b2852c5c156b683a9f8d4a8daeda2f35f025cb0cf34943dcac70d6a3
Signature: [v = 1, r = 6f0156091cbe912f2d5d1215cc3cd81c0963c8839b93af60e0921b61a19c5430, s = 0c71006dd93f3508c432daca21db0095f4b16542782b7986f48a5d0ae3c583d4]

Recovered public key: 7b83ad6afb1209f3c82ebeb08c0c5fa9bf6724548506f2fb4f991e2287a77090177316ca82b0bdf70cd9dee145c3002c0da1d92626449875972a27807b73b42e
Signature valid? true

@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