diff options
Diffstat (limited to 'src/crypto/ecdsa/ecdsa.go')
-rw-r--r-- | src/crypto/ecdsa/ecdsa.go | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/src/crypto/ecdsa/ecdsa.go b/src/crypto/ecdsa/ecdsa.go index 9f9a09a884..c1dd32a2d8 100644 --- a/src/crypto/ecdsa/ecdsa.go +++ b/src/crypto/ecdsa/ecdsa.go @@ -34,6 +34,11 @@ import ( "golang.org/x/crypto/cryptobyte/asn1" ) +import ( + "crypto/internal/boring" + "unsafe" +) + // A invertible implements fast inverse in GF(N). type invertible interface { // Inverse returns the inverse of k mod Params().N. @@ -54,6 +59,8 @@ const ( type PublicKey struct { elliptic.Curve X, Y *big.Int + + boring unsafe.Pointer } // Any methods implemented on PublicKey might need to also be implemented on @@ -81,6 +88,8 @@ func (pub *PublicKey) Equal(x crypto.PublicKey) bool { type PrivateKey struct { PublicKey D *big.Int + + boring unsafe.Pointer } // Public returns the public key corresponding to priv. @@ -107,6 +116,15 @@ func (priv *PrivateKey) Equal(x crypto.PrivateKey) bool { // where the private part is kept in, for example, a hardware module. Common // uses can use the SignASN1 function in this package directly. func (priv *PrivateKey) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) ([]byte, error) { + if boring.Enabled && rand == boring.RandReader { + b, err := boringPrivateKey(priv) + if err != nil { + return nil, err + } + return boring.SignMarshalECDSA(b, digest) + } + boring.UnreachableExceptTests() + r, s, err := Sign(rand, priv, digest) if err != nil { return nil, err @@ -143,6 +161,15 @@ func randFieldElement(c elliptic.Curve, rand io.Reader) (k *big.Int, err error) // GenerateKey generates a public and private key pair. func GenerateKey(c elliptic.Curve, rand io.Reader) (*PrivateKey, error) { + if boring.Enabled && rand == boring.RandReader { + x, y, d, err := boring.GenerateKeyECDSA(c.Params().Name) + if err != nil { + return nil, err + } + return &PrivateKey{PublicKey: PublicKey{Curve: c, X: x, Y: y}, D: d}, nil + } + boring.UnreachableExceptTests() + k, err := randFieldElement(c, rand) if err != nil { return nil, err @@ -194,6 +221,15 @@ var errZeroParam = errors.New("zero parameter") func Sign(rand io.Reader, priv *PrivateKey, hash []byte) (r, s *big.Int, err error) { randutil.MaybeReadByte(rand) + if boring.Enabled && rand == boring.RandReader { + b, err := boringPrivateKey(priv) + if err != nil { + return nil, nil, err + } + return boring.SignECDSA(b, hash) + } + boring.UnreachableExceptTests() + // This implementation derives the nonce from an AES-CTR CSPRNG keyed by: // // SHA2-512(priv.D || entropy || hash)[:32] @@ -290,6 +326,15 @@ func SignASN1(rand io.Reader, priv *PrivateKey, hash []byte) ([]byte, error) { // return value records whether the signature is valid. Most applications should // use VerifyASN1 instead of dealing directly with r, s. func Verify(pub *PublicKey, hash []byte, r, s *big.Int) bool { + if boring.Enabled { + b, err := boringPublicKey(pub) + if err != nil { + return false + } + return boring.VerifyECDSA(b, hash, r, s) + } + boring.UnreachableExceptTests() + c := pub.Curve N := c.Params().N |