/src/nettle/ecc-add-jjj.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* ecc-add-jjj.c |
2 | | |
3 | | Copyright (C) 2013 Niels Möller |
4 | | |
5 | | This file is part of GNU Nettle. |
6 | | |
7 | | GNU Nettle is free software: you can redistribute it and/or |
8 | | modify it under the terms of either: |
9 | | |
10 | | * the GNU Lesser General Public License as published by the Free |
11 | | Software Foundation; either version 3 of the License, or (at your |
12 | | option) any later version. |
13 | | |
14 | | or |
15 | | |
16 | | * the GNU General Public License as published by the Free |
17 | | Software Foundation; either version 2 of the License, or (at your |
18 | | option) any later version. |
19 | | |
20 | | or both in parallel, as here. |
21 | | |
22 | | GNU Nettle is distributed in the hope that it will be useful, |
23 | | but WITHOUT ANY WARRANTY; without even the implied warranty of |
24 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
25 | | General Public License for more details. |
26 | | |
27 | | You should have received copies of the GNU General Public License and |
28 | | the GNU Lesser General Public License along with this program. If |
29 | | not, see http://www.gnu.org/licenses/. |
30 | | */ |
31 | | |
32 | | /* Development of Nettle's ECC support was funded by the .SE Internet Fund. */ |
33 | | |
34 | | #if HAVE_CONFIG_H |
35 | | # include "config.h" |
36 | | #endif |
37 | | |
38 | | #include "ecc.h" |
39 | | #include "ecc-internal.h" |
40 | | |
41 | | void |
42 | | ecc_add_jjj (const struct ecc_curve *ecc, |
43 | | mp_limb_t *r, const mp_limb_t *p, const mp_limb_t *q, |
44 | | mp_limb_t *scratch) |
45 | 0 | { |
46 | 0 | #define x1 p |
47 | 0 | #define y1 (p + ecc->p.size) |
48 | 0 | #define z1 (p + 2*ecc->p.size) |
49 | |
|
50 | 0 | #define x2 q |
51 | 0 | #define y2 (q + ecc->p.size) |
52 | 0 | #define z2 (q + 2*ecc->p.size) |
53 | |
|
54 | 0 | #define x3 r |
55 | 0 | #define y3 (r + ecc->p.size) |
56 | 0 | #define z3 (r + 2*ecc->p.size) |
57 | | /* Formulas, from djb, |
58 | | http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl: |
59 | | |
60 | | Computation Operation Live variables |
61 | | |
62 | | Z1Z1 = Z1^2 sqr Z1Z1 |
63 | | Z2Z2 = Z2^2 sqr Z1Z1, Z2Z2 |
64 | | U1 = X1*Z2Z2 mul Z1Z1, Z2Z2, U1 |
65 | | U2 = X2*Z1Z1 mul Z1Z1, Z2Z2, U1, U2 |
66 | | H = U2-U1 Z1Z1, Z2Z2, U1, H |
67 | | Z3 = ((Z1+Z2)^2-Z1Z1-Z2Z2)*H sqr, mul Z1Z1, Z2Z2, U1, H |
68 | | S1 = Y1*Z2*Z2Z2 mul, mul Z1Z1, U1, H, S1 |
69 | | S2 = Y2*Z1*Z1Z1 mul, mul U1, H, S1, S2 |
70 | | W = 2*(S2-S1) (djb: r) U1, H, S1, W |
71 | | I = (2*H)^2 sqr U1, H, S1, W, I |
72 | | J = H*I mul U1, S1, W, J, V |
73 | | V = U1*I mul S1, W, J, V |
74 | | X3 = W^2-J-2*V sqr S1, W, J, V |
75 | | Y3 = W*(V-X3)-2*S1*J mul, mul |
76 | | */ |
77 | |
|
78 | 0 | #define h scratch |
79 | 0 | #define z1z1 (scratch + ecc->p.size) |
80 | 0 | #define z2z2 z1z1 |
81 | 0 | #define z1z2 (scratch + 2*ecc->p.size) |
82 | |
|
83 | 0 | #define w (scratch + ecc->p.size) |
84 | 0 | #define i (scratch + 2*ecc->p.size) |
85 | 0 | #define j h |
86 | 0 | #define v i |
87 | |
|
88 | 0 | #define tp (scratch + 3*ecc->p.size) |
89 | |
|
90 | 0 | ecc_mod_sqr (&ecc->p, z2z2, z2, tp); /* z2z2 */ |
91 | | /* Store u1 at x3 */ |
92 | 0 | ecc_mod_mul (&ecc->p, x3, x1, z2z2, tp); /* z2z2 */ |
93 | |
|
94 | 0 | ecc_mod_add (&ecc->p, z1z2, z1, z2); /* z2z2, z1z2 */ |
95 | 0 | ecc_mod_sqr (&ecc->p, z1z2, z1z2, tp); |
96 | 0 | ecc_mod_sub (&ecc->p, z1z2, z1z2, z2z2); /* z2z2, z1z2 */ |
97 | | |
98 | | /* Do s1 early, store at y3 */ |
99 | 0 | ecc_mod_mul (&ecc->p, z2z2, z2z2, z2, tp); /* z2z2, z1z2 */ |
100 | 0 | ecc_mod_mul (&ecc->p, y3, z2z2, y1, tp); /* z1z2 */ |
101 | |
|
102 | 0 | ecc_mod_sqr (&ecc->p, z1z1, z1, tp); /* z1z1, z1z2 */ |
103 | 0 | ecc_mod_sub (&ecc->p, z1z2, z1z2, z1z1); |
104 | 0 | ecc_mod_mul (&ecc->p, h, x2, z1z1, tp); /* z1z1, z1z2, h */ |
105 | 0 | ecc_mod_sub (&ecc->p, h, h, x3); |
106 | | |
107 | | /* z1^3 */ |
108 | 0 | ecc_mod_mul (&ecc->p, z1z1, z1z1, z1, tp); |
109 | | |
110 | | /* z3 <-- h z1 z2 delayed until now, since that may clobber z1. */ |
111 | 0 | ecc_mod_mul (&ecc->p, z3, z1z2, h, tp); /* z1z1, h */ |
112 | | /* w = 2 (s2 - s1) */ |
113 | 0 | ecc_mod_mul (&ecc->p, w, z1z1, y2, tp); /* h, w */ |
114 | 0 | ecc_mod_sub (&ecc->p, w, w, y3); |
115 | 0 | ecc_mod_add (&ecc->p, w, w, w); |
116 | | |
117 | | /* i = (2h)^2 */ |
118 | 0 | ecc_mod_add (&ecc->p, i, h, h); /* h, w, i */ |
119 | 0 | ecc_mod_sqr (&ecc->p, i, i, tp); |
120 | | |
121 | | /* j and h can overlap */ |
122 | 0 | ecc_mod_mul (&ecc->p, j, h, i, tp); /* j, w, i */ |
123 | | |
124 | | /* v and i can overlap */ |
125 | 0 | ecc_mod_mul (&ecc->p, v, x3, i, tp); /* j, w, v */ |
126 | | |
127 | | /* x3 <-- w^2 - j - 2v */ |
128 | 0 | ecc_mod_sqr (&ecc->p, x3, w, tp); |
129 | 0 | ecc_mod_sub (&ecc->p, x3, x3, j); |
130 | 0 | ecc_mod_submul_1 (&ecc->p, x3, v, 2); |
131 | | |
132 | | /* y3 <-- w (v - x3) - 2 s1 j */ |
133 | 0 | ecc_mod_mul (&ecc->p, j, j, y3, tp); |
134 | 0 | ecc_mod_sub (&ecc->p, v, v, x3); |
135 | 0 | ecc_mod_mul (&ecc->p, y3, v, w, tp); |
136 | 0 | ecc_mod_submul_1 (&ecc->p, y3, j, 2); |
137 | 0 | } |