1
2
3
4
5 package elliptic
6
7 import (
8 "crypto/elliptic/internal/nistec"
9 "crypto/rand"
10 "math/big"
11 )
12
13
14
15
16
17
18
19
20
21
22
23 type p384Curve struct {
24 params *CurveParams
25 }
26
27 var p384 p384Curve
28 var _ Curve = p384
29
30 func initP384() {
31 p384.params = &CurveParams{
32 Name: "P-384",
33 BitSize: 384,
34
35 P: bigFromDecimal("394020061963944792122790401001436138050797392704654" +
36 "46667948293404245721771496870329047266088258938001861606973112319"),
37 N: bigFromDecimal("394020061963944792122790401001436138050797392704654" +
38 "46667946905279627659399113263569398956308152294913554433653942643"),
39 B: bigFromHex("b3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088" +
40 "f5013875ac656398d8a2ed19d2a85c8edd3ec2aef"),
41 Gx: bigFromHex("aa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741" +
42 "e082542a385502f25dbf55296c3a545e3872760ab7"),
43 Gy: bigFromHex("3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da31" +
44 "13b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5f"),
45 }
46 }
47
48 func (curve p384Curve) Params() *CurveParams {
49 return curve.params
50 }
51
52 func (curve p384Curve) IsOnCurve(x, y *big.Int) bool {
53
54
55 if x.Sign() == 0 && y.Sign() == 0 {
56 return false
57 }
58 _, ok := p384PointFromAffine(x, y)
59 return ok
60 }
61
62 func p384PointFromAffine(x, y *big.Int) (p *nistec.P384Point, ok bool) {
63
64
65
66 if x.Sign() == 0 && y.Sign() == 0 {
67 return nistec.NewP384Point(), true
68 }
69 if x.Sign() < 0 || y.Sign() < 0 {
70 return nil, false
71 }
72 if x.BitLen() > 384 || y.BitLen() > 384 {
73 return nil, false
74 }
75 p, err := nistec.NewP384Point().SetBytes(Marshal(P384(), x, y))
76 if err != nil {
77 return nil, false
78 }
79 return p, true
80 }
81
82 func p384PointToAffine(p *nistec.P384Point) (x, y *big.Int) {
83 out := p.Bytes()
84 if len(out) == 1 && out[0] == 0 {
85
86
87 return new(big.Int), new(big.Int)
88 }
89 x, y = Unmarshal(P384(), out)
90 if x == nil {
91 panic("crypto/elliptic: internal error: Unmarshal rejected a valid point encoding")
92 }
93 return x, y
94 }
95
96
97
98
99
100
101
102
103
104
105 func p384RandomPoint() (x, y *big.Int) {
106 _, x, y, err := GenerateKey(P384(), rand.Reader)
107 if err != nil {
108 panic("crypto/elliptic: failed to generate random point")
109 }
110 return x, y
111 }
112
113 func (p384Curve) Add(x1, y1, x2, y2 *big.Int) (*big.Int, *big.Int) {
114 p1, ok := p384PointFromAffine(x1, y1)
115 if !ok {
116 return p384RandomPoint()
117 }
118 p2, ok := p384PointFromAffine(x2, y2)
119 if !ok {
120 return p384RandomPoint()
121 }
122 return p384PointToAffine(p1.Add(p1, p2))
123 }
124
125 func (p384Curve) Double(x1, y1 *big.Int) (*big.Int, *big.Int) {
126 p, ok := p384PointFromAffine(x1, y1)
127 if !ok {
128 return p384RandomPoint()
129 }
130 return p384PointToAffine(p.Double(p))
131 }
132
133 func (p384Curve) ScalarMult(Bx, By *big.Int, scalar []byte) (*big.Int, *big.Int) {
134 p, ok := p384PointFromAffine(Bx, By)
135 if !ok {
136 return p384RandomPoint()
137 }
138 return p384PointToAffine(p.ScalarMult(p, scalar))
139 }
140
141 func (p384Curve) ScalarBaseMult(scalar []byte) (*big.Int, *big.Int) {
142 p := nistec.NewP384Generator()
143 return p384PointToAffine(p.ScalarMult(p, scalar))
144 }
145
View as plain text