comparison libtommath/bn_mp_and.c @ 1739:13d834efc376 fuzz

merge from main
author Matt Johnston <matt@ucc.asn.au>
date Thu, 15 Oct 2020 19:55:15 +0800
parents 1051e4eea25a
children
comparison
equal deleted inserted replaced
1562:768ebf737aa0 1739:13d834efc376
1 #include <tommath_private.h> 1 #include "tommath_private.h"
2 #ifdef BN_MP_AND_C 2 #ifdef BN_MP_AND_C
3 /* LibTomMath, multiple-precision integer library -- Tom St Denis 3 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
4 * 4 /* SPDX-License-Identifier: Unlicense */
5 * LibTomMath is a library that provides multiple-precision
6 * integer arithmetic as well as number theoretic functionality.
7 *
8 * The library was designed directly after the MPI library by
9 * Michael Fromberger but has been written from scratch with
10 * additional optimizations in place.
11 *
12 * The library is free for all purposes without any express
13 * guarantee it works.
14 *
15 * Tom St Denis, [email protected], http://libtom.org
16 */
17 5
18 /* AND two ints together */ 6 /* two complement and */
19 int 7 mp_err mp_and(const mp_int *a, const mp_int *b, mp_int *c)
20 mp_and (mp_int * a, mp_int * b, mp_int * c)
21 { 8 {
22 int res, ix, px; 9 int used = MP_MAX(a->used, b->used) + 1, i;
23 mp_int t, *x; 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;
24 13
25 if (a->used > b->used) { 14 if (c->alloc < used) {
26 if ((res = mp_init_copy (&t, a)) != MP_OKAY) { 15 if ((err = mp_grow(c, used)) != MP_OKAY) {
27 return res; 16 return err;
28 } 17 }
29 px = b->used; 18 }
30 x = b;
31 } else {
32 if ((res = mp_init_copy (&t, b)) != MP_OKAY) {
33 return res;
34 }
35 px = a->used;
36 x = a;
37 }
38 19
39 for (ix = 0; ix < px; ix++) { 20 for (i = 0; i < used; i++) {
40 t.dp[ix] &= x->dp[ix]; 21 mp_digit x, y;
41 }
42 22
43 /* zero digits above the last from the smallest mp_int */ 23 /* convert to two complement if negative */
44 for (; ix < t.used; ix++) { 24 if (a->sign == MP_NEG) {
45 t.dp[ix] = 0; 25 ac += (i >= a->used) ? MP_MASK : (~a->dp[i] & MP_MASK);
46 } 26 x = ac & MP_MASK;
27 ac >>= MP_DIGIT_BIT;
28 } else {
29 x = (i >= a->used) ? 0uL : a->dp[i];
30 }
47 31
48 mp_clamp (&t); 32 /* convert to two complement if negative */
49 mp_exch (c, &t); 33 if (b->sign == MP_NEG) {
50 mp_clear (&t); 34 bc += (i >= b->used) ? MP_MASK : (~b->dp[i] & MP_MASK);
51 return MP_OKAY; 35 y = bc & MP_MASK;
36 bc >>= MP_DIGIT_BIT;
37 } else {
38 y = (i >= b->used) ? 0uL : 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 }
50
51 c->used = used;
52 c->sign = csign;
53 mp_clamp(c);
54 return MP_OKAY;
52 } 55 }
53 #endif 56 #endif
54
55 /* ref: $Format:%D$ */
56 /* git commit: $Format:%H$ */
57 /* commit time: $Format:%ai$ */