]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.boringcrypto] crypto/ecdsa: use unsafe.Pointer instead of atomic.Value
authorRuss Cox <rsc@golang.org>
Fri, 18 Aug 2017 13:11:40 +0000 (09:11 -0400)
committerRuss Cox <rsc@golang.org>
Sat, 19 Aug 2017 03:16:44 +0000 (03:16 +0000)
Using atomic.Value causes vet errors in code copying
PublicKey or PrivateKey structures. I don't think the errors
are accurate, but it's easier to work around them than
to change vet or change atomic.Value.

See #21504.

Change-Id: I3a3435c1fc664cc5166c81674f6f7c58dab35f21
Reviewed-on: https://go-review.googlesource.com/56671
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Adam Langley <agl@golang.org>
src/crypto/ecdsa/boring.go
src/crypto/ecdsa/ecdsa.go

index 3e59f76a1411589bbb453ef5a9f33ac356d13d44..fa15ecb850298a643023a59277cbf43c18b69320 100644 (file)
@@ -5,9 +5,10 @@
 package ecdsa
 
 import (
-       "crypto/elliptic"
        "crypto/internal/boring"
        "math/big"
+       "sync/atomic"
+       "unsafe"
 )
 
 // Cached conversions from Go PublicKey/PrivateKey to BoringCrypto.
@@ -29,81 +30,71 @@ import (
 
 type boringPub struct {
        key  *boring.PublicKeyECDSA
-       orig publicKey
-}
-
-// copy of PublicKey without the atomic.Value field, to placate vet.
-type publicKey struct {
-       elliptic.Curve
-       X, Y *big.Int
+       orig PublicKey
 }
 
 func boringPublicKey(pub *PublicKey) (*boring.PublicKeyECDSA, error) {
-       b, _ := pub.boring.Load().(boringPub)
-       if publicKeyEqual(&b.orig, pub) {
+       b := (*boringPub)(atomic.LoadPointer(&pub.boring))
+       if b != nil && publicKeyEqual(&b.orig, pub) {
                return b.key, nil
        }
 
+       b = new(boringPub)
        b.orig = copyPublicKey(pub)
        key, err := boring.NewPublicKeyECDSA(b.orig.Curve.Params().Name, b.orig.X, b.orig.Y)
        if err != nil {
                return nil, err
        }
        b.key = key
-       pub.boring.Store(b)
+       atomic.StorePointer(&pub.boring, unsafe.Pointer(b))
        return key, nil
 }
 
 type boringPriv struct {
        key  *boring.PrivateKeyECDSA
-       orig privateKey
-}
-
-// copy of PrivateKey without the atomic.Value field, to placate vet.
-type privateKey struct {
-       publicKey
-       D *big.Int
+       orig PrivateKey
 }
 
 func boringPrivateKey(priv *PrivateKey) (*boring.PrivateKeyECDSA, error) {
-       b, _ := priv.boring.Load().(boringPriv)
-       if privateKeyEqual(&b.orig, priv) {
+       b := (*boringPriv)(atomic.LoadPointer(&priv.boring))
+       if b != nil && privateKeyEqual(&b.orig, priv) {
                return b.key, nil
        }
 
+       b = new(boringPriv)
        b.orig = copyPrivateKey(priv)
        key, err := boring.NewPrivateKeyECDSA(b.orig.Curve.Params().Name, b.orig.X, b.orig.Y, b.orig.D)
        if err != nil {
                return nil, err
        }
        b.key = key
-       priv.boring.Store(b)
+       atomic.StorePointer(&priv.boring, unsafe.Pointer(b))
        return key, nil
 }
 
-func publicKeyEqual(k1 *publicKey, k2 *PublicKey) bool {
+func publicKeyEqual(k1, k2 *PublicKey) bool {
        return k1.X != nil &&
                k1.Curve.Params() == k2.Curve.Params() &&
                k1.X.Cmp(k2.X) == 0 &&
                k1.Y.Cmp(k2.Y) == 0
 }
 
-func privateKeyEqual(k1 *privateKey, k2 *PrivateKey) bool {
-       return publicKeyEqual(&k1.publicKey, &k2.PublicKey) &&
+func privateKeyEqual(k1, k2 *PrivateKey) bool {
+       return publicKeyEqual(&k1.PublicKey, &k2.PublicKey) &&
                k1.D.Cmp(k2.D) == 0
 }
 
-func copyPublicKey(k *PublicKey) publicKey {
-       return publicKey{
+func copyPublicKey(k *PublicKey) PublicKey {
+       return PublicKey{
                Curve: k.Curve,
                X:     new(big.Int).Set(k.X),
                Y:     new(big.Int).Set(k.Y),
        }
 }
 
-func copyPrivateKey(k *PrivateKey) privateKey {
-       return privateKey{
-               publicKey: copyPublicKey(&k.PublicKey),
+func copyPrivateKey(k *PrivateKey) PrivateKey {
+       return PrivateKey{
+               PublicKey: copyPublicKey(&k.PublicKey),
                D:         new(big.Int).Set(k.D),
        }
 }
index a3fa743e66421efc57b9d6ffe5e84c907841e16a..3fe1dda660a57d2d18e332bbc43358540b07d783 100644 (file)
@@ -27,7 +27,7 @@ import (
        "errors"
        "io"
        "math/big"
-       "sync/atomic"
+       "unsafe"
 )
 
 // A invertible implements fast inverse mod Curve.Params().N
@@ -50,7 +50,7 @@ type PublicKey struct {
        elliptic.Curve
        X, Y *big.Int
 
-       boring atomic.Value
+       boring unsafe.Pointer
 }
 
 // PrivateKey represents a ECDSA private key.
@@ -58,7 +58,7 @@ type PrivateKey struct {
        PublicKey
        D *big.Int
 
-       boring atomic.Value
+       boring unsafe.Pointer
 }
 
 type ecdsaSignature struct {