1  //FIXME Not checked on threadsafety yet; after checking please remove this line


2  /* crypto/bn/bn_shift.c */


3  /* Copyright (C) 19951998 Eric Young (eay@cryptsoft.com)


4  * All rights reserved.


5  *


6  * This package is an SSL implementation written


7  * by Eric Young (eay@cryptsoft.com).


8  * The implementation was written so as to conform with Netscapes SSL.


9  *


10  * This library is free for commercial and noncommercial use as long as


11  * the following conditions are aheared to. The following conditions


12  * apply to all code found in this distribution, be it the RC4, RSA,


13  * lhash, DES, etc., code; not just the SSL code. The SSL documentation


14  * included with this distribution is covered by the same copyright terms


15  * except that the holder is Tim Hudson (tjh@cryptsoft.com).


16  *


17  * Copyright remains Eric Young's, and as such any Copyright notices in


18  * the code are not to be removed.


19  * If this package is used in a product, Eric Young should be given attribution


20  * as the author of the parts of the library used.


21  * This can be in the form of a textual message at program startup or


22  * in documentation (online or textual) provided with the package.


23  *


24  * Redistribution and use in source and binary forms, with or without


25  * modification, are permitted provided that the following conditions


26  * are met:


27  * 1. Redistributions of source code must retain the copyright


28  * notice, this list of conditions and the following disclaimer.


29  * 2. Redistributions in binary form must reproduce the above copyright


30  * notice, this list of conditions and the following disclaimer in the


31  * documentation and/or other materials provided with the distribution.


32  * 3. All advertising materials mentioning features or use of this software


33  * must display the following acknowledgement:


34  * "This product includes cryptographic software written by


35  * Eric Young (eay@cryptsoft.com)"


36  * The word 'cryptographic' can be left out if the rouines from the library


37  * being used are not cryptographic related :).


38  * 4. If you include any Windows specific code (or a derivative thereof) from


39  * the apps directory (application code) you must include an acknowledgement:


40  * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"


41  *


42  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND


43  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE


44  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE


45  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE


46  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL


47  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS


48  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)


49  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT


50  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY


51  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF


52  * SUCH DAMAGE.


53  *


54  * The licence and distribution terms for any publically available version or


55  * derivative of this code cannot be changed. i.e. this code cannot simply be


56  * copied and put under another distribution licence


57  * [including the GNU Public Licence.]


58  */


59 


60  #include <stdio.h>


61  #include <string.h>


62  #include "bn_lcl.h"


63  #include "openssl_mods.h"


64 


65  int BN_lshift1(BIGNUM *r, BIGNUM *a)


66  {


67  register BN_ULONG *ap,*rp,t,c;


68  int i;


69 


70  if (r != a)


71  {


72  r>neg=a>neg;


73  if (bn_wexpand(r,a>top+1) == NULL) return(0);


74  r>top=a>top;


75  }


76  else


77  {


78  if (bn_wexpand(r,a>top+1) == NULL) return(0);


79  }


80  ap=a>d;


81  rp=r>d;


82  c=0;


83  for (i=0; i<a>top; i++)


84  {


85  t= *(ap++);


86  *(rp++)=((t<<1)c)&BN_MASK2;


87  c=(t & BN_TBIT)?1:0;


88  }


89  if (c)


90  {


91  *rp=1;


92  r>top++;


93  }


94  return(1);


95  }


96 


97  int BN_rshift1(BIGNUM *r, BIGNUM *a)


98  {


99  BN_ULONG *ap,*rp,t,c;


100  int i;


101 


102  if (BN_is_zero(a))


103  {


104  BN_zero(r);


105  return(1);


106  }


107  if (a != r)


108  {


109  if (bn_wexpand(r,a>top) == NULL) return(0);


110  r>top=a>top;


111  r>neg=a>neg;


112  }


113  ap=a>d;


114  rp=r>d;


115  c=0;


116  for (i=a>top1; i>=0; i)


117  {


118  t=ap[i];


119  rp[i]=((t>>1)&BN_MASK2)c;


120  c=(t&1)?BN_TBIT:0;


121  }


122  bn_fix_top(r);


123  return(1);


124  }


125 


126  int BN_lshift(BIGNUM *r, const BIGNUM *a, int n)


127  {


128  int i,nw,lb,rb;


129  BN_ULONG *t,*f;


130  BN_ULONG l;


131 


132  r>neg=a>neg;


133  if (bn_wexpand(r,a>top+(n/BN_BITS2)+1) == NULL) return(0);


134  nw=n/BN_BITS2;


135  lb=n%BN_BITS2;


136  rb=BN_BITS2lb;


137  f=a>d;


138  t=r>d;


139  t[a>top+nw]=0;


140  if (lb == 0)


141  for (i=a>top1; i>=0; i)


142  t[nw+i]=f[i];


143  else


144  for (i=a>top1; i>=0; i)


145  {


146  l=f[i];


147  t[nw+i+1]=(l>>rb)&BN_MASK2;


148  t[nw+i]=(l<<lb)&BN_MASK2;


149  }


150  memset(t,0,nw*sizeof(t[0]));


151  /* for (i=0; i<nw; i++)


152  t[i]=0;*/


153  r>top=a>top+nw+1;


154  bn_fix_top(r);


155  return(1);


156  }


157 


158  int BN_rshift(BIGNUM *r, BIGNUM *a, int n)


159  {


160  int i,j,nw,lb,rb;


161  BN_ULONG *t,*f;


162  BN_ULONG l,tmp;


163 


164  nw=n/BN_BITS2;


165  rb=n%BN_BITS2;


166  lb=BN_BITS2rb;


167  if (nw > a>top  a>top == 0)


168  {


169  BN_zero(r);


170  return(1);


171  }


172  if (r != a)


173  {


174  r>neg=a>neg;


175  if (bn_wexpand(r,a>topnw+1) == NULL) return(0);


176  }


177  else


178  {


179  if (n == 0)


180  return 1; /* or the copying loop will go berserk */


181  }


182 


183  f= &(a>d[nw]);


184  t=r>d;


185  j=a>topnw;


186  r>top=j;


187 


188  if (rb == 0)


189  {


190  for (i=j+1; i > 0; i)


191  *(t++)= *(f++);


192  }


193  else


194  {


195  l= *(f++);


196  for (i=1; i<j; i++)


197  {


198  tmp =(l>>rb)&BN_MASK2;


199  l= *(f++);


200  *(t++) =(tmp(l<<lb))&BN_MASK2;


201  }


202  *(t++) =(l>>rb)&BN_MASK2;


203  }


204  *t=0;


205  bn_fix_top(r);


206  return(1);


207  }

