Skip to content

Commit 03cc01b

Browse files
Tom St Denissjaeckel
Tom St Denis
authored andcommitted
added libtommath-0.24
1 parent eed6765 commit 03cc01b

15 files changed

+398
-71
lines changed

bn.pdf

530 Bytes
Binary file not shown.

bn.tex

+6-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
\documentclass[]{article}
22
\begin{document}
33

4-
\title{LibTomMath v0.23 \\ A Free Multiple Precision Integer Library \\ http://math.libtomcrypt.org }
4+
\title{LibTomMath v0.24 \\ A Free Multiple Precision Integer Library \\ http://math.libtomcrypt.org }
55
\author{Tom St Denis \\ tomstdenis@iahu.ca}
66
\maketitle
77
\newpage
@@ -389,7 +389,7 @@ \subsection{Primality Routines}
389389
/* finds the next prime after the number "a" using "t" trials
390390
* of Miller-Rabin.
391391
*/
392-
int mp_prime_next_prime(mp_int *a, int t);
392+
int mp_prime_next_prime(mp_int *a, int t, int bbs_style);
393393
\end{verbatim}
394394

395395
\subsection{Radix Conversions}
@@ -832,9 +832,11 @@ \subsubsection{mp\_prime\_is\_prime(mp\_int *a, int t, int *result)}
832832
function will always set $result$ to $1$. If $a$ is composite then it will almost always set $result$
833833
to $0$. The probability of error is given in figure two.
834834

835-
\subsubsection{mp\_prime\_next\_prime(mp\_int *a, int t)}
835+
\subsubsection{mp\_prime\_next\_prime(mp\_int *a, int t, int bbs\_style)}
836836
This function will find the next prime \textbf{after} $a$ by using trial division and $t$ trials of
837-
Miller-Rabin.
837+
Miller-Rabin. If $bbs\_style$ is set to one than $a$ will be the next prime such that $a \equiv 3 \mbox{ (mod }4\mbox{)}$
838+
which is useful for certain algorithms. Otherwise, $a$ will be the next prime greater than the initial input
839+
value and may be $\lbrace 1, 3 \rbrace \equiv a \mbox{ (mod }4\mbox{)}$.
838840

839841
\section{Timing Analysis}
840842

bn_mp_add_d.c

+77-8
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,84 @@
1818
int
1919
mp_add_d (mp_int * a, mp_digit b, mp_int * c)
2020
{
21-
mp_int t;
22-
int res;
21+
int res, ix, oldused;
22+
mp_digit *tmpa, *tmpc, mu;
2323

24-
if ((res = mp_init_size(&t, 1)) != MP_OKAY) {
25-
return res;
24+
/* grow c as required */
25+
if (c->alloc < a->used + 1) {
26+
if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) {
27+
return res;
28+
}
2629
}
27-
mp_set (&t, b);
28-
res = mp_add (a, &t, c);
2930

30-
mp_clear (&t);
31-
return res;
31+
/* if a is negative and |a| >= b, call c = |a| - b */
32+
if (a->sign == MP_NEG && (a->used > 1 || a->dp[0] >= b)) {
33+
/* temporarily fix sign of a */
34+
a->sign = MP_ZPOS;
35+
36+
/* c = |a| - b */
37+
res = mp_sub_d(a, b, c);
38+
39+
/* fix sign */
40+
a->sign = c->sign = MP_NEG;
41+
42+
return res;
43+
}
44+
45+
46+
/* old number of used digits in c */
47+
oldused = c->used;
48+
49+
/* sign always positive */
50+
c->sign = MP_ZPOS;
51+
52+
/* source alias */
53+
tmpa = a->dp;
54+
55+
/* destination alias */
56+
tmpc = c->dp;
57+
58+
/* if a is positive */
59+
if (a->sign == MP_ZPOS) {
60+
/* setup size */
61+
c->used = a->used + 1;
62+
63+
/* add digit, after this we're propagating
64+
* the carry.
65+
*/
66+
*tmpc = *tmpa++ + b;
67+
mu = *tmpc >> DIGIT_BIT;
68+
*tmpc++ &= MP_MASK;
69+
70+
/* now handle rest of the digits */
71+
for (ix = 1; ix < a->used; ix++) {
72+
*tmpc = *tmpa++ + mu;
73+
mu = *tmpc >> DIGIT_BIT;
74+
*tmpc++ &= MP_MASK;
75+
}
76+
/* set final carry */
77+
ix++;
78+
*tmpc++ = mu;
79+
80+
} else {
81+
/* a was negative and |a| < b */
82+
c->used = 1;
83+
84+
/* the result is a single digit */
85+
*tmpc++ = b - a->dp[0];
86+
87+
/* setup count so the clearing of oldused
88+
* can fall through correctly
89+
*/
90+
ix = 1;
91+
}
92+
93+
/* now zero to oldused */
94+
while (ix++ < oldused) {
95+
*tmpc++ = 0;
96+
}
97+
mp_clamp(c);
98+
99+
return MP_OKAY;
32100
}
101+

bn_mp_gcd.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ mp_gcd (mp_int * a, mp_int * b, mp_int * c)
2929
return mp_copy (a, c);
3030
}
3131
if (mp_iszero (a) == 1 && mp_iszero (b) == 1) {
32-
mp_set (c, 1);
32+
mp_zero(c);
3333
return MP_OKAY;
3434
}
3535

bn_mp_prime_miller_rabin.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ mp_prime_miller_rabin (mp_int * a, mp_int * b, int *result)
5353
*/
5454
s = mp_cnt_lsb(&r);
5555

56-
/* now divide n - 1 by 2^s */
56+
/* now divide n - 1 by 2**s */
5757
if ((err = mp_div_2d (&r, s, &r, NULL)) != MP_OKAY) {
5858
goto __R;
5959
}

bn_mp_prime_next_prime.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ int mp_prime_next_prime(mp_int *a, int t, int bbs_style)
112112
/* y == 1 if any residue was zero [e.g. cannot be prime] */
113113
y = 0;
114114

115-
/* increase step to next odd */
115+
/* increase step to next candidate */
116116
step += kstep;
117117

118118
/* compute the new residue without using division */

bn_mp_sub_d.c

+53-8
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,61 @@
1818
int
1919
mp_sub_d (mp_int * a, mp_digit b, mp_int * c)
2020
{
21-
mp_int t;
22-
int res;
21+
mp_digit *tmpa, *tmpc, mu;
22+
int res, ix, oldused;
2323

24+
/* grow c as required */
25+
if (c->alloc < a->used + 1) {
26+
if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) {
27+
return res;
28+
}
29+
}
2430

25-
if ((res = mp_init (&t)) != MP_OKAY) {
26-
return res;
31+
/* if a is negative just do an unsigned
32+
* addition [with fudged signs]
33+
*/
34+
if (a->sign == MP_NEG) {
35+
a->sign = MP_ZPOS;
36+
res = mp_add_d(a, b, c);
37+
a->sign = c->sign = MP_NEG;
38+
return res;
2739
}
28-
mp_set (&t, b);
29-
res = mp_sub (a, &t, c);
3040

31-
mp_clear (&t);
32-
return res;
41+
/* setup regs */
42+
oldused = c->used;
43+
tmpa = a->dp;
44+
tmpc = c->dp;
45+
46+
/* if a <= b simply fix the single digit */
47+
if ((a->used == 1 && a->dp[0] <= b) || a->used == 0) {
48+
*tmpc++ = b - *tmpa;
49+
ix = 1;
50+
51+
/* negative/1digit */
52+
c->sign = MP_NEG;
53+
c->used = 1;
54+
} else {
55+
/* positive/size */
56+
c->sign = MP_ZPOS;
57+
c->used = a->used;
58+
59+
/* subtract first digit */
60+
*tmpc = *tmpa++ - b;
61+
mu = *tmpc >> (sizeof(mp_digit) * CHAR_BIT - 1);
62+
*tmpc++ &= MP_MASK;
63+
64+
/* handle rest of the digits */
65+
for (ix = 1; ix < a->used; ix++) {
66+
*tmpc = *tmpa++ - mu;
67+
mu = *tmpc >> (sizeof(mp_digit) * CHAR_BIT - 1);
68+
*tmpc++ &= MP_MASK;
69+
}
70+
}
71+
72+
for (; ix < oldused; ix++) {
73+
*tmpc++ = 0;
74+
}
75+
mp_clamp(c);
76+
return MP_OKAY;
3377
}
78+

changes.txt

+9
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
July 15th, 2003
2+
v0.24 -- Optimized mp_add_d and mp_sub_d to not allocate temporary variables
3+
-- Fixed mp_gcd() so the gcd of 0,0 is 0. Allows the gcd operation to be chained
4+
e.g. (0,0,a) == a [instead of 1]
5+
-- Should be one of the last release for a while. Working on LibTomMath book now.
6+
-- optimized the pprime demo [/etc/pprime.c] to first make a huge table of single
7+
digit primes then it reads them randomly instead of randomly choosing/testing single
8+
digit primes.
9+
110
July 12th, 2003
211
v0.23 -- Optimized mp_prime_next_prime() to not use mp_mod [via is_divisible()] in each
312
iteration. Instead now a smaller table is kept of the residues which can be updated

demo/demo.c

+30-5
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ int main(void)
4646
{
4747
mp_int a, b, c, d, e, f;
4848
unsigned long expt_n, add_n, sub_n, mul_n, div_n, sqr_n, mul2d_n, div2d_n, gcd_n, lcm_n, inv_n,
49-
div2_n, mul2_n;
49+
div2_n, mul2_n, add_d_n, sub_d_n;
5050
unsigned rr;
5151
int cnt, ix, old_kara_m, old_kara_s;
5252

@@ -190,7 +190,7 @@ int main(void)
190190
mp_rand(&b, cnt);
191191
reset();
192192
rr = 0;
193-
do {
193+
do {
194194
DO(mp_add(&a,&b,&c));
195195
rr += 16;
196196
} while (rdtsc() < (CLOCKS_PER_SEC * 2));
@@ -355,7 +355,7 @@ int main(void)
355355
#endif
356356

357357
div2_n = mul2_n = inv_n = expt_n = lcm_n = gcd_n = add_n =
358-
sub_n = mul_n = div_n = sqr_n = mul2d_n = div2d_n = cnt = 0;
358+
sub_n = mul_n = div_n = sqr_n = mul2d_n = div2d_n = cnt = add_d_n = sub_d_n= 0;
359359

360360
/* force KARA and TOOM to enable despite cutoffs */
361361
KARATSUBA_SQR_CUTOFF = KARATSUBA_MUL_CUTOFF = 110;
@@ -374,7 +374,7 @@ int main(void)
374374
}
375375

376376

377-
printf("%7lu/%7lu/%7lu/%7lu/%7lu/%7lu/%7lu/%7lu/%7lu/%7lu/%7lu/%7lu/%7lu ", add_n, sub_n, mul_n, div_n, sqr_n, mul2d_n, div2d_n, gcd_n, lcm_n, expt_n, inv_n, div2_n, mul2_n);
377+
printf("%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu ", add_n, sub_n, mul_n, div_n, sqr_n, mul2d_n, div2d_n, gcd_n, lcm_n, expt_n, inv_n, div2_n, mul2_n, add_d_n, sub_d_n);
378378
fgets(cmd, 4095, stdin);
379379
cmd[strlen(cmd)-1] = 0;
380380
printf("%s ]\r",cmd); fflush(stdout);
@@ -559,8 +559,33 @@ draw(&a);draw(&b);draw(&c);draw(&d);
559559
draw(&c);
560560
return 0;
561561
}
562+
} else if (!strcmp(cmd, "add_d")) { ++add_d_n;
563+
fgets(buf, 4095, stdin); mp_read_radix(&a, buf, 64);
564+
fgets(buf, 4095, stdin); sscanf(buf, "%d", &ix);
565+
fgets(buf, 4095, stdin); mp_read_radix(&b, buf, 64);
566+
mp_add_d(&a, ix, &c);
567+
if (mp_cmp(&b, &c) != MP_EQ) {
568+
printf("add_d %lu failure\n", add_d_n);
569+
draw(&a);
570+
draw(&b);
571+
draw(&c);
572+
printf("d == %d\n", ix);
573+
return 0;
574+
}
575+
} else if (!strcmp(cmd, "sub_d")) { ++sub_d_n;
576+
fgets(buf, 4095, stdin); mp_read_radix(&a, buf, 64);
577+
fgets(buf, 4095, stdin); sscanf(buf, "%d", &ix);
578+
fgets(buf, 4095, stdin); mp_read_radix(&b, buf, 64);
579+
mp_sub_d(&a, ix, &c);
580+
if (mp_cmp(&b, &c) != MP_EQ) {
581+
printf("sub_d %lu failure\n", sub_d_n);
582+
draw(&a);
583+
draw(&b);
584+
draw(&c);
585+
printf("d == %d\n", ix);
586+
return 0;
587+
}
562588
}
563-
564589
}
565590
return 0;
566591
}

etc/makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,4 @@ mont: mont.o
4141

4242

4343
clean:
44-
rm -f *.log *.o *.obj *.exe pprime tune mersenne drprime tune86 tune86l mont 2kprime
44+
rm -f *.log *.o *.obj *.exe pprime tune mersenne drprime tune86 tune86l mont 2kprime pprime.dat

0 commit comments

Comments
 (0)