ECDSA Signature Verification Performance in Java

913 Views Asked by At

I am trying to calculate the performance of ECDSA signature verification in Java for secp521r1 curve. I am getting around 3000 signature verification per second.

Adding my other work also, I tested with openssl speed command for secp521r1 curve, there I got around 9000 verification on my machine (40 cores). I tested with Golang also but the performance with secp521r1 is not good, though the performance with secp256r1 is great(28000 verification per second). I reached out to Golang community and found 256 is hand optimized but other curves are not.

I also tested with nodeJs to verify signature, there I got 9000 verification per second which is similar to Openssl. By checking the source code of nodeJs crypto module implementation, I found they are using openssl like implementation.

But I have to work on Java only, so reaching out to the community. Is this the usual result in Java or do we have any openssl like implementation in Java as well?

Dummy Code==========================

package dummy;

import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.math.BigInteger;
import java.security.InvalidAlgorithmParameterException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Security;
import java.security.Signature;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

import org.bouncycastle.asn1.DERInteger;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.io.pem.PemObject;
import org.bouncycastle.util.io.pem.PemReader;
import org.json.JSONObject;

public class DSA {
    static JSONObject ob = new JSONObject();
    static byte[] strByte = null;
    static byte[] realSig;
    static String str = "a";//"{\"type\":\"issueTx\",\"userId\":1,\"transaction\":{\"amount\":1000}}"; /a
    static byte[] sigdata;
    static String sigEdata;
    static X509Certificate c;
    static String sigTestSigneddata;

    public static void main(String[] args)
            throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, IOException {

        try {


            KeyPairGenerator keyGen = KeyPairGenerator.getInstance("EC");
            keyGen.initialize(new ECGenParameterSpec("secp521r1"), new SecureRandom());

            KeyPair pair = keyGen.generateKeyPair();
            PrivateKey priv = pair.getPrivate();
            PublicKey pub = pair.getPublic();
            FileWriter fw = new FileWriter("MyKeys/n.pem");
            PemWriter writer = new PemWriter(fw);
            writer.writeObject(new PemObject("PUBLIC KEY", pub.getEncoded()));
            writer.close();
            FileWriter fw2 = new FileWriter("MyKeys/n_sk");
            PemWriter writer2 = new PemWriter(fw2);
            writer2.writeObject(new PemObject("PRIVATE KEY ", priv.getEncoded()));
            writer2.close();

            Security.addProvider(new BouncyCastleProvider());
            Signature ecdsa;

            ecdsa = Signature.getInstance("SHA256withECDSA"); // SHA512WITHECDSA SHA512withECDSA
            ecdsa.initSign(getPrivate("MyKeys/n_sk"));

            strByte = str.getBytes("UTF-8");
            ecdsa.update(strByte);
            realSig = ecdsa.sign();

            sigEdata = Base64.getEncoder().encodeToString(realSig);

            Thread.sleep(1000);
             verify();

        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public static void verify() throws Exception {

        verifySignature();

    }

    private static void verifySignature() throws Exception {
    
        Signature sig = Signature.getInstance("SHA256withECDSA", "BC"); // SHA256withECDSA // SHA512withECDSA

        // sig.initVerify(c.getPublicKey()); to verify using digi cert
        sig.initVerify(getPublic("MyKeys/n.pem"));
        sig.update(str.getBytes());
        System.out.println(sig.verify(Base64.getDecoder().decode(sigEdata)));

        // sig.verify(sigEdata.getBytes(Charset.defaultCharset()));
        System.out.println(str);

    }

    private static PrivateKey getPrivate(String filename) throws Exception {

        PemReader reader = new PemReader(new FileReader(filename));
        PemObject pemObject = reader.readPemObject();
        byte[] content = pemObject.getContent();
        reader.close();
        PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(content);
        KeyFactory kf = KeyFactory.getInstance("EC");
        return kf.generatePrivate(spec);
    }

    

    private static PublicKey getPublic(String filename) throws Exception {

        PemReader reader = new PemReader(new FileReader(filename));
        PemObject pemObject = reader.readPemObject();
        byte[] content = pemObject.getContent();
        reader.close();
        X509EncodedKeySpec spec = new X509EncodedKeySpec(content);
        KeyFactory kf = KeyFactory.getInstance("EC");
        return kf.generatePublic(spec);
    }
    
    
}
0

There are 0 best solutions below