5
5
package ecdsa
6
6
7
7
import (
8
- "crypto/elliptic"
9
8
"crypto/internal/boring"
10
9
"math/big"
10
+ "sync/atomic"
11
+ "unsafe"
11
12
)
12
13
13
14
// Cached conversions from Go PublicKey/PrivateKey to BoringCrypto.
@@ -29,81 +30,71 @@ import (
29
30
30
31
type boringPub struct {
31
32
key * boring.PublicKeyECDSA
32
- orig publicKey
33
- }
34
-
35
- // copy of PublicKey without the atomic.Value field, to placate vet.
36
- type publicKey struct {
37
- elliptic.Curve
38
- X , Y * big.Int
33
+ orig PublicKey
39
34
}
40
35
41
36
func boringPublicKey (pub * PublicKey ) (* boring.PublicKeyECDSA , error ) {
42
- b , _ := pub . boring . Load ().( boringPub )
43
- if publicKeyEqual (& b .orig , pub ) {
37
+ b := ( * boringPub )( atomic . LoadPointer ( & pub . boring ) )
38
+ if b != nil && publicKeyEqual (& b .orig , pub ) {
44
39
return b .key , nil
45
40
}
46
41
42
+ b = new (boringPub )
47
43
b .orig = copyPublicKey (pub )
48
44
key , err := boring .NewPublicKeyECDSA (b .orig .Curve .Params ().Name , b .orig .X , b .orig .Y )
49
45
if err != nil {
50
46
return nil , err
51
47
}
52
48
b .key = key
53
- pub .boring . Store ( b )
49
+ atomic . StorePointer ( & pub .boring , unsafe . Pointer ( b ) )
54
50
return key , nil
55
51
}
56
52
57
53
type boringPriv struct {
58
54
key * boring.PrivateKeyECDSA
59
- orig privateKey
60
- }
61
-
62
- // copy of PrivateKey without the atomic.Value field, to placate vet.
63
- type privateKey struct {
64
- publicKey
65
- D * big.Int
55
+ orig PrivateKey
66
56
}
67
57
68
58
func boringPrivateKey (priv * PrivateKey ) (* boring.PrivateKeyECDSA , error ) {
69
- b , _ := priv . boring . Load ().( boringPriv )
70
- if privateKeyEqual (& b .orig , priv ) {
59
+ b := ( * boringPriv )( atomic . LoadPointer ( & priv . boring ) )
60
+ if b != nil && privateKeyEqual (& b .orig , priv ) {
71
61
return b .key , nil
72
62
}
73
63
64
+ b = new (boringPriv )
74
65
b .orig = copyPrivateKey (priv )
75
66
key , err := boring .NewPrivateKeyECDSA (b .orig .Curve .Params ().Name , b .orig .X , b .orig .Y , b .orig .D )
76
67
if err != nil {
77
68
return nil , err
78
69
}
79
70
b .key = key
80
- priv .boring . Store ( b )
71
+ atomic . StorePointer ( & priv .boring , unsafe . Pointer ( b ) )
81
72
return key , nil
82
73
}
83
74
84
- func publicKeyEqual (k1 * publicKey , k2 * PublicKey ) bool {
75
+ func publicKeyEqual (k1 , k2 * PublicKey ) bool {
85
76
return k1 .X != nil &&
86
77
k1 .Curve .Params () == k2 .Curve .Params () &&
87
78
k1 .X .Cmp (k2 .X ) == 0 &&
88
79
k1 .Y .Cmp (k2 .Y ) == 0
89
80
}
90
81
91
- func privateKeyEqual (k1 * privateKey , k2 * PrivateKey ) bool {
92
- return publicKeyEqual (& k1 .publicKey , & k2 .PublicKey ) &&
82
+ func privateKeyEqual (k1 , k2 * PrivateKey ) bool {
83
+ return publicKeyEqual (& k1 .PublicKey , & k2 .PublicKey ) &&
93
84
k1 .D .Cmp (k2 .D ) == 0
94
85
}
95
86
96
- func copyPublicKey (k * PublicKey ) publicKey {
97
- return publicKey {
87
+ func copyPublicKey (k * PublicKey ) PublicKey {
88
+ return PublicKey {
98
89
Curve : k .Curve ,
99
90
X : new (big.Int ).Set (k .X ),
100
91
Y : new (big.Int ).Set (k .Y ),
101
92
}
102
93
}
103
94
104
- func copyPrivateKey (k * PrivateKey ) privateKey {
105
- return privateKey {
106
- publicKey : copyPublicKey (& k .PublicKey ),
95
+ func copyPrivateKey (k * PrivateKey ) PrivateKey {
96
+ return PrivateKey {
97
+ PublicKey : copyPublicKey (& k .PublicKey ),
107
98
D : new (big.Int ).Set (k .D ),
108
99
}
109
100
}
0 commit comments