第4章 基本算法

第4章 基本算法

4.1 简介

在这里插入图片描述

4.2 加法和减法

在这里插入图片描述

4.2.1 低级加法

s_mp_add的原理

在这里插入图片描述

s_mp_add的实现
		/*无符号低级加法*/
18 		/* low level addition, based on HAC pp.594, Algorithm 14.7 */
19 		int
20 		s_mp_add (mp_int * a, mp_int * b, mp_int * c)
21 		{
22 		  mp_int *x;
23 		  int     olduse, res, min, max;
24 
			/*首先找到两个输入中的最大值*/
25 		  /* find sizes, we let |a| <= |b| which means we have to sort */
26 		  /* them.  "x" will point to the input with the most digits */
27 		  /**/
28 		  if (a->used > b->used) {
29 			min = b->used;
30 			max = a->used;
31 			x = a;
32 		  } else {
33 			min = a->used;
34 			max = b->used;
35 			x = b;
36 		  }
37 
			/*如果c.alloc<max+1,则增加c,使其至少包含max+1位*/
38 		  /* init result */
39 		  if (c->alloc < max + 1) {
40 			if ((res = mp_grow (c, max + 1)) != MP_OKAY) {
41 			  return res;
42 			}
43 		  }
44 
45 		  /* get old used digit count and set new one */
46 		  olduse = c->used;
47 		  c->used = max + 1;
48 
49 		  {
50 			register mp_digit u, *tmpa, *tmpb, *tmpc;
51 			register int i;
52 
53 			/* alias for digit pointers */
54 
55 			/* first input */
56 			tmpa = a->dp;
57 
58 			/* second input */
59 			tmpb = b->dp;
60 
61 			/* destination */
62 			tmpc = c->dp;
63 
64 			/* zero the carry */
65 			u = 0;
66 			for (i = 0; i < min; i++) {
67 			  /* Compute the sum at one digit, T[i] = A[i] + B[i] + U */
68 			  *tmpc = *tmpa++ + *tmpb++ + u;
69 
70 			  /* U = carry bit of T[i] */
71 			  u = *tmpc >> ((mp_digit)DIGIT_BIT);
72 
73 			  /* take away carry bit from T[i] */
74 			  *tmpc++ &= MP_MASK;
75 			}
76 
77 			/* now copy higher words if any, that is in A+B  */
78 			/* if A or B has more digits add those in  */
79 			/**/
80 			if (min != max) {
81 			  for (; i < max; i++) {
82 				/* T[i] = X[i] + U */
83 				*tmpc = x->dp[i] + u;
84 
85 				/* U = carry bit of T[i] */
86 				u = *tmpc >> ((mp_digit)DIGIT_BIT);
87 
88 				/* take away carry bit from T[i] */
89 				*tmpc++ &= MP_MASK;
90 			  }
91 			}
92 
93 			/* add carry */
94 			*tmpc++ = u;
95 
96 			/* clear digits above oldused */
97 			for (i = c->used; i < olduse; i++) {
98 			  *tmpc++ = 0;
99 			}
100		  }
101
			/*压缩c中的多余位*/
102		  mp_clamp (c);
103		  return MP_OKAY;
104		}

在这里插入图片描述

s_mp_add的使用
#include <stdio.h>
#include <stdlib.h>

#include "utils.h"

int main(){
    printf("hello libtommath\n");

    mp_int a,b,c;
    mp_init_multi(&a,&b,&c,NULL);
    mp_read_radix(&a,"a",16);
    mp_read_radix(&b,"2",16);
    s_mp_add(&a,&b,&c);
    printf("a和b相加的结果为:");
    MP_print(&c);
    return 0;
}
=============================================
:~/workspace/tommath_test$ ./a.out
hello libtommath
a和b相加的结果为: C

4.2.2 低级减法

s_mp_sub的原理

在这里插入图片描述

s_mp_sub的实现
		/*无符号低级减法*/
18		/* low level subtraction (assumes |a| > |b|), HAC pp.595 Algorithm 14.9 */
19		int
20		s_mp_sub (mp_int * a, mp_int * b, mp_int * c)
21		{
22		  int     olduse, res, min, max;
23
24		  /* find sizes */
25		  min = b->used;
26		  max = a->used;
27
			/*如果c.alloc<max,则增加c以便至少包含max位*/
28		  /* init result */
29		  if (c->alloc < max) {
30			if ((res = mp_grow (c, max)) != MP_OKAY) {
31			  return res;
32			}
33		  }
34		  olduse = c->used;
35		  c->used = max;
36
37		  {
38			register mp_digit u, *tmpa, *tmpb, *tmpc;
39			register int i;
40
41			/* alias for digit pointers */
42			tmpa = a->dp;
43			tmpb = b->dp;
44			tmpc = c->dp;
45
46			/* set carry to zero */
47			u = 0;
48			for (i = 0; i < min; i++) {
49			  /* T[i] = A[i] - B[i] - U */
50			  *tmpc = *tmpa++ - *tmpb++ - u;
51
52			  /* U = carry bit of T[i]*/
53			  /* Note this saves performing an AND operation since*/
54			  /* if a carry does occur it will propagate all the way to the*/
55			  /* MSB.  As a result a single shift is enough to get the carry*/
56			  /**/
57			  u = *tmpc >> ((mp_digit)(CHAR_BIT * sizeof (mp_digit) - 1));
58
59			  /* Clear carry from T[i] */
60			  *tmpc++ &= MP_MASK;
61			}
62
63			/* now copy higher words if any, e.g. if A has more digits than B  */
64			for (; i < max; i++) {
65			  /* T[i] = A[i] - U */
66			  *tmpc = *tmpa++ - u;
67
68			  /* U = carry bit of T[i] */
69			  u = *tmpc >> ((mp_digit)(CHAR_BIT * sizeof (mp_digit) - 1));
70
71			  /* Clear carry from T[i] */
72			  *tmpc++ &= MP_MASK;
73			}
74
75			/* clear digits above used (since we may not have grown result above) */
76			for (i = c->used; i < olduse; i++) {
77			  *tmpc++ = 0;
78			}
79		  }
80
81		  mp_clamp (c);
82		  return MP_OKAY;
83		}

在这里插入图片描述

s_mp_sub的使用
#include <stdio.h>
#include <stdlib.h>

#include "utils.h"

int main(){
    printf("hello libtommath\n");

    mp_int a,b,c;
    mp_init_multi(&a,&b,&c,NULL);
    mp_read_radix(&a,"a",16);
    mp_read_radix(&b,"2",16);
    s_mp_sub(&a,&b,&c);
    printf("a和b相减的结果为:");
    MP_print(&c);
    return 0;
}
=============================================
:~/workspace/tommath_test$ ./a.out
hello libtommath
a和b相加的结果为: 8

4.2.3 高级加法

mp_add的原理

在这里插入图片描述

mp_add的实现
		/*有符号加法*/
18		/* high level addition (handles signs) */
19		int mp_add (mp_int * a, mp_int * b, mp_int * c)
20		{
21		  int     sa, sb, res;
22
23		  /* get sign of both inputs */
24		  sa = a->sign;
25		  sb = b->sign;
26
			/*如果是a和b符号相同的情况*/
27		  /* handle two cases, not four */
28		  if (sa == sb) {
29			/* both positive or both negative */
30			/* add their magnitudes, copy the sign */
31			c->sign = sa;
			/*c=|a|+|b|*/
32			res = s_mp_add (a, b, c);
33		  } else {
34			/* one positive, the other negative */
35			/* subtract the one with the greater magnitude from */
36			/* the one of the lesser magnitude.  The result gets */
37			/* the sign of the one with the greater magnitude. */
			/*如果是|a|<|b|的情况*/
38			if (mp_cmp_mag (a, b) == MP_LT) {
39			  c->sign = sb;
			/*|c|=|b|-|a|*/
40			  res = s_mp_sub (b, a, c);
41			} else {
			/*如果是|a|>|b|的情况*/
42			  c->sign = sa;
			/*|c|=|a|-|b|*/
43			  res = s_mp_sub (a, b, c);
44			}
45		  }
46		  return res;
47		}

在这里插入图片描述

mp_add的使用
#include <stdio.h>
#include <stdlib.h>

#include "utils.h"

int main(){
    printf("hello libtommath\n");

    mp_int a,b,c;
    mp_init_multi(&a,&b,&c,NULL);
    mp_read_radix(&a,"a",16);
    mp_read_radix(&b,"-2",16);
    mp_add(&a,&b,&c);
    printf("a和b相加的结果为:");
    MP_print(&c);
    return 0;
}
==============================================
:~/workspace/tommath_test$ ./a.out
hello libtommath
a和b相加的结果为: 8

4.2.4 高级减法

mp_sub算法的原理

在这里插入图片描述

mp_sub算法的实现
		/*有符号减法运算*/
18		/* high level subtraction (handles signs) */
19		int 
20		mp_sub (mp_int * a, mp_int * b, mp_int * c)
21		{
22		  int     sa, sb, res;
23
24		  sa = a->sign;
25		  sb = b->sign;
26
			/*如果是a和b符号不同的情况*/
27		  if (sa != sb) {
28			/* subtract a negative from a positive, OR */
29			/* subtract a positive from a negative. */
30			/* In either case, ADD their magnitudes, */
31			/* and use the sign of the first number. */
32			c->sign = sa;
33			res = s_mp_add (a, b, c);
			/*如果是a和b符号相同的情况*/
34		  } else {
35			/* subtract a positive from a positive, OR */
36			/* subtract a negative from a negative. */
37			/* First, take the difference between their */
38			/* magnitudes, then... */
			/*如果是|a|>=|b|的情况*/
39			if (mp_cmp_mag (a, b) != MP_LT) {
40			  /* Copy the sign from the first */
41			  c->sign = sa;
42			  /* The first has a larger or equal magnitude */
43			  res = s_mp_sub (a, b, c);
44			} else {
			/*如果是|a|<|b|的情况*/
45			  /* The result has the *opposite* sign from */
46			  /* the first number. */
47			  c->sign = (sa == MP_ZPOS) ? MP_NEG : MP_ZPOS;
48			  /* The second has a larger magnitude */
49			  res = s_mp_sub (b, a, c);
50			}
51		  }
52		  return res;
53		}

在这里插入图片描述

mp_sub算法的使用
#include <stdio.h>
#include <stdlib.h>

#include "utils.h"

int main(){
    printf("hello libtommath\n");

    mp_int a,b,c;
    mp_init_multi(&a,&b,&c,NULL);
    mp_read_radix(&a,"a",16);
    mp_read_radix(&b,"-2",16);
    mp_sub(&a,&b,&c);
    printf("a和b相减的结果为:");
    MP_print(&c);
    return 0;
}
===================================================
:~/workspace/tommath_test$ ./a.out
hello libtommath
a和b相减的结果为: C

4.3 比特和数字移位

在这里插入图片描述

4.3.1 乘以2

mp_mul_2的原理

在这里插入图片描述

mp_mul_2的实现
18		/* b = a*2 */
19		int mp_mul_2(mp_int * a, mp_int * b)
20		{
21		  int     x, res, oldused;
22
			/*如果b.alloc<a.used+1,则将b增加为包含a.used+1位*/
23		  /* grow to accomodate result */
24		  if (b->alloc < a->used + 1) {
25			if ((res = mp_grow (b, a->used + 1)) != MP_OKAY) {
26			  return res;
27			}
28		  }
29
30		  oldused = b->used;
31		  b->used = a->used;
32
33		  {
34			register mp_digit r, rr, *tmpa, *tmpb;
35
36			/* alias for source */
37			tmpa = a->dp;
38			
39			/* alias for dest */
40			tmpb = b->dp;
41
42			/* carry */
43			r = 0;
44			for (x = 0; x < a->used; x++) {
45			
46			  /* get what will be the *next* carry bit from the */
47			  /* MSB of the current digit */
48			  /**/
49			  rr = *tmpa >> ((mp_digit)(DIGIT_BIT - 1));
50			  
51			  /* now shift up this digit, add in the carry [from the previous] */
52			  *tmpb++ = ((*tmpa++ << ((mp_digit)1)) | r) & MP_MASK;
53			  
54			  /* copy the carry that would be from the source */
55			  /* digit into the next iteration */
56			  /**/
57			  r = rr;
58			}
59
60			/* new leading digit? */
61			if (r != 0) {
62			  /* add a MSB which is always 1 at this point */
63			  *tmpb = 1;
64			  ++(b->used);
65			}
66
67			/* now zero any excess digits on the destination */
68			/* that we didn't write to */
69			/**/
70			tmpb = b->dp + b->used;
71			for (x = b->used; x < oldused; x++) {
72			  *tmpb++ = 0;
73			}
74		  }
75		  b->sign = a->sign;
76		  return MP_OKAY;
77		}

在这里插入图片描述

mp_mul_2的使用
#include <stdio.h>
#include <stdlib.h>

#include "utils.h"

int main(){
    printf("hello libtommath\n");

    mp_int a,b;
    mp_init_multi(&a,&b,NULL);
    mp_read_radix(&a,"a",16);
    mp_mul_2(&a,&b);
    printf("b的结果为:");
    MP_print(&b);
    return 0;
}
==========================================
:~/workspace/tommath_test$ ./a.out
hello libtommath
b的结果为: 14

4.3.2 除以2

mp_div_2的原理

在这里插入图片描述

mp_div_2的实现
		/*除以2运算*/
18		/* b = a/2 */
19		int mp_div_2(mp_int * a, mp_int * b)
20		{
21		  int     x, res, oldused;
22
23		  /* copy */
24		  if (b->alloc < a->used) {
25			if ((res = mp_grow (b, a->used)) != MP_OKAY) {
26			  return res;
27			}
28		  }
29
30		  oldused = b->used;
31		  b->used = a->used;
32		  {
33			register mp_digit r, rr, *tmpa, *tmpb;
34
35			/* source alias */
36			tmpa = a->dp + b->used - 1;
37
38			/* dest alias */
39			tmpb = b->dp + b->used - 1;
40
41			/* carry */
42			r = 0;
43			for (x = b->used - 1; x >= 0; x--) {
44			  /* get the carry for the next iteration */
45			  rr = *tmpa & 1;
46
47			  /* shift the current digit, add in carry and store */
48			  *tmpb-- = (*tmpa-- >> 1) | (r << (DIGIT_BIT - 1));
49
50			  /* forward carry to next iteration */
51			  r = rr;
52			}
53
54			/* zero excess digits */
55			tmpb = b->dp + b->used;
56			for (x = b->used; x < oldused; x++) {
57			  *tmpb++ = 0;
58			}
59		  }
60		  b->sign = a->sign;
61		  mp_clamp (b);
62		  return MP_OKAY;
63		}
mp_div_2的使用
#include <stdio.h>
#include <stdlib.h>

#include "utils.h"

int main(){
    printf("hello mp_div_2\n");

    mp_int a,b;
    mp_init_multi(&a,&b,NULL);
    mp_read_radix(&a,"a",16);
    mp_div_2(&a,&b);
    printf("b的结果为:");
    MP_print(&b);
    return 0;
}
=============================================
:~/workspace/tommath_test$ ./a.out
hello mp_div_2
b的结果为: 5

4.4 多项式基运算

在这里插入图片描述

4.4.1 乘以x

mp_lshd算法的原理

在这里插入图片描述

mp_lshd算法的实现
18		/* shift left a certain amount of digits */
19		int mp_lshd (mp_int * a, int b)
20		{
21		  int     x, res;
22
23		  /* if its less than zero return */
24		  if (b <= 0) {
25			return MP_OKAY;
26		  }
27
28		  /* grow to fit the new digits */
29		  if (a->alloc < a->used + b) {
30			 if ((res = mp_grow (a, a->used + b)) != MP_OKAY) {
31			   return res;
32			 }
33		  }
34
35		  {
36			register mp_digit *top, *bottom;
37
38			/* increment the used by the shift amount then copy upwards */
39			a->used += b;
40
41			/* top */
42			top = a->dp + a->used - 1;
43
44			/* base */
45			bottom = a->dp + a->used - 1 - b;
46
47			/* much like mp_rshd this is implemented using a sliding window*/
48			/* except the window goes the otherway around.  Copying from*/
49			/* the bottom to the top.  see bn_mp_rshd.c for more info.*/
50			/**/
51			for (x = a->used - 1; x >= b; x--) {
52			  *top-- = *bottom--;
53			}
54
55			/* zero the lower digits */
56			top = a->dp;
57			for (x = 0; x < b; x++) {
58			  *top++ = 0;
59			}
60		  }
61		  return MP_OKAY;
62		}

在这里插入图片描述

mp_lshd算法的使用
#include <stdio.h>
#include <stdlib.h>

#include "utils.h"

int main(){
    printf("hello mp_lshd\n");

    mp_int a;
    mp_init(&a);
    int b = 1;
    mp_read_radix(&a,"2",16);
    mp_lshd(&a,b);
    printf("a*b的结果为:");
    MP_print(&a);
    return 0;
}
==================================================
:~/workspace/tommath_test$ ./a.out
hello mp_lshd
a*b的结果为: 20000000 00000000

4.4.2 除以x

mp_rshd算法的原理

在这里插入图片描述

mp_rshd算法的实现
18		/* shift right a certain amount of digits */
19		void mp_rshd (mp_int * a, int b)
20		{
21		  int     x;
22
			/*如果b<=0,则返回*/
23		  /* if b <= 0 then ignore it */
24		  if (b <= 0) {
25			return;
26		  }
27
28		  /* if b > used then simply zero it and return */
29		  if (a->used <= b) {
30			mp_zero (a);
31			return;
32		  }
33
34		  {
35			register mp_digit *bottom, *top;
36
37			/* shift the digits down */
38
39			/* bottom */
40			bottom = a->dp;
41
42			/* top [offset into digits] */
43			top = a->dp + b;
44
45			/* this is implemented as a sliding window where 
46			 * the window is b-digits long and digits from 
47			 * the top of the window are copied to the bottom
48			 *
49			 * e.g.
50
51			 b-2 | b-1 | b0 | b1 | b2 | ... | bb |   ---->
52						 /\                   |      ---->
53						  \-------------------/      ---->
54			 */
55			for (x = 0; x < (a->used - b); x++) {
56			  *bottom++ = *top++;
57			}
58
59			/* zero the top digits */
60			for (; x < a->used; x++) {
61			  *bottom++ = 0;
62			}
63		  }
64		  
65		  /* remove excess digits */
66		  a->used -= b;
67		}

在这里插入图片描述

mp_rshd算法的使用
#include <stdio.h>
#include <stdlib.h>

#include "utils.h"

int main(){
    printf("hello mp_rshd\n");

    mp_int a;
    mp_init(&a);
    int b = 1;
    mp_read_radix(&a,"20202020202020202020202020202020",16);
    mp_rshd(&a,b);
    printf("a*b的结果为:");
    MP_print(&a);
    return 0;
}
================================================================
:~/workspace/tommath_test$ ./a.out
hello mp_lshd
a*b的结果为: 20202020 20202020 2

4.5 2的幂

在这里插入图片描述

4.5.1 乘以2的幂

mp_mul_2d的原理

在这里插入图片描述

mp_mul_2d的实现
18		/* shift left by a certain bit count */
19		int mp_mul_2d (mp_int * a, int b, mp_int * c)
20		{
21		  mp_digit d;
22		  int      res;
23
24		  /* copy */
25		  if (a != c) {
26			 if ((res = mp_copy (a, c)) != MP_OKAY) {
27			   return res;
28			 }
29		  }
30
31		  if (c->alloc < (int)(c->used + b/DIGIT_BIT + 1)) {
32			 if ((res = mp_grow (c, c->used + b / DIGIT_BIT + 1)) != MP_OKAY) {
33			   return res;
34			 }
35		  }
36
37		  /* shift by as many digits in the bit count */
38		  if (b >= (int)DIGIT_BIT) {
39			if ((res = mp_lshd (c, b / DIGIT_BIT)) != MP_OKAY) {
40			  return res;
41			}
42		  }
43
44		  /* shift any bit count < DIGIT_BIT */
45		  d = (mp_digit) (b % DIGIT_BIT);
46		  if (d != 0) {
47			register mp_digit *tmpc, shift, mask, r, rr;
48			register int x;
49
50			/* bitmask for carries */
51			mask = (((mp_digit)1) << d) - 1;
52
53			/* shift for msbs */
54			shift = DIGIT_BIT - d;
55
56			/* alias */
57			tmpc = c->dp;
58
59			/* carry */
60			r    = 0;
61			for (x = 0; x < c->used; x++) {
62			  /* get the higher bits of the current word */
63			  rr = (*tmpc >> shift) & mask;
64
65			  /* shift the current word and OR in the carry */
66			  *tmpc = ((*tmpc << d) | r) & MP_MASK;
67			  ++tmpc;
68
69			  /* set the carry to the carry bits of the current word */
70			  r = rr;
71			}
72			
73			/* set final carry */
74			if (r != 0) {
75			   c->dp[(c->used)++] = r;
76			}
77		  }
78		  mp_clamp (c);
79		  return MP_OKAY;
80		}

在这里插入图片描述

mp_mul_2d的使用
#include <stdio.h>
#include <stdlib.h>

#include "utils.h"

int main(){
    printf("hello libtommath\n");

    mp_int a,c;
    mp_init_multi(&a,&c,NULL);
    int b = 2;
    mp_read_radix(&a,"3",16);
    mp_mul_2d(&a,b,&c);
    printf("a*2^b的结果为:");
    MP_print(&c);
    return 0;
}
============================================
:~/workspace/tommath_test$ ./a.out
hello libtommath
a*2^b的结果为: C

4.5.2 除以2的幂

mp_div_2d的原理

在这里插入图片描述

mp_div_2d的实现
18 		/* shift right by a certain bit count */
19 		/*(store quotient in c, optional remainder in d) */
20 		int mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d)
21 		{
22 		  mp_digit D, r, rr;
23 		  int     x, res;
24 		  mp_int  t;
25 
26 
27 		  /* if the shift count is <= 0 then we do no work */
28 		  if (b <= 0) {
29 			res = mp_copy (a, c);
30 			if (d != NULL) {
31 			  mp_zero (d);
32 			}
33 			return res;
34 		  }
35 
36 		  if ((res = mp_init (&t)) != MP_OKAY) {
37 			return res;
38 		  }
39 
40 		  /* get the remainder */
41 		  if (d != NULL) {
42 			if ((res = mp_mod_2d (a, b, &t)) != MP_OKAY) {
43 			  mp_clear (&t);
44 			  return res;
45 			}
46 		  }
47 
48 		  /* copy */
49 		  if ((res = mp_copy (a, c)) != MP_OKAY) {
50 			mp_clear (&t);
51 			return res;
52 		  }
53 
54 		  /* shift by as many digits in the bit count */
55 		  if (b >= (int)DIGIT_BIT) {
56 			mp_rshd (c, b / DIGIT_BIT);
57 		  }
58 
59 		  /* shift any bit count < DIGIT_BIT */
60 		  D = (mp_digit) (b % DIGIT_BIT);
61 		  if (D != 0) {
62 			register mp_digit *tmpc, mask, shift;
63 
64 			/* mask */
65 			mask = (((mp_digit)1) << D) - 1;
66 
67 			/* shift for lsb */
68 			shift = DIGIT_BIT - D;
69 
70 			/* alias */
71 			tmpc = c->dp + (c->used - 1);
72 
73 			/* carry */
74 			r = 0;
75 			for (x = c->used - 1; x >= 0; x--) {
76 			  /* get the lower  bits of this word in a temp */
77 			  rr = *tmpc & mask;
78 
79 			  /* shift the current word and */
80 			  /*mix in the carry bits from the previous word */
81 			  *tmpc = (*tmpc >> D) | (r << shift);
82 			  --tmpc;
83 
84 			  /* set the carry to the carry bits of the current word found above */
85 			  r = rr;
86 			}
87 		  }
88 		  mp_clamp (c);
89 		  if (d != NULL) {
90 			mp_exch (&t, d);
91 		  }
92 		  mp_clear (&t);
93 		  return MP_OKAY;
94 		}

在这里插入图片描述

mp_div_2d的使用
#include <stdio.h>
#include <stdlib.h>

#include "utils.h"

int main(){
    printf("hello libtommath\n");

    mp_int a,c,d;
    mp_init_multi(&a,&c,&d,NULL);
    int b = 1;
    mp_read_radix(&a,"3",16);
    mp_div_2d(&a,b,&c,&d);
    printf("a/2^b的结果为:");
    MP_print(&c);
    printf("a%2^b的结果为:");
    MP_print(&d);
    return 0;
}
============================================
:~/workspace/tommath_test$ ./a.out
hello libtommath
a/2^b的结果为: 1
a%2^b的结果为: 1

4.5.3 除以2的幂的余数

mp_mod_2d的原理

在这里插入图片描述

mp_mod_2d的实现
18		/* calc a value mod 2**b */
19		int 
20		mp_mod_2d (mp_int * a, int b, mp_int * c)
21		{
22		  int     x, res;
23
24		  /* if b is <= 0 then zero the int */
25		  if (b <= 0) {
26			mp_zero (c);
27			return MP_OKAY;
28		  }
29
30		  /* if the modulus is larger than the value than return */
31		  if (b >= (int) (a->used * DIGIT_BIT)) {
32			res = mp_copy (a, c);
33			return res;
34		  }
35
36		  /* copy */
37		  if ((res = mp_copy (a, c)) != MP_OKAY) {
38			return res;
39		  }
40
41		  /* zero digits above the last digit of the modulus */
42		  for (x = (b / DIGIT_BIT) + ((b % DIGIT_BIT) == 0 ? 0 : 1); 
43		  x < c->used; x++) {
44			c->dp[x] = 0;
45		  }
46		  /* clear the digit that is not completely outside/inside the modulus */
47		  c->dp[b / DIGIT_BIT] &=
48			(mp_digit) ((((mp_digit) 1) << (((mp_digit) b) % DIGIT_BIT)) - 
49						((mp_digit) 1));
50		  mp_clamp (c);
51		  return MP_OKAY;
52		}

在这里插入图片描述

mp_mod_2d的使用
#include <stdio.h>
#include <stdlib.h>

#include "utils.h"

int main(){
    printf("hello libtommath\n");

    mp_int a,c;
    mp_init_multi(&a,&c,NULL);
    int b = 1;
    mp_read_radix(&a,"3",16);
    mp_mod_2d(&a,b,&c);
    printf("a%2^b的结果为:");
    MP_print(&c);

    return 0;
}
======================================
:~/workspace/tommath_test$ ./a.out
hello libtommath
a%2^b的结果为: 1
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值