Created
December 2, 2012 07:00
-
-
Save skids/4187527 to your computer and use it in GitHub Desktop.
A fix for tomath repr bitops
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
static void grow_and_negate(mp_int *a, int size, mp_int *b) { | |
int i; | |
/* Always add an extra digit so we can tell positive values | |
* with a one in the highest bit apart from negative values | |
* with a zero in the highest bit. | |
*/ | |
int actual_size = MAX(size, USED(a)) + 1; | |
SIGN(b) = MP_ZPOS; | |
mp_grow(b, actual_size); | |
USED(b) = actual_size; | |
for (i = 0; i < USED(a); i++) { | |
DIGIT(b, i) = (~DIGIT(a, i)) & MP_MASK; | |
} | |
if (MP_NEG == SIGN(a)) { | |
for (; i < actual_size; i++) { | |
DIGIT(b, i) = MP_MASK; | |
} | |
} | |
/* Note: this is never called with a containing only zeros because: | |
* 1) we assume "negative zero" just does not happen (?) | |
* 2) positive values only come here if they have a high bit of one | |
* As such, this add cannot cause another grow. | |
*/ | |
mp_add_d(b, 1, b); | |
} | |
static void two_complement_bitop(mp_int *a, mp_int *b, mp_int *c, | |
int (*mp_bitop)(mp_int *, mp_int *, mp_int *)) { | |
mp_int d; | |
mp_int e; | |
mp_int *f; | |
mp_int *g; | |
f = a; | |
g = b; | |
if (MP_NEG == SIGN(a)) { | |
mp_init(&d); | |
grow_and_negate(a, USED(b), &d); | |
f = &d; | |
} | |
if (MP_NEG == SIGN(b)) { | |
mp_init(&e); | |
grow_and_negate(b, USED(a), &e); | |
g = &e; | |
} | |
mp_bitop(f, g, c); | |
if (f == &d) mp_clear(&d); | |
if (g == &e) mp_clear(&e); | |
/* Use the fact that tomath clamps to detect signed results */ | |
if (USED(c) > MAX(USED(a),USED(b))) { | |
mp_init(&d); | |
grow_and_negate(c, c->used, &d); | |
mp_clamp(&d); | |
mp_copy(&d, c); | |
mp_neg(c, c); | |
mp_clear(&d); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment