177{
178
179
180
181
182
183
184 init_counters();
185
189
192
195 fp_set(seed, in->seed);
198
199 clearpublicprimes(&Points[0], &A24);
200 clearpublicprimes(&Points[1], &A24);
201
202
204 {
207 }
208
209 for (int16_t
j =
batch_stop[primes_batches - 1] + 1;
j < primes_num;
j++)
210 {
213 }
214
215
216 int16_t unused[
batch_stop[primes_batches - 1] + 1];
217
218 int16_t u = 0;
219 int16_t e = 0;
220 int16_t w = 0;
221 for (e = 0; e <=
batch_stop[primes_batches - 1]; e++)
222 {
223#ifdef ENABLE_CT_TESTING
224 VALGRIND_MAKE_MEM_DEFINED(&u, sizeof(int16_t));
225 VALGRIND_MAKE_MEM_DEFINED(&e, sizeof(int16_t));
226 VALGRIND_MAKE_MEM_DEFINED(&w, sizeof(int16_t));
227#endif
228
229 unused[u] = e;
230
231 int64_t mov = -int64mask_equal((int64_t)e, (int64_t)priv->ells[w]);
232
234 t1[0] = u;
235 t2[0] = u + 1;
237 u = t1[0];
238
239 t1[0] = w;
240 t2[0] = w + 1;
242 w = t1[0];
243 }
244
245
246 int16_t tmp_b = 0;
247 for (u = 0; u <=
batch_stop[primes_batches - 1] - WOMBATKEYS; u++)
248 {
249 int16_t t = unused[u];
251 tmp_b++;
252
255
258 }
259
260
261 proj ramifications[2 * WOMBATKEYS] = {0};
262 int inner,
263 block = 0,
264 pos,
265 k = 0;
266
267 int64_t moves = 0,
268 xmul_counter[WOMBATKEYS] = {0},
269 Plen = 0;
270 (void)pos;
271
273
274 proj_copy(&ramifications[0], (
const proj *)&Points[0]);
275 proj_copy(&ramifications[1], (
const proj *)&Points[1]);
276
277 int16_t current_batch = 0;
279
280 proj Points_[2 * WOMBATKEYS] = {0};
281
282
283
284 for (
int i = WOMBATKEYS - 1;
i >= 0;
i--)
285 {
287 {
288 current_batch++;
290 }
291
292
293 uint16_t flip_index = WOMBATKEYS -
i -1;
294 uint16_t current_ell_index = priv->ells[flip_index];
295 uint64_t current_ell = lookup(current_ell_index,
primes);
296
297 int64_t direction = priv->directions[flip_index];
298
300 uint64_t upperend_ell =
primes[
batch_stop[current_batch] - current_batch_inner + 1];
301
302
303
304 swap = -int64mask_equal(direction, (int64_t)2);
305 proj_cswap(&ramifications[0+ 2 * block], &ramifications[1+ 2 * block],
swap);
306
307 tmp_b = primes_batches-1;
309 {
310 block += 1;
311
312 proj_copy(&ramifications[0 + 2 * block], (
const proj *)&ramifications[0 + 2 * (block - 1)]);
313 proj_copy(&ramifications[1 + 2 * block], (
const proj *)&ramifications[1 + 2 * (block - 1)]);
314
315
316 for (inner = moves; inner < (moves +
strategy[k]); inner++)
317 {
318 pos = WOMBATKEYS - inner -1;
320 tmp_b--;
321
322 int64_t dac = lookup(priv->ells[pos],
primes_dac);
324
326 {
327 xMUL_dac(&ramifications[0 + 2 * block], &A24, 0, &ramifications[0 + 2 * block], dac, daclen,
batch_maxdac[tmp_b]);
328 xMUL_dac(&ramifications[1 + 2 * block], &A24, 0, &ramifications[1 + 2 * block], dac, daclen,
batch_maxdac[tmp_b]);
329 }
330 else {
331 xMUL_dac(&ramifications[0 + 2 * block], &A24, 0, &ramifications[0 + 2 * block], dac, daclen,
batch_maxdac[tmp_b]);
332 }
333 }
334
337 k += 1;
338 }
339
340
341 Plen = 2 * block;
342
343
345 proj_copy(&Anew, &A);
346 for (
int j = 0;
j < Plen;
j++)
347 {
348
349 proj_copy(&Points_[
j], &ramifications[
j]);
350 }
351
352 xISOG_matryoshka(&Anew, Points_, Plen, &ramifications[0 + 2 * block], current_ell, lowerend_ell, upperend_ell);
353
354
355
356 proj_cmov(&A, &Anew, -int64mask_nonzero(direction));
358
359
360 for (
int j = 0;
j < Plen;
j++)
361 {
362 proj_cmov(&ramifications[
j], &Points_[
j], -int64mask_nonzero(direction));
363
364
365
366 int64_t dac = lookup(current_ell_index,
primes_dac);
368
370 }
371
372
373
374 moves -= xmul_counter[block];
375 xmul_counter[block] = 0;
376 block -= 1;
377
378 proj_cswap(&ramifications[0+ 2 * block], &ramifications[1+ 2 * block],
swap);
379
380 current_batch_inner--;
381 }
382
383#if defined(_M0_)
385 fp_mul2(&
A.x, (
const fp *)&
A.z);
387#else
389#endif
390
391}
void swap(ticks *a, ticks *b)
void isogeny_walks_3_fp(fp_t output_A, const fp_t input_A, int input_length)
uint64_t fp[NUMBER_OF_WORDS]
#define batch_keybounds_start
const int8_t strategy[WOMBATKEYS]
#define batch_keybounds_stop