1 package ed25519
2
3 import fp "github.com/cloudflare/circl/math/fp25519"
4
5 type (
6 pointR1 struct{ x, y, z, ta, tb fp.Elt }
7 pointR2 struct {
8 pointR3
9 z2 fp.Elt
10 }
11 )
12 type pointR3 struct{ addYX, subYX, dt2 fp.Elt }
13
14 func (P *pointR1) neg() {
15 fp.Neg(&P.x, &P.x)
16 fp.Neg(&P.ta, &P.ta)
17 }
18
19 func (P *pointR1) SetIdentity() {
20 P.x = fp.Elt{}
21 fp.SetOne(&P.y)
22 fp.SetOne(&P.z)
23 P.ta = fp.Elt{}
24 P.tb = fp.Elt{}
25 }
26
27 func (P *pointR1) toAffine() {
28 fp.Inv(&P.z, &P.z)
29 fp.Mul(&P.x, &P.x, &P.z)
30 fp.Mul(&P.y, &P.y, &P.z)
31 fp.Modp(&P.x)
32 fp.Modp(&P.y)
33 fp.SetOne(&P.z)
34 P.ta = P.x
35 P.tb = P.y
36 }
37
38 func (P *pointR1) ToBytes(k []byte) error {
39 P.toAffine()
40 var x [fp.Size]byte
41 err := fp.ToBytes(k[:fp.Size], &P.y)
42 if err != nil {
43 return err
44 }
45 err = fp.ToBytes(x[:], &P.x)
46 if err != nil {
47 return err
48 }
49 b := x[0] & 1
50 k[paramB-1] = k[paramB-1] | (b << 7)
51 return nil
52 }
53
54 func (P *pointR1) FromBytes(k []byte) bool {
55 if len(k) != paramB {
56 panic("wrong size")
57 }
58 signX := k[paramB-1] >> 7
59 copy(P.y[:], k[:fp.Size])
60 P.y[fp.Size-1] &= 0x7F
61 p := fp.P()
62 if !isLessThan(P.y[:], p[:]) {
63 return false
64 }
65
66 one, u, v := &fp.Elt{}, &fp.Elt{}, &fp.Elt{}
67 fp.SetOne(one)
68 fp.Sqr(u, &P.y)
69 fp.Mul(v, u, ¶mD)
70 fp.Sub(u, u, one)
71 fp.Add(v, v, one)
72 isQR := fp.InvSqrt(&P.x, u, v)
73 if !isQR {
74 return false
75 }
76 fp.Modp(&P.x)
77 if fp.IsZero(&P.x) && signX == 1 {
78 return false
79 }
80 if signX != (P.x[0] & 1) {
81 fp.Neg(&P.x, &P.x)
82 }
83 P.ta = P.x
84 P.tb = P.y
85 fp.SetOne(&P.z)
86 return true
87 }
88
89
90 func (P *pointR1) double() {
91 Px, Py, Pz, Pta, Ptb := &P.x, &P.y, &P.z, &P.ta, &P.tb
92 a, b, c, e, f, g, h := Px, Py, Pz, Pta, Px, Py, Ptb
93 fp.Add(e, Px, Py)
94 fp.Sqr(a, Px)
95 fp.Sqr(b, Py)
96 fp.Sqr(c, Pz)
97 fp.Add(c, c, c)
98 fp.Add(h, a, b)
99 fp.Sqr(e, e)
100 fp.Sub(e, e, h)
101 fp.Sub(g, b, a)
102 fp.Sub(f, c, g)
103 fp.Mul(Pz, f, g)
104 fp.Mul(Px, e, f)
105 fp.Mul(Py, g, h)
106 }
107
108 func (P *pointR1) mixAdd(Q *pointR3) {
109 fp.Add(&P.z, &P.z, &P.z)
110 P.coreAddition(Q)
111 }
112
113 func (P *pointR1) add(Q *pointR2) {
114 fp.Mul(&P.z, &P.z, &Q.z2)
115 P.coreAddition(&Q.pointR3)
116 }
117
118
119 func (P *pointR1) coreAddition(Q *pointR3) {
120 Px, Py, Pz, Pta, Ptb := &P.x, &P.y, &P.z, &P.ta, &P.tb
121 addYX2, subYX2, dt2 := &Q.addYX, &Q.subYX, &Q.dt2
122 a, b, c, d, e, f, g, h := Px, Py, &fp.Elt{}, Pz, Pta, Px, Py, Ptb
123 fp.Mul(c, Pta, Ptb)
124 fp.Sub(h, Py, Px)
125 fp.Add(b, Py, Px)
126 fp.Mul(a, h, subYX2)
127 fp.Mul(b, b, addYX2)
128 fp.Mul(c, c, dt2)
129 fp.Sub(e, b, a)
130 fp.Add(h, b, a)
131 fp.Sub(f, d, c)
132 fp.Add(g, d, c)
133 fp.Mul(Pz, f, g)
134 fp.Mul(Px, e, f)
135 fp.Mul(Py, g, h)
136 }
137
138 func (P *pointR1) oddMultiples(T []pointR2) {
139 var R pointR2
140 n := len(T)
141 T[0].fromR1(P)
142 _2P := *P
143 _2P.double()
144 R.fromR1(&_2P)
145 for i := 1; i < n; i++ {
146 P.add(&R)
147 T[i].fromR1(P)
148 }
149 }
150
151 func (P *pointR1) isEqual(Q *pointR1) bool {
152 l, r := &fp.Elt{}, &fp.Elt{}
153 fp.Mul(l, &P.x, &Q.z)
154 fp.Mul(r, &Q.x, &P.z)
155 fp.Sub(l, l, r)
156 b := fp.IsZero(l)
157 fp.Mul(l, &P.y, &Q.z)
158 fp.Mul(r, &Q.y, &P.z)
159 fp.Sub(l, l, r)
160 b = b && fp.IsZero(l)
161 fp.Mul(l, &P.ta, &P.tb)
162 fp.Mul(l, l, &Q.z)
163 fp.Mul(r, &Q.ta, &Q.tb)
164 fp.Mul(r, r, &P.z)
165 fp.Sub(l, l, r)
166 b = b && fp.IsZero(l)
167 return b
168 }
169
170 func (P *pointR3) neg() {
171 P.addYX, P.subYX = P.subYX, P.addYX
172 fp.Neg(&P.dt2, &P.dt2)
173 }
174
175 func (P *pointR2) fromR1(Q *pointR1) {
176 fp.Add(&P.addYX, &Q.y, &Q.x)
177 fp.Sub(&P.subYX, &Q.y, &Q.x)
178 fp.Mul(&P.dt2, &Q.ta, &Q.tb)
179 fp.Mul(&P.dt2, &P.dt2, ¶mD)
180 fp.Add(&P.dt2, &P.dt2, &P.dt2)
181 fp.Add(&P.z2, &Q.z, &Q.z)
182 }
183
184 func (P *pointR3) cneg(b int) {
185 t := &fp.Elt{}
186 fp.Cswap(&P.addYX, &P.subYX, uint(b))
187 fp.Neg(t, &P.dt2)
188 fp.Cmov(&P.dt2, t, uint(b))
189 }
190
191 func (P *pointR3) cmov(Q *pointR3, b int) {
192 fp.Cmov(&P.addYX, &Q.addYX, uint(b))
193 fp.Cmov(&P.subYX, &Q.subYX, uint(b))
194 fp.Cmov(&P.dt2, &Q.dt2, uint(b))
195 }
196
View as plain text