Line data Source code
1 : #include "tommath_private.h" 2 : #ifdef BN_MP_AND_C 3 : /* LibTomMath, multiple-precision integer library -- Tom St Denis */ 4 : /* SPDX-License-Identifier: Unlicense */ 5 : 6 : /* two complement and */ 7 0 : mp_err mp_and(const mp_int *a, const mp_int *b, mp_int *c) 8 : { 9 0 : int used = MP_MAX(a->used, b->used) + 1, i; 10 0 : mp_err err; 11 0 : mp_digit ac = 1, bc = 1, cc = 1; 12 0 : mp_sign csign = ((a->sign == MP_NEG) && (b->sign == MP_NEG)) ? MP_NEG : MP_ZPOS; 13 : 14 0 : if (c->alloc < used) { 15 0 : if ((err = mp_grow(c, used)) != MP_OKAY) { 16 0 : return err; 17 : } 18 : } 19 : 20 0 : for (i = 0; i < used; i++) { 21 0 : mp_digit x, y; 22 : 23 : /* convert to two complement if negative */ 24 0 : if (a->sign == MP_NEG) { 25 0 : ac += (i >= a->used) ? MP_MASK : (~a->dp[i] & MP_MASK); 26 0 : x = ac & MP_MASK; 27 0 : ac >>= MP_DIGIT_BIT; 28 : } else { 29 0 : x = (i >= a->used) ? 0uL : a->dp[i]; 30 : } 31 : 32 : /* convert to two complement if negative */ 33 0 : if (b->sign == MP_NEG) { 34 0 : bc += (i >= b->used) ? MP_MASK : (~b->dp[i] & MP_MASK); 35 0 : y = bc & MP_MASK; 36 0 : bc >>= MP_DIGIT_BIT; 37 : } else { 38 0 : y = (i >= b->used) ? 0uL : b->dp[i]; 39 : } 40 : 41 0 : c->dp[i] = x & y; 42 : 43 : /* convert to to sign-magnitude if negative */ 44 0 : if (csign == MP_NEG) { 45 0 : cc += ~c->dp[i] & MP_MASK; 46 0 : c->dp[i] = cc & MP_MASK; 47 0 : cc >>= MP_DIGIT_BIT; 48 : } 49 : } 50 : 51 0 : c->used = used; 52 0 : c->sign = csign; 53 0 : mp_clamp(c); 54 0 : return MP_OKAY; 55 : } 56 : #endif