I am using Golang to verify digital signatures, signed by ECDSA keys with secp256r1/scep384r1/secp521r1.
The difference in signature verification performance for secp256r1/scep384r1/secp521r1 is shocking.
For Digital signatures which are signed by key secp256r1, Golang is able to verify around 27k signatures per second.
For signatures which are signed by key secp384r1, it is able to verify around 1700 signatures per second and for signatures which are signed by key of secp521r1, just 350 signatures are being verified per second.
The difference in verification of digital signature is really huge, signature algorithm is same for all three cases i.e. SHA256withECDSA.
Sample code which is being used to verify signatures:
package main
import (
"crypto/ecdsa"
"crypto/sha256"
"encoding/asn1"
"encoding/base64"
"encoding/json"
"errors"
// "fmt"
"math/big"
"sync/atomic"
)
type ECDSASignature struct {
R, S *big.Int
}
type Envelope struct {
RawMessage json.RawMessage `json:"message"`
Message interface{} `json:"-"`
Signature string `json:"signature"`
}
func hash(b []byte) []byte {
h := sha256.New()
h.Write(b)
return h.Sum(nil)
}
func (e *Envelope) Validate(publicKey *ecdsa.PublicKey) bool{
der, err := base64.StdEncoding.DecodeString(e.Signature)
if err != nil {
return err
}
sig := &ECDSASignature{}
_, err = asn1.Unmarshal(der, sig)
if err != nil {
return err
}
h := hash(e.RawMessage)
valid := ecdsa.Verify(
publicKey,
h,
sig.R,
sig.S,
)
return valid
}
Am I missing something here? Do I need to handle secp384r1 & secp521r1 differently for verifying signatures? How can I improve performance for verification of these signatures? Is it an expected behavior in Golang for these key types?