1 // Copyright 2007,2008,2010 Segher Boessenkool <segher@kernel.crashing.org>
2 // Licensed under the terms of the GNU GPL, version 2
3 // http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
16 static u8 ec_a
[20]; // mon
17 static u8 ec_b
[20]; // mon
19 static struct point ec_G
; // mon
20 static struct point ec_Q
; // mon
23 static void elt_copy(u8
*d
, u8
*a
)
28 static void elt_zero(u8
*d
)
33 static int elt_is_zero(u8
*d
)
37 for (i
= 0; i
< 20; i
++)
44 static void elt_add(u8
*d
, u8
*a
, u8
*b
)
46 bn_add(d
, a
, b
, ec_p
, 20);
49 static void elt_sub(u8
*d
, u8
*a
, u8
*b
)
51 bn_sub(d
, a
, b
, ec_p
, 20);
54 static void elt_mul(u8
*d
, u8
*a
, u8
*b
)
56 bn_mon_mul(d
, a
, b
, ec_p
, 20);
59 static void elt_square(u8
*d
, u8
*a
)
64 static void elt_inv(u8
*d
, u8
*a
)
68 bn_mon_inv(d
, s
, ec_p
, 20);
71 static void point_to_mon(struct point
*p
)
73 bn_to_mon(p
->x
, ec_p
, 20);
74 bn_to_mon(p
->y
, ec_p
, 20);
77 static void point_from_mon(struct point
*p
)
79 bn_from_mon(p
->x
, ec_p
, 20);
80 bn_from_mon(p
->y
, ec_p
, 20);
84 static int point_is_on_curve(u8
*p
)
103 return elt_is_zero(s
);
107 static void point_zero(struct point
*p
)
113 static int point_is_zero(struct point
*p
)
115 return elt_is_zero(p
->x
) && elt_is_zero(p
->y
);
118 static void point_double(struct point
*r
, struct point
*p
)
122 u8
*px
, *py
, *rx
, *ry
;
131 if (elt_is_zero(py
)) {
136 elt_square(t
, px
); // t = px*px
137 elt_add(s
, t
, t
); // s = 2*px*px
138 elt_add(s
, s
, t
); // s = 3*px*px
139 elt_add(s
, s
, ec_a
); // s = 3*px*px + a
140 elt_add(t
, py
, py
); // t = 2*py
141 elt_inv(t
, t
); // t = 1/(2*py)
142 elt_mul(s
, s
, t
); // s = (3*px*px+a)/(2*py)
144 elt_square(rx
, s
); // rx = s*s
145 elt_add(t
, px
, px
); // t = 2*px
146 elt_sub(rx
, rx
, t
); // rx = s*s - 2*px
148 elt_sub(t
, px
, rx
); // t = -(rx-px)
149 elt_mul(ry
, s
, t
); // ry = -s*(rx-px)
150 elt_sub(ry
, ry
, py
); // ry = -s*(rx-px) - py
153 static void point_add(struct point
*r
, struct point
*p
, struct point
*q
)
155 u8 s
[20], t
[20], u
[20];
156 u8
*px
, *py
, *qx
, *qy
, *rx
, *ry
;
169 if (point_is_zero(&pp
)) {
175 if (point_is_zero(&qq
)) {
183 if (elt_is_zero(u
)) {
186 point_double(r
, &pp
);
193 elt_inv(t
, u
); // t = 1/(qx-px)
194 elt_sub(u
, qy
, py
); // u = qy-py
195 elt_mul(s
, t
, u
); // s = (qy-py)/(qx-px)
197 elt_square(rx
, s
); // rx = s*s
198 elt_add(t
, px
, qx
); // t = px+qx
199 elt_sub(rx
, rx
, t
); // rx = s*s - (px+qx)
201 elt_sub(t
, px
, rx
); // t = -(rx-px)
202 elt_mul(ry
, s
, t
); // ry = -s*(rx-px)
203 elt_sub(ry
, ry
, py
); // ry = -s*(rx-px) - py
206 static void point_mul(struct point
*d
, u8
*a
, struct point
*b
) // a is bignum
213 for (i
= 0; i
< 21; i
++)
214 for (mask
= 0x80; mask
!= 0; mask
>>= 1) {
216 if ((a
[i
] & mask
) != 0)
221 static void generate_ecdsa(u8
*R
, u8
*S
, u8
*k
, u8
*hash
)
230 memcpy(e
+ 1, hash
, 20);
231 bn_reduce(e
, ec_N
, 21);
235 get_rand(m
, sizeof m
);
237 if (bn_compare(m
, ec_N
, 21) >= 0)
242 point_mul(&mG
, m
, &ec_G
);
247 // S = m**-1*(e + Rk) (mod N)
250 bn_reduce(kk
, ec_N
, 21);
251 bn_to_mon(m
, ec_N
, 21);
252 bn_to_mon(e
, ec_N
, 21);
253 bn_to_mon(R
, ec_N
, 21);
254 bn_to_mon(kk
, ec_N
, 21);
256 bn_mon_mul(S
, R
, kk
, ec_N
, 21);
257 bn_add(kk
, S
, e
, ec_N
, 21);
258 bn_mon_inv(minv
, m
, ec_N
, 21);
259 bn_mon_mul(S
, minv
, kk
, ec_N
, 21);
261 bn_from_mon(R
, ec_N
, 21);
262 bn_from_mon(S
, ec_N
, 21);
265 static int check_ecdsa(struct point
*Q
, u8
*R
, u8
*S
, u8
*hash
)
274 memcpy(e
+ 1, hash
, 20);
275 bn_reduce(e
, ec_N
, 21);
277 bn_to_mon(R
, ec_N
, 21);
278 bn_to_mon(S
, ec_N
, 21);
279 bn_to_mon(e
, ec_N
, 21);
281 bn_mon_inv(Sinv
, S
, ec_N
, 21);
283 bn_mon_mul(w1
, e
, Sinv
, ec_N
, 21);
284 bn_mon_mul(w2
, R
, Sinv
, ec_N
, 21);
286 bn_from_mon(w1
, ec_N
, 21);
287 bn_from_mon(w2
, ec_N
, 21);
289 point_mul(&r1
, w1
, &ec_G
);
290 point_mul(&r2
, w2
, Q
);
292 point_add(&r1
, &r1
, &r2
);
297 memcpy(rr
+ 1, r1
.x
, 20);
298 bn_reduce(rr
, ec_N
, 21);
300 bn_from_mon(R
, ec_N
, 21);
301 bn_from_mon(S
, ec_N
, 21);
303 return (bn_compare(rr
, R
, 21) == 0);
307 static void ec_priv_to_pub(u8
*k
, u8
*Q
)
309 point_mul(Q
, k
, ec_G
);
313 int ecdsa_set_curve(u32 type
)
315 if (ecdsa_get_params(type
, ec_p
, ec_a
, ec_b
, ec_N
, ec_G
.x
, ec_G
.y
) < 0)
318 bn_to_mon(ec_a
, ec_p
, 20);
319 bn_to_mon(ec_b
, ec_p
, 20);
326 void ecdsa_set_pub(u8
*Q
)
328 memcpy(ec_Q
.x
, Q
, 20);
329 memcpy(ec_Q
.y
, Q
+20, 20);
333 void ecdsa_set_priv(u8
*k
)
335 memcpy(ec_k
, k
, sizeof ec_k
);
338 int ecdsa_verify(u8
*hash
, u8
*R
, u8
*S
)
340 return check_ecdsa(&ec_Q
, R
, S
, hash
);
343 void ecdsa_sign(u8
*hash
, u8
*R
, u8
*S
)
345 generate_ecdsa(R
, S
, ec_k
, hash
);