...
1
2
3 package ecutil
4
5 import (
6 "crypto/elliptic"
7 "math/big"
8 "sync"
9
10 "github.com/lestrrat-go/jwx/jwa"
11 )
12
13
14 var curveToAlg = map[elliptic.Curve]jwa.EllipticCurveAlgorithm{}
15 var algToCurve = map[jwa.EllipticCurveAlgorithm]elliptic.Curve{}
16 var availableAlgs []jwa.EllipticCurveAlgorithm
17 var availableCrvs []elliptic.Curve
18
19 func RegisterCurve(crv elliptic.Curve, alg jwa.EllipticCurveAlgorithm) {
20 curveToAlg[crv] = alg
21 algToCurve[alg] = crv
22 availableAlgs = append(availableAlgs, alg)
23 availableCrvs = append(availableCrvs, crv)
24 }
25
26 func IsAvailable(alg jwa.EllipticCurveAlgorithm) bool {
27 _, ok := algToCurve[alg]
28 return ok
29 }
30
31 func AvailableAlgorithms() []jwa.EllipticCurveAlgorithm {
32 return availableAlgs
33 }
34
35 func AvailableCurves() []elliptic.Curve {
36 return availableCrvs
37 }
38
39 func AlgorithmForCurve(crv elliptic.Curve) (jwa.EllipticCurveAlgorithm, bool) {
40 v, ok := curveToAlg[crv]
41 return v, ok
42 }
43
44 func CurveForAlgorithm(alg jwa.EllipticCurveAlgorithm) (elliptic.Curve, bool) {
45 v, ok := algToCurve[alg]
46 return v, ok
47 }
48
49 const (
50
51 ec521BufferSize = 66
52 )
53
54 var ecpointBufferPool = sync.Pool{
55 New: func() interface{} {
56
57
58 buf := make([]byte, 0, ec521BufferSize)
59 return &buf
60 },
61 }
62
63 func getCrvFixedBuffer(size int) []byte {
64
65 buf := *(ecpointBufferPool.Get().(*[]byte))
66 if size > ec521BufferSize && cap(buf) < size {
67 buf = append(buf, make([]byte, size-cap(buf))...)
68 }
69 return buf[:size]
70 }
71
72
73 func ReleaseECPointBuffer(buf []byte) {
74 buf = buf[:cap(buf)]
75 buf[0] = 0x0
76 for i := 1; i < len(buf); i *= 2 {
77 copy(buf[i:], buf[:i])
78 }
79 buf = buf[:0]
80 ecpointBufferPool.Put(&buf)
81 }
82
83
84
85
86 func AllocECPointBuffer(v *big.Int, crv elliptic.Curve) []byte {
87
88
89
90 bits := crv.Params().BitSize
91
92
93
94 var inBytes int
95 switch bits {
96 case 224, 256, 384:
97 inBytes = bits / 8
98 case 521:
99 inBytes = ec521BufferSize
100 default:
101 inBytes = bits / 8
102 if (bits % 8) != 0 {
103 inBytes++
104 }
105 }
106
107 buf := getCrvFixedBuffer(inBytes)
108 v.FillBytes(buf)
109 return buf
110 }
111
View as plain text