Improving performance of bn_mp_expt_d
The loop was always iterating DIGIT_BIT times, instead of halting when possible. This changes makes sure it executes less operations. This change has also been incorporated into Rubinius / https://github.com/evanphx/rubinius which uses libtommath
This commit is contained in:
		
							parent
							
								
									5fc6314643
								
							
						
					
					
						commit
						921be35779
					
				@ -18,7 +18,7 @@
 | 
				
			|||||||
/* calculate c = a**b  using a square-multiply algorithm */
 | 
					/* calculate c = a**b  using a square-multiply algorithm */
 | 
				
			||||||
int mp_expt_d (mp_int * a, mp_digit b, mp_int * c)
 | 
					int mp_expt_d (mp_int * a, mp_digit b, mp_int * c)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  int     res, x;
 | 
					  int     res;
 | 
				
			||||||
  mp_int  g;
 | 
					  mp_int  g;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if ((res = mp_init_copy (&g, a)) != MP_OKAY) {
 | 
					  if ((res = mp_init_copy (&g, a)) != MP_OKAY) {
 | 
				
			||||||
@ -28,23 +28,23 @@ int mp_expt_d (mp_int * a, mp_digit b, mp_int * c)
 | 
				
			|||||||
  /* set initial result */
 | 
					  /* set initial result */
 | 
				
			||||||
  mp_set (c, 1);
 | 
					  mp_set (c, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  for (x = 0; x < (int) DIGIT_BIT; x++) {
 | 
					  while (b > 0) {
 | 
				
			||||||
 | 
					    /* if the bit is set multiply */
 | 
				
			||||||
 | 
					    if (b & 1) {
 | 
				
			||||||
 | 
					      if ((res = mp_mul (c, &g, c)) != MP_OKAY) {
 | 
				
			||||||
 | 
					        mp_clear (&g);
 | 
				
			||||||
 | 
					        return res;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* square */
 | 
					    /* square */
 | 
				
			||||||
    if ((res = mp_sqr (c, c)) != MP_OKAY) {
 | 
					    if (b > 1 && (res = mp_sqr (c, c)) != MP_OKAY) {
 | 
				
			||||||
      mp_clear (&g);
 | 
					      mp_clear (&g);
 | 
				
			||||||
      return res;
 | 
					      return res;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* if the bit is set multiply */
 | 
					 | 
				
			||||||
    if ((b & (mp_digit) (((mp_digit)1) << (DIGIT_BIT - 1))) != 0) {
 | 
					 | 
				
			||||||
      if ((res = mp_mul (c, &g, c)) != MP_OKAY) {
 | 
					 | 
				
			||||||
         mp_clear (&g);
 | 
					 | 
				
			||||||
         return res;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* shift to next bit */
 | 
					    /* shift to next bit */
 | 
				
			||||||
    b <<= 1;
 | 
					    b >>= 1;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  mp_clear (&g);
 | 
					  mp_clear (&g);
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user