Skip to content

Commit 1af0de1

Browse files
minadsjaeckel
authored andcommitted
deprecate mp_tc_(and|or|xor) in favor of mp_(and|or|xor)
* same behavior for positive numbers * generalisation for negative numbers, treating them as two complement * improve algorithm, iterate once over the digits, manually perform two complement * simplify mp_add_d, mp_sub_d * functions are safe in case of a==c or b==c * renamed mp_tc_div_2d to mp_signed_rsh (signed right shift)
1 parent aeeea0d commit 1af0de1

23 files changed

+276
-511
lines changed

bn_deprecated.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,4 +122,28 @@ void bn_reverse(unsigned char *s, int len)
122122
s_mp_reverse(s, len);
123123
}
124124
#endif
125+
#ifdef BN_MP_TC_AND_C
126+
mp_err mp_tc_and(const mp_int *a, const mp_int *b, mp_int *c)
127+
{
128+
return mp_and(a, b, c);
129+
}
130+
#endif
131+
#ifdef BN_MP_TC_OR_C
132+
mp_err mp_tc_or(const mp_int *a, const mp_int *b, mp_int *c)
133+
{
134+
return mp_or(a, b, c);
135+
}
136+
#endif
137+
#ifdef BN_MP_TC_XOR_C
138+
mp_err mp_tc_xor(const mp_int *a, const mp_int *b, mp_int *c)
139+
{
140+
return mp_xor(a, b, c);
141+
}
142+
#endif
143+
#ifdef BN_MP_TC_DIV_2D_C
144+
mp_err mp_tc_div_2d(const mp_int *a, int b, mp_int *c)
145+
{
146+
return mp_signed_rsh(a, b, c);
147+
}
148+
#endif
125149
#endif

bn_mp_add_d.c

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ mp_err mp_add_d(const mp_int *a, mp_digit b, mp_int *c)
88
{
99
mp_err err;
1010
int ix, oldused;
11-
mp_digit *tmpa, *tmpc, mu;
11+
mp_digit *tmpa, *tmpc;
1212

1313
/* grow c as required */
1414
if (c->alloc < (a->used + 1)) {
@@ -46,15 +46,9 @@ mp_err mp_add_d(const mp_int *a, mp_digit b, mp_int *c)
4646

4747
/* if a is positive */
4848
if (a->sign == MP_ZPOS) {
49-
/* add digit, after this we're propagating
50-
* the carry.
51-
*/
52-
*tmpc = *tmpa++ + b;
53-
mu = *tmpc >> MP_DIGIT_BIT;
54-
*tmpc++ &= MP_MASK;
55-
56-
/* now handle rest of the digits */
57-
for (ix = 1; ix < a->used; ix++) {
49+
/* add digits, mu is carry */
50+
mp_digit mu = b;
51+
for (ix = 0; ix < a->used; ix++) {
5852
*tmpc = *tmpa++ + mu;
5953
mu = *tmpc >> MP_DIGIT_BIT;
6054
*tmpc++ &= MP_MASK;

bn_mp_and.c

Lines changed: 38 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,38 +3,54 @@
33
/* LibTomMath, multiple-precision integer library -- Tom St Denis */
44
/* SPDX-License-Identifier: Unlicense */
55

6-
/* AND two ints together */
6+
/* two complement and */
77
mp_err mp_and(const mp_int *a, const mp_int *b, mp_int *c)
88
{
9-
int ix, px;
9+
int used = MP_MAX(a->used, b->used) + 1, i;
1010
mp_err err;
11-
mp_int t;
12-
const mp_int *x;
11+
mp_digit ac = 1, bc = 1, cc = 1;
12+
mp_sign csign = (a->sign == MP_NEG && b->sign == MP_NEG) ? MP_NEG : MP_ZPOS;
1313

14-
if (a->used > b->used) {
15-
if ((err = mp_init_copy(&t, a)) != MP_OKAY) {
14+
if (c->alloc < used) {
15+
if ((err = mp_grow(c, used)) != MP_OKAY) {
1616
return err;
1717
}
18-
px = b->used;
19-
x = b;
20-
} else {
21-
if ((err = mp_init_copy(&t, b)) != MP_OKAY) {
22-
return err;
23-
}
24-
px = a->used;
25-
x = a;
2618
}
2719

28-
for (ix = 0; ix < px; ix++) {
29-
t.dp[ix] &= x->dp[ix];
30-
}
20+
for (i = 0; i < used; i++) {
21+
mp_digit x, y;
22+
23+
/* convert to two complement if negative */
24+
if (a->sign == MP_NEG) {
25+
ac += i >= a->used ? MP_MASK : ~a->dp[i] & MP_MASK;
26+
x = ac & MP_MASK;
27+
ac >>= MP_DIGIT_BIT;
28+
} else {
29+
x = i >= a->used ? 0 : a->dp[i];
30+
}
3131

32-
/* zero digits above the last from the smallest mp_int */
33-
MP_ZERO_DIGITS(t.dp + ix, t.used - ix);
32+
/* convert to two complement if negative */
33+
if (b->sign == MP_NEG) {
34+
bc += i >= b->used ? MP_MASK : ~b->dp[i] & MP_MASK;
35+
y = bc & MP_MASK;
36+
bc >>= MP_DIGIT_BIT;
37+
} else {
38+
y = i >= b->used ? 0 : b->dp[i];
39+
}
40+
41+
c->dp[i] = x & y;
42+
43+
/* convert to to sign-magnitude if negative */
44+
if (csign == MP_NEG) {
45+
cc += ~c->dp[i] & MP_MASK;
46+
c->dp[i] = cc & MP_MASK;
47+
cc >>= MP_DIGIT_BIT;
48+
}
49+
}
3450

35-
mp_clamp(&t);
36-
mp_exch(c, &t);
37-
mp_clear(&t);
51+
c->used = used;
52+
c->sign = csign;
53+
mp_clamp(c);
3854
return MP_OKAY;
3955
}
4056
#endif

bn_mp_lshd.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,7 @@ mp_err mp_lshd(mp_int *a, int b)
4444
}
4545

4646
/* zero the lower digits */
47-
top = a->dp;
48-
for (x = 0; x < b; x++) {
49-
*top++ = 0;
50-
}
47+
MP_ZERO_DIGITS(a->dp, b);
5148

5249
return MP_OKAY;
5350
}

bn_mp_or.c

Lines changed: 40 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,34 +3,54 @@
33
/* LibTomMath, multiple-precision integer library -- Tom St Denis */
44
/* SPDX-License-Identifier: Unlicense */
55

6-
/* OR two ints together */
6+
/* two complement or */
77
mp_err mp_or(const mp_int *a, const mp_int *b, mp_int *c)
88
{
9-
int ix, px;
10-
mp_err err;
11-
mp_int t;
12-
const mp_int *x;
9+
int used = MP_MAX(a->used, b->used) + 1, i;
10+
mp_err err;
11+
mp_digit ac = 1, bc = 1, cc = 1;
12+
mp_sign csign = (a->sign == MP_NEG || b->sign == MP_NEG) ? MP_NEG : MP_ZPOS;
1313

14-
if (a->used > b->used) {
15-
if ((err = mp_init_copy(&t, a)) != MP_OKAY) {
14+
if (c->alloc < used) {
15+
if ((err = mp_grow(c, used)) != MP_OKAY) {
1616
return err;
1717
}
18-
px = b->used;
19-
x = b;
20-
} else {
21-
if ((err = mp_init_copy(&t, b)) != MP_OKAY) {
22-
return err;
23-
}
24-
px = a->used;
25-
x = a;
2618
}
2719

28-
for (ix = 0; ix < px; ix++) {
29-
t.dp[ix] |= x->dp[ix];
20+
for (i = 0; i < used; i++) {
21+
mp_digit x, y;
22+
23+
/* convert to two complement if negative */
24+
if (a->sign == MP_NEG) {
25+
ac += i >= a->used ? MP_MASK : ~a->dp[i] & MP_MASK;
26+
x = ac & MP_MASK;
27+
ac >>= MP_DIGIT_BIT;
28+
} else {
29+
x = i >= a->used ? 0 : a->dp[i];
30+
}
31+
32+
/* convert to two complement if negative */
33+
if (b->sign == MP_NEG) {
34+
bc += i >= b->used ? MP_MASK : ~b->dp[i] & MP_MASK;
35+
y = bc & MP_MASK;
36+
bc >>= MP_DIGIT_BIT;
37+
} else {
38+
y = i >= b->used ? 0 : b->dp[i];
39+
}
40+
41+
c->dp[i] = x | y;
42+
43+
/* convert to to sign-magnitude if negative */
44+
if (csign == MP_NEG) {
45+
cc += ~c->dp[i] & MP_MASK;
46+
c->dp[i] = cc & MP_MASK;
47+
cc >>= MP_DIGIT_BIT;
48+
}
3049
}
31-
mp_clamp(&t);
32-
mp_exch(c, &t);
33-
mp_clear(&t);
50+
51+
c->used = used;
52+
c->sign = csign;
53+
mp_clamp(c);
3454
return MP_OKAY;
3555
}
3656
#endif

bn_mp_rshd.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,7 @@ void mp_rshd(mp_int *a, int b)
4343
}
4444

4545
/* zero the top digits */
46-
for (; x < a->used; x++) {
47-
*bottom++ = 0;
48-
}
46+
MP_ZERO_DIGITS(bottom, a->used - x);
4947

5048
/* remove excess digits */
5149
a->used -= b;

bn_mp_signed_rsh.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#include "tommath_private.h"
2+
#ifdef BN_MP_SIGNED_RSH_C
3+
/* LibTomMath, multiple-precision integer library -- Tom St Denis */
4+
/* SPDX-License-Identifier: Unlicense */
5+
6+
/* shift right by a certain bit count with sign extension */
7+
mp_err mp_signed_rsh(const mp_int *a, int b, mp_int *c)
8+
{
9+
mp_err res;
10+
if (a->sign == MP_ZPOS) {
11+
return mp_div_2d(a, b, c, NULL);
12+
}
13+
14+
res = mp_add_d(a, 1uL, c);
15+
if (res != MP_OKAY) {
16+
return res;
17+
}
18+
19+
res = mp_div_2d(c, b, c, NULL);
20+
return (res == MP_OKAY) ? mp_sub_d(c, 1uL, c) : res;
21+
}
22+
#endif

bn_mp_sub_d.c

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
/* single digit subtraction */
77
mp_err mp_sub_d(const mp_int *a, mp_digit b, mp_int *c)
88
{
9-
mp_digit *tmpa, *tmpc, mu;
9+
mp_digit *tmpa, *tmpc;
1010
mp_err err;
1111
int ix, oldused;
1212

@@ -50,17 +50,14 @@ mp_err mp_sub_d(const mp_int *a, mp_digit b, mp_int *c)
5050
c->sign = MP_NEG;
5151
c->used = 1;
5252
} else {
53+
mp_digit mu = b;
54+
5355
/* positive/size */
5456
c->sign = MP_ZPOS;
5557
c->used = a->used;
5658

57-
/* subtract first digit */
58-
*tmpc = *tmpa++ - b;
59-
mu = *tmpc >> (MP_SIZEOF_BITS(mp_digit) - 1u);
60-
*tmpc++ &= MP_MASK;
61-
62-
/* handle rest of the digits */
63-
for (ix = 1; ix < a->used; ix++) {
59+
/* subtract digits, mu is carry */
60+
for (ix = 0; ix < a->used; ix++) {
6461
*tmpc = *tmpa++ - mu;
6562
mu = *tmpc >> (MP_SIZEOF_BITS(mp_digit) - 1u);
6663
*tmpc++ &= MP_MASK;

bn_mp_tc_and.c

Lines changed: 0 additions & 78 deletions
This file was deleted.

bn_mp_tc_div_2d.c

Lines changed: 0 additions & 22 deletions
This file was deleted.

0 commit comments

Comments
 (0)