forked from libtom/libtommath
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbn_mp_giantsteps.c
67 lines (58 loc) · 1.46 KB
/
bn_mp_giantsteps.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include <tommath.h>
#ifdef BN_MP_GIANTSTEPS_C
/*
Function quite alike the similarily named one from Python.
Example (error-handling ommitted):
int start, end, stepsize, *precs, steps, *s;
...
mp_giantsteps(start, end, stepsize, &precs, &steps);
printf("steps = %d\n", steps);
s = precs;
for(i = 0;i<steps;i++){
printf("%d, ", *precs);
precs++;
}
puts("");
free(s);
CAVEAT: the maximum value is listed twice! This has the reason that
some algorithms (e.g.: integer division with Newton-Raphson)
need a last round with full precision. It won't hurt the
result if ignored when not needed it will just add some extra
run-time.
*/
int mp_giantsteps(int start, int end, int stepsize, int **precs, int *steps)
{
int i, t;
if (start < 0 || end <= 0 || stepsize < 2 || end <= start) {
return MP_VAL;
}
t = end;
i = 0;
// we need to run this loop twice but it is cheap and runs only
// log_2(end - start) times max.
for (;;) {
if (t < start * stepsize) {
break;
}
i++;
t = (t / stepsize) ;
}
i++;
*precs = malloc((i+1) * sizeof(int));
if (*precs == NULL) {
return MP_MEM;
}
*precs += i ;
**precs = end;
i--;
(*precs)--;
**precs = end;
*steps = 2;
while (i--) {
(*precs)--;
(*steps)++;
**precs = (*((*precs)+1) / stepsize) ;
}
return MP_OKAY;
}
#endif