diff --git a/.gitignore b/.gitignore index 8a14b3b..1e054d9 100644 --- a/.gitignore +++ b/.gitignore @@ -64,4 +64,13 @@ nb-configuration.xml ########################## ## OS X ########################## -.DS_Store \ No newline at end of file +.DS_Store + +########################## +## Example Files +########################## +src/main/java/Generate* +message.txt +publicKey.pem +privateKey.pem +signatureBinary.txt diff --git a/README.md b/README.md index aae9f55..a5e55a4 100644 --- a/README.md +++ b/README.md @@ -19,19 +19,32 @@ We currently support `secp256k1`, but it's super easy to add more curves to the How to use it: ```java -// Generate Keys -PrivateKey privateKey = new PrivateKey(); -PublicKey publicKey = privateKey.publicKey(); +import com.starkbank.ellipticcurve.PrivateKey; +import com.starkbank.ellipticcurve.PublicKey; +import com.starkbank.ellipticcurve.Signature; +import com.starkbank.ellipticcurve.Ecdsa; -String message = "My test message"; -// Generate Signature -Signature signature = Ecsda.sign(message, privateKey); +public class GenerateKeys{ -// Verify if signature is valid -System.out.println(Ecsda.verify(message, signature, publicKey)); -``` + public static void main(String[] args){ + // Generate Keys + PrivateKey privateKey = new PrivateKey(); + PublicKey publicKey = privateKey.publicKey(); + + String message = "Testing message"; + // Generate Signature + Signature signature = Ecdsa.sign(message, privateKey); + + // Verify if signature is valid + boolean verified = Ecdsa.verify(message, signature, publicKey) ; + // Return the signature verification status + System.out.println("Verified: " + verified); + + } +} +``` ### OpenSSL This library is compatible with OpenSSL, so you can use it to generate keys: @@ -50,14 +63,31 @@ openssl dgst -sha256 -sign privateKey.pem -out signatureBinary.txt message.txt It's time to verify: ```java -String publicKeyPem = new String(Files.readAllBytes(Path.get("publicKey.pem"))); -byte[] signatureBin = Files.readAllBytes(Path.get("signatureBinary.txt")); -String message = new String(Files.readAllBytes(Path.get("message.txt"))); +import com.starkbank.ellipticcurve.Ecdsa; +import com.starkbank.ellipticcurve.PublicKey; +import com.starkbank.ellipticcurve.Signature; +import com.starkbank.ellipticcurve.utils.ByteString; +import com.starkbank.ellipticcurve.utils.File; + -PublicKey publicKey = PublicKey.fromPem(publicKeyPem); -Signature signature = Signature.fromDer(signatureBin); +public class VerifyKeys { -System.out.println(Ecdsa.verify(message, signature, publicKey)); + public static void main(String[] args){ + // Read files + String publicKeyPem = File.read("publicKey.pem"); + byte[] signatureBin = File.readBytes("signatureBinary.txt"); + String message = File.read("message.txt"); + + ByteString byteString = new ByteString(signatureBin); + + PublicKey publicKey = PublicKey.fromPem(publicKeyPem); + Signature signature = Signature.fromDer(byteString); + + // Get verification status: + boolean verified = Ecdsa.verify(message, signature, publicKey); + System.out.println("Verification status: " + verified); + } +} ``` You can also verify it on terminal: @@ -75,11 +105,21 @@ openssl base64 -in signatureBinary.txt -out signatureBase64.txt With this library, you can do it: ```java -byte[] signatureBin = Files.readAllBytes(Path.get("signatureBinary.txt")); +import com.starkbank.ellipticcurve.utils.ByteString; +import com.starkbank.ellipticcurve.Signature; +import com.starkbank.ellipticcurve.utils.File; -Signature signature = Signature.fromDer(new ByteString(signatureBin)); -System.out.println(signature.toBase64()); +public class GenerateSignature { + + public static void main(String[] args) { + // Load signature file + byte[] signaturteBin = File.readBytes("signatureBinary.txt"); + Signature signature = Signature.fromDer(new ByteString(signaturteBin)); + // Print signature + System.out.println(signature.toBase64()); + } +} ``` [Stark Bank]: https://starkbank.com @@ -96,4 +136,6 @@ System.out.println(signature.toBase64()); ``` ### Run all unit tests -gradle test \ No newline at end of file +```shell +gradle test +``` diff --git a/src/main/java/com/starkbank/ellipticcurve/Ecdsa.java b/src/main/java/com/starkbank/ellipticcurve/Ecdsa.java index 7173b8e..47b7961 100644 --- a/src/main/java/com/starkbank/ellipticcurve/Ecdsa.java +++ b/src/main/java/com/starkbank/ellipticcurve/Ecdsa.java @@ -6,7 +6,7 @@ import java.security.NoSuchAlgorithmException; -public final class Ecdsa { +public class Ecdsa { public static Signature sign(String message, PrivateKey privateKey, MessageDigest hashfunc) { byte[] hashMessage = hashfunc.digest(message.getBytes()); diff --git a/src/main/java/com/starkbank/ellipticcurve/Math.java b/src/main/java/com/starkbank/ellipticcurve/Math.java index 9b4bb0c..f2dc1a9 100644 --- a/src/main/java/com/starkbank/ellipticcurve/Math.java +++ b/src/main/java/com/starkbank/ellipticcurve/Math.java @@ -27,6 +27,7 @@ public static Point multiply(Point p, BigInteger n, BigInteger N, BigInteger A, * @param P Prime number in the module of the equation Y^2 = X^3 + A*X + B (mod P) * @return Point that represents the sum of First and Second Point */ + public static Point add(Point p, Point q, BigInteger A, BigInteger P) { return fromJacobian(jacobianAdd(toJacobian(p), toJacobian(q), A, P), P); } @@ -66,6 +67,7 @@ public static BigInteger inv(BigInteger x, BigInteger n) { * @return Point in Jacobian coordinates */ public static Point toJacobian(Point p) { + return new Point(p.x, p.y, BigInteger.ONE); } diff --git a/src/main/java/com/starkbank/ellipticcurve/utils/Base64.java b/src/main/java/com/starkbank/ellipticcurve/utils/Base64.java index 8bf5e92..0a0e66e 100644 --- a/src/main/java/com/starkbank/ellipticcurve/utils/Base64.java +++ b/src/main/java/com/starkbank/ellipticcurve/utils/Base64.java @@ -440,7 +440,7 @@ private final static byte[] getDecodabet( int options ) { /** Defeats instantiation. */ - private Base64(){} + public Base64(){} diff --git a/src/main/java/com/starkbank/ellipticcurve/utils/ByteString.java b/src/main/java/com/starkbank/ellipticcurve/utils/ByteString.java index 1d033ed..606170e 100644 --- a/src/main/java/com/starkbank/ellipticcurve/utils/ByteString.java +++ b/src/main/java/com/starkbank/ellipticcurve/utils/ByteString.java @@ -2,12 +2,7 @@ import java.io.UnsupportedEncodingException; import java.util.Arrays; -/** - * Company: SFL LLC - * Created on 20-Jan-19 - * - * @author Taron Petrosyan - */ + public class ByteString { private byte[] bytes; diff --git a/src/main/java/com/starkbank/ellipticcurve/utils/Der.java b/src/main/java/com/starkbank/ellipticcurve/utils/Der.java index bda0f05..9602122 100644 --- a/src/main/java/com/starkbank/ellipticcurve/utils/Der.java +++ b/src/main/java/com/starkbank/ellipticcurve/utils/Der.java @@ -7,11 +7,7 @@ import static com.starkbank.ellipticcurve.utils.BinaryAscii.*; -/** - * Created on 05-Jan-19 - * - * @author Taron Petrosyan - */ + public class Der { private Der() { diff --git a/src/main/java/com/starkbank/ellipticcurve/utils/File.java b/src/main/java/com/starkbank/ellipticcurve/utils/File.java new file mode 100644 index 0000000..067ebd8 --- /dev/null +++ b/src/main/java/com/starkbank/ellipticcurve/utils/File.java @@ -0,0 +1,42 @@ +package com.starkbank.ellipticcurve.utils; + +import java.io.IOException; +import java.nio.file.*; + +/* + *This class handles the fileinput types as filename string + *If using bytearray file as "signatureBinary.txt" + *Use the readByte method + **/ +public class File { + + public static String read(String fileName) + { + String content = ""; + try + { + content = new String(Files.readAllBytes(Paths.get(fileName))); + } + catch (IOException e) + { + e.printStackTrace(); + } + return content; + } + + public static byte[] readBytes(String fileName) + { + byte[] content = null; + try + { + content = Files.readAllBytes(Paths.get(fileName)); + } + catch (IOException e) + { + e.printStackTrace(); + } + + return content; + } + +} \ No newline at end of file