Line data Source code
1 : #include "tommath_private.h"
2 : #ifdef BN_MP_OR_C
3 : /* LibTomMath, multiple-precision integer library -- Tom St Denis */
4 : /* SPDX-License-Identifier: Unlicense */
5 :
6 : /* two complement or */
7 0 : mp_err mp_or(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 : 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 : 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
|