1
2
3
4
5
6
7 package ecdsa
8
9 import (
10 "crypto/internal/boring"
11 "crypto/internal/boring/bbig"
12 "crypto/internal/boring/bcache"
13 "math/big"
14 )
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 var pubCache bcache.Cache[PublicKey, boringPub]
30 var privCache bcache.Cache[PrivateKey, boringPriv]
31
32 func init() {
33 pubCache.Register()
34 privCache.Register()
35 }
36
37 type boringPub struct {
38 key *boring.PublicKeyECDSA
39 orig PublicKey
40 }
41
42 func boringPublicKey(pub *PublicKey) (*boring.PublicKeyECDSA, error) {
43 b := pubCache.Get(pub)
44 if b != nil && publicKeyEqual(&b.orig, pub) {
45 return b.key, nil
46 }
47
48 b = new(boringPub)
49 b.orig = copyPublicKey(pub)
50 key, err := boring.NewPublicKeyECDSA(b.orig.Curve.Params().Name, bbig.Enc(b.orig.X), bbig.Enc(b.orig.Y))
51 if err != nil {
52 return nil, err
53 }
54 b.key = key
55 pubCache.Put(pub, b)
56 return key, nil
57 }
58
59 type boringPriv struct {
60 key *boring.PrivateKeyECDSA
61 orig PrivateKey
62 }
63
64 func boringPrivateKey(priv *PrivateKey) (*boring.PrivateKeyECDSA, error) {
65 b := privCache.Get(priv)
66 if b != nil && privateKeyEqual(&b.orig, priv) {
67 return b.key, nil
68 }
69
70 b = new(boringPriv)
71 b.orig = copyPrivateKey(priv)
72 key, err := boring.NewPrivateKeyECDSA(b.orig.Curve.Params().Name, bbig.Enc(b.orig.X), bbig.Enc(b.orig.Y), bbig.Enc(b.orig.D))
73 if err != nil {
74 return nil, err
75 }
76 b.key = key
77 privCache.Put(priv, b)
78 return key, nil
79 }
80
81 func publicKeyEqual(k1, k2 *PublicKey) bool {
82 return k1.X != nil &&
83 k1.Curve.Params() == k2.Curve.Params() &&
84 k1.X.Cmp(k2.X) == 0 &&
85 k1.Y.Cmp(k2.Y) == 0
86 }
87
88 func privateKeyEqual(k1, k2 *PrivateKey) bool {
89 return publicKeyEqual(&k1.PublicKey, &k2.PublicKey) &&
90 k1.D.Cmp(k2.D) == 0
91 }
92
93 func copyPublicKey(k *PublicKey) PublicKey {
94 return PublicKey{
95 Curve: k.Curve,
96 X: new(big.Int).Set(k.X),
97 Y: new(big.Int).Set(k.Y),
98 }
99 }
100
101 func copyPrivateKey(k *PrivateKey) PrivateKey {
102 return PrivateKey{
103 PublicKey: copyPublicKey(&k.PublicKey),
104 D: new(big.Int).Set(k.D),
105 }
106 }
107
View as plain text