Let us walk on the 3-isogeny graph
Loading...
Searching...
No Matches
isogeny_walks_3.c
Go to the documentation of this file.
1//
2// 3-isogeny walk calculations via radical computations
3//
4
5#include "isogeny_walks.h"
6#include "utilities.h"
7#include <stdio.h>
8
9
10void isogeny_walks_3(fp2_t *output_a1, fp2_t *output_a3, fp2_t input_a1, fp2_t input_a3, const uint8_t *input_path, size_t input_length) {
11 // This function assumes the input and output determines elliptic
12 // curves of form y² + a₁xy + a₃y = x³ − 5a₁a₃x − (a₁³)a₃ − 7(a₃)²
13 size_t i, j;
14 fp2_t a, a1, a3, cube_roots_of_unity[3], r, s, t;
15
16 fp2_set_to_one(&cube_roots_of_unity[0]);
17 fp2_copy(&cube_roots_of_unity[1], *((fp2_t *)&CUBE_ROOT_OF_UNITY));
18 fp2_sqr(&cube_roots_of_unity[2], cube_roots_of_unity[1]);
19
20 fp2_copy(&a1, input_a1);
21 fp2_copy(&a3, input_a3);
22
23 uint32_t trit_string[input_length];
24 to_trit_string(trit_string, input_path, input_length);
25
26 for (i = 0; i < input_length; i++) {
27 uint32_t mask = 0x0000000F;
28 for (j = 0; j < 5; j++) {
29 fp2_neg(&a, a3);
30 fp2_curt(&a, a);
31 fp2_linear_pass_in(&t, cube_roots_of_unity, 3, (trit_string[i] & mask) >> (4*j));
32 fp2_mul(&a, a, t);
33
34 // radical 3-isogeny
35 fp2_add(&t, a, a); // 2α
36 fp2_add(&t, t, a); // 3α
37 fp2_add(&t, t, t); // 6α
38
39 fp2_add(&r, a1, a1); // 2a₁
40 fp2_add(&r, r, a1); // 3a₁
41 fp2_sqr(&s, a1); // a₁²
42
43 fp2_sub(&a1, a1, t); // a₁ <- a₁ - 6α
44
45 fp2_sqr(&t, a); // α²
46 fp2_mul(&r, r, t); // 3a₁ · α²
47 fp2_mul(&s, s, a); // a₁² · α
48 fp2_add(&t, a3, a3); // 2a₃
49 fp2_add(&t, t, a3); // 3a₃
50 fp2_add(&a, t, t); // 6a₃
51 fp2_add(&t, a, t); // 9a₃
52 fp2_sub(&a3, r, s); // a₃ <- 3a₁ · α² - a₁² · α
53 fp2_add(&a3, a3, t); // a₃ <- 3a₁ · α² - a₁² · α + 9a₃
54
55 mask <<= 4;
56 }
57 }
58 fp2_copy(output_a1, a1);
59 fp2_copy(output_a3, a3);
60}
61
62void isogeny_walks_from_montgomery_model_3(fp2_t *output_a1, fp2_t *output_a3, fp2_t input_A, fp2_t input_xP) {
63 // inputs: x-coordinate of an order-3 point P on E: y² = x³ + Ax² + x, and A
64 // output: isomorphic curve of form F: y² + a₁xy + a₃y = x³
65 // Cost: 2M + 2S + 7A
66 fp2_t r, s, xP_squared, A_times_xP;
67
68 fp2_sqr(&xP_squared, input_xP);
69 fp2_add(&r, xP_squared, xP_squared);
70 fp2_add(&r, xP_squared, r);
71
72 fp2_mul(&A_times_xP, input_A, input_xP);
73 fp2_add(&s, A_times_xP, A_times_xP);
74 fp2_add(&r, r, s);
75
77 fp2_add(output_a1, r, s); // (3xₚ² + 2Axₚ + 1)
78
79 fp2_add(output_a3, xP_squared, A_times_xP);
80 fp2_add(output_a3, *output_a3, s);
81 fp2_mul(output_a3, *output_a3, input_xP);
82 fp2_sqr(output_a3, *output_a3);
83 fp2_add(output_a3, *output_a3, *output_a3); // 2 yₚ⁴ = 2 (xₚ³ + Axₚ² + xₚ)²
84}
85
86
87void isogeny_walks_switch_from_model_3(fp2_t *output_j, fp2_t input_a1, fp2_t input_a3) {
88 // Computes the j-invariant of an elliptic curve E : y² + a₁xy + a₃y = x³ − 5a₁a₃x − (a₁³)a₃ − 7(a₃)²
89 fp2_t aux, tmp, num, den, a1_cube, a3_cube;
90
91 fp2_sqr(&a1_cube, input_a1);
92 fp2_sqr(&a3_cube, input_a3);
93 fp2_mul(&a1_cube, a1_cube, input_a1);
94 fp2_mul(&a3_cube, a3_cube, input_a3);
95
96 fp2_add(&tmp, input_a3, input_a3); // 2 × a₃
97 fp2_add(&tmp, tmp, input_a3); // 3 × a₃
98 fp2_add(&aux, tmp, tmp); // 6 × a₃
99 fp2_add(&aux, aux, aux); // 12 × a₃
100
101 fp2_add(&aux, aux, aux); // 24 × a₃
102 fp2_add(&aux, aux, tmp); // 27 × a₃
103 fp2_add(&tmp, aux, aux); // 54 × a₃
104 fp2_add(&tmp, tmp, tmp); // 108 × a₃
105
106 fp2_add(&tmp, tmp, tmp); // 216 × a₃
107 fp2_add(&num, a1_cube, tmp); // a₁³ + 216 × a₃
108 fp2_sub(&den, a1_cube, aux); // a₁³ - 27 × a₃
109
110 fp2_sqr(&tmp, num);
111 fp2_sqr(&aux, den);
112
113 fp2_mul(&num, num, tmp); // (a₁³ + 216 × a₃)³
114 fp2_mul(&den, den, aux); // (a₁³ - 27 × a₃)³
115 fp2_mul(&num, a1_cube, num); // (a₁³ + 216 × a₃)³ × a₁³
116 fp2_mul(&den, input_a3, den); // (a₁³ - 27 × a₃)³ × a₃
117
118 fp2_inv(&den, den);
119 fp2_mul(output_j, num, den);
120
121}
122
123
124void isogeny_walks_get_points_3(fp2_t *output, fp2_t input_A) {
125 fp2_t A_times_one_third, A_squared, r, s, t, u, v, y, s0, i0, s1, s2;
126 fp_t THREE, EIGHT;
127
128 fp_set_to_one(THREE); // 1
129
130 fp_add(EIGHT, THREE, THREE); // 2
131 fp_add(THREE, THREE, EIGHT); // 3
132 fp_add(EIGHT, EIGHT, EIGHT); // 4
133 fp_add(EIGHT, EIGHT, EIGHT); // 8
134
135 fp_mul(A_times_one_third.re, input_A.re, ONE_THIRD);
136 fp_mul(A_times_one_third.im, input_A.im, ONE_THIRD);
137 fp2_sqr(&A_squared, input_A);
138
139 // t takes the value of ⅑(3 - A²)
140 fp_sub(t.re, THREE, A_squared.re);
141 fp_neg(t.im, A_squared.im);
142 fp_mul(t.re, t.re, ONE_NINTH);
143 fp_mul(t.im, t.im, ONE_NINTH);
144
145 // r takes the value of (⁸⁄₂₇)A³
146 fp2_mul(&r, A_squared, input_A);
147 fp_mul(r.re, r.re, ONE_BY_27);
148 fp_mul(r.im, r.im, ONE_BY_27);
149 fp2_add(&r, r, r); // 2r
150 fp2_add(&r, r, r); // 4r
151 fp2_add(&r, r, r); // 8r
152 fp2_add(&r, r, r); // 16r
153
154 // s takes the calue of (⁸⁄₃)A
155 fp2_copy(&s, A_times_one_third);
156 fp2_add(&s, s, s); // 2s
157 fp2_add(&s, s, s); // 4s
158 fp2_add(&s, s, s); // 8s
159 fp2_sub(&u, r, s); // r - s
160
161 // v takes the value of -2A² + 8
162 fp2_add(&v, A_squared, A_squared);
163 fp_sub(v.re, EIGHT, v.re);
164 fp_neg(v.im, v.im);
165 fp2_curt(&y, v); // cube-root of v
166
167 // y takes the value of t + (¹⁄₃)∛v
168 fp_mul(y.re, y.re, ONE_THIRD);
169 fp_mul(y.im, y.im, ONE_THIRD);
170 fp2_add(&y, t, y);
171 fp2_add(&r, y, y); // 2y
172
173 fp2_add(&s, t, t); // 2t
174 fp2_add(&s, t, s); // 3t
175 fp2_add(&s, s, s); // 6t
176 fp2_sub(&t, r, s); // r - s
177
178 // s₀ takes the value of √(r - s)
179 fp2_sqrt_slow(&s0, t);
180 fp2_inv(&i0, s0); // 1 / s₀
181
182 fp2_add(&v, r, s); // r + s
183 fp2_neg(&v, v); // -(r + s)
184 fp2_mul(&t, u, i0); // u / s₀
185
186 // s₁ takes the value of √[v + (u / s₀)]
187 fp2_add(&s, v, t); // v + (u / s₀)
188 fp2_sqrt_slow(&s1, s);
189 // s₂ takes the value of √[v - (u / s₀)]
190 fp2_sub(&s, v, t); // v - (u / s₀)
191 fp2_sqrt_slow(&s2, s);
192
193 fp2_sub(&r, s1, s0); // -s₀ + s₁
194 fp2_add(&s, s1, s0); // s₀ + s₁
195 fp2_add(&t, s0, s2); // s₀ + s₂
196 fp2_sub(&u, s0, s2); // s₀ - s₂
197
198 fp2_neg(&s, s); // -(s₀ + s₁)
199
200 fp2_half(&r, r); // (¹⁄₂)(-s₀ + s₁)
201 fp2_half(&s, s); // (¹⁄₂)(-s₀ - s₁)
202 fp2_half(&t, t); // (¹⁄₂)( s₀ + s₂)
203 fp2_half(&u, u); // (¹⁄₂)( s₀ - s₂)
204
205 fp2_sub(&output[3], u, A_times_one_third); // r - (¹⁄₃)A
206 fp2_sub(&output[2], t, A_times_one_third); // s - (¹⁄₃)A
207 fp2_sub(&output[1], s, A_times_one_third); // t - (¹⁄₃)A
208 fp2_sub(&output[0], r, A_times_one_third); // u - (¹⁄₃)A
209}
210
211
212void isogeny_walks_sample_trit_string(uint8_t *output) {
213 uint8_t bound = 0xF3;
214 for(int i = 0; i < (TRITLENGTH_PATH / 5); i++) {
215 output[i] = 0x00;
216 randombytes(&output[i], 1);
217 while (issmaller((int32_t)bound, (int32_t)(output[i]))) {
218 randombytes(&output[i], 1);
219 }
220 }
221}
void fp2_sqrt_slow(fp2_t *output, fp2_t input)
Definition fp2.c:283
void fp2_linear_pass_in(fp2_t *output, const fp2_t *input, uint8_t input_length, uint8_t input_index)
Definition fp2.c:159
void fp2_half(fp2_t *output, fp2_t input)
Definition fp2.c:107
void fp2_curt(fp2_t *output, fp2_t input)
Definition fp2.c:399
void fp2_set_to_one(fp2_t *output)
Definition fp2.c:49
void randombytes(void *x, size_t l)
Definition rng.c:8
#define fp_sub
Definition fp-gmp.h:67
#define fp_mul
Definition fp-gmp.h:70
#define fp_add
Definition fp-gmp.h:64
void fp_neg(fp_t output, const fp_t input)
Definition fp.c:9
void fp_set_to_one(fp_t input_output)
Definition fp.c:14
uint64_t fp_t[FIELD_64BITS_WORDS]
Definition fp.h:12
void isogeny_walks_from_montgomery_model_3(fp2_t *output_a1, fp2_t *output_a3, fp2_t input_A, fp2_t input_xP)
void isogeny_walks_3(fp2_t *output_a1, fp2_t *output_a3, fp2_t input_a1, fp2_t input_a3, const uint8_t *input_path, size_t input_length)
void isogeny_walks_get_points_3(fp2_t *output, fp2_t input_A)
void isogeny_walks_switch_from_model_3(fp2_t *output_j, fp2_t input_a1, fp2_t input_a3)
void isogeny_walks_sample_trit_string(uint8_t *output)
den a3
num
#define TRITLENGTH_PATH
Definition p254.h:15
for i
for j
Definition fp2.h:10
fp_t re
Definition fp2.h:11
fp_t im
Definition fp2.h:12
g a1
Definition to_model.m:15
f a
Definition to_model.m:12