Merge pull request #578 from PX4/fix_mp_prime_strong_lucas_lefridge_compilation
[libtommath.git] / mp_and.c
blobb5230c4d178c75177cea0d0ece2ceeba16039a35
1 #include "tommath_private.h"
2 #ifdef MP_AND_C
3 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
4 /* SPDX-License-Identifier: Unlicense */
6 /* two complement and */
7 mp_err mp_and(const mp_int *a, const mp_int *b, mp_int *c)
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 bool neg = (mp_isneg(a) && mp_isneg(b));
14 if ((err = mp_grow(c, used)) != MP_OKAY) {
15 return err;
18 for (i = 0; i < used; i++) {
19 mp_digit x, y;
21 /* convert to two complement if negative */
22 if (mp_isneg(a)) {
23 ac += (i >= a->used) ? MP_MASK : (~a->dp[i] & MP_MASK);
24 x = ac & MP_MASK;
25 ac >>= MP_DIGIT_BIT;
26 } else {
27 x = (i >= a->used) ? 0uL : a->dp[i];
30 /* convert to two complement if negative */
31 if (mp_isneg(b)) {
32 bc += (i >= b->used) ? MP_MASK : (~b->dp[i] & MP_MASK);
33 y = bc & MP_MASK;
34 bc >>= MP_DIGIT_BIT;
35 } else {
36 y = (i >= b->used) ? 0uL : b->dp[i];
39 c->dp[i] = x & y;
41 /* convert to to sign-magnitude if negative */
42 if (neg) {
43 cc += ~c->dp[i] & MP_MASK;
44 c->dp[i] = cc & MP_MASK;
45 cc >>= MP_DIGIT_BIT;
49 c->used = used;
50 c->sign = (neg ? MP_NEG : MP_ZPOS);
51 mp_clamp(c);
52 return MP_OKAY;
54 #endif