| 
									
										
										
										
											2018-09-10 18:48:58 +02:00
										 |  |  | #include "tommath_private.h"
 | 
					
						
							|  |  |  | #ifdef BN_MP_TC_XOR_C
 | 
					
						
							|  |  |  | /* LibTomMath, multiple-precision integer library -- Tom St Denis
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * LibTomMath is a library that provides multiple-precision | 
					
						
							|  |  |  |  * integer arithmetic as well as number theoretic functionality. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * The library was designed directly after the MPI library by | 
					
						
							|  |  |  |  * Michael Fromberger but has been written from scratch with | 
					
						
							|  |  |  |  * additional optimizations in place. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * The library is free for all purposes without any express | 
					
						
							|  |  |  |  * guarantee it works. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* two complement xor */ | 
					
						
							|  |  |  | int mp_tc_xor(const mp_int *a, const mp_int *b, mp_int *c) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |    int res = MP_OKAY, bits; | 
					
						
							| 
									
										
										
										
											2018-09-23 10:16:25 +02:00
										 |  |  |    int as = mp_isneg(a), bs = mp_isneg(b); | 
					
						
							| 
									
										
										
										
											2018-09-23 09:39:53 +02:00
										 |  |  |    mp_int *mx = NULL, _mx, acpy, bcpy; | 
					
						
							| 
									
										
										
										
											2018-09-10 18:48:58 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-23 10:26:47 +02:00
										 |  |  |    if ((as != MP_NO) || (bs != MP_NO)) { | 
					
						
							| 
									
										
										
										
											2018-09-10 18:48:58 +02:00
										 |  |  |       bits = MAX(mp_count_bits(a), mp_count_bits(b)); | 
					
						
							| 
									
										
										
										
											2018-09-23 09:46:31 +02:00
										 |  |  |       res = mp_init_set_int(&_mx, 1uL); | 
					
						
							| 
									
										
										
										
											2018-09-10 18:48:58 +02:00
										 |  |  |       if (res != MP_OKAY) { | 
					
						
							|  |  |  |          goto end; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       mx = &_mx; | 
					
						
							|  |  |  |       res = mp_mul_2d(mx, bits + 1, mx); | 
					
						
							|  |  |  |       if (res != MP_OKAY) { | 
					
						
							|  |  |  |          goto end; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-23 10:26:47 +02:00
										 |  |  |       if (as != MP_NO) { | 
					
						
							| 
									
										
										
										
											2018-09-10 18:48:58 +02:00
										 |  |  |          res = mp_init(&acpy); | 
					
						
							|  |  |  |          if (res != MP_OKAY) { | 
					
						
							|  |  |  |             goto end; | 
					
						
							|  |  |  |          } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |          res = mp_add(mx, a, &acpy); | 
					
						
							|  |  |  |          if (res != MP_OKAY) { | 
					
						
							|  |  |  |             mp_clear(&acpy); | 
					
						
							|  |  |  |             goto end; | 
					
						
							|  |  |  |          } | 
					
						
							|  |  |  |          a = &acpy; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2018-09-23 10:26:47 +02:00
										 |  |  |       if (bs != MP_NO) { | 
					
						
							| 
									
										
										
										
											2018-09-10 18:48:58 +02:00
										 |  |  |          res = mp_init(&bcpy); | 
					
						
							|  |  |  |          if (res != MP_OKAY) { | 
					
						
							|  |  |  |             goto end; | 
					
						
							|  |  |  |          } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |          res = mp_add(mx, b, &bcpy); | 
					
						
							|  |  |  |          if (res != MP_OKAY) { | 
					
						
							|  |  |  |             mp_clear(&bcpy); | 
					
						
							|  |  |  |             goto end; | 
					
						
							|  |  |  |          } | 
					
						
							|  |  |  |          b = &bcpy; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |    } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    res = mp_xor(a, b, c); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-23 10:16:25 +02:00
										 |  |  |    if ((as != bs) && (res == MP_OKAY)) { | 
					
						
							| 
									
										
										
										
											2018-09-10 18:48:58 +02:00
										 |  |  |       res = mp_sub(c, mx, c); | 
					
						
							|  |  |  |    } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | end: | 
					
						
							|  |  |  |    if (a == &acpy) { | 
					
						
							|  |  |  |       mp_clear(&acpy); | 
					
						
							|  |  |  |    } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    if (b == &bcpy) { | 
					
						
							|  |  |  |       mp_clear(&bcpy); | 
					
						
							|  |  |  |    } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    if (mx == &_mx) { | 
					
						
							|  |  |  |       mp_clear(mx); | 
					
						
							|  |  |  |    } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    return res; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ref:         $Format:%D$ */ | 
					
						
							|  |  |  | /* git commit:  $Format:%H$ */ | 
					
						
							|  |  |  | /* commit time: $Format:%ai$ */ |