jdk/src/share/native/sun/security/ec/mplogic.c
changeset 3492 e549cea58864
equal deleted inserted replaced
3480:c197e38bf15a 3492:e549cea58864
       
     1 /* *********************************************************************
       
     2  *
       
     3  * Sun elects to have this file available under and governed by the
       
     4  * Mozilla Public License Version 1.1 ("MPL") (see
       
     5  * http://www.mozilla.org/MPL/ for full license text). For the avoidance
       
     6  * of doubt and subject to the following, Sun also elects to allow
       
     7  * licensees to use this file under the MPL, the GNU General Public
       
     8  * License version 2 only or the Lesser General Public License version
       
     9  * 2.1 only. Any references to the "GNU General Public License version 2
       
    10  * or later" or "GPL" in the following shall be construed to mean the
       
    11  * GNU General Public License version 2 only. Any references to the "GNU
       
    12  * Lesser General Public License version 2.1 or later" or "LGPL" in the
       
    13  * following shall be construed to mean the GNU Lesser General Public
       
    14  * License version 2.1 only. However, the following notice accompanied
       
    15  * the original version of this file:
       
    16  *
       
    17  *
       
    18  *  Bitwise logical operations on MPI values
       
    19  *
       
    20  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       
    21  *
       
    22  * The contents of this file are subject to the Mozilla Public License Version
       
    23  * 1.1 (the "License"); you may not use this file except in compliance with
       
    24  * the License. You may obtain a copy of the License at
       
    25  * http://www.mozilla.org/MPL/
       
    26  *
       
    27  * Software distributed under the License is distributed on an "AS IS" basis,
       
    28  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
       
    29  * for the specific language governing rights and limitations under the
       
    30  * License.
       
    31  *
       
    32  * The Original Code is the MPI Arbitrary Precision Integer Arithmetic library.
       
    33  *
       
    34  * The Initial Developer of the Original Code is
       
    35  * Michael J. Fromberger.
       
    36  * Portions created by the Initial Developer are Copyright (C) 1998
       
    37  * the Initial Developer. All Rights Reserved.
       
    38  *
       
    39  * Contributor(s):
       
    40  *
       
    41  * Alternatively, the contents of this file may be used under the terms of
       
    42  * either the GNU General Public License Version 2 or later (the "GPL"), or
       
    43  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
       
    44  * in which case the provisions of the GPL or the LGPL are applicable instead
       
    45  * of those above. If you wish to allow use of your version of this file only
       
    46  * under the terms of either the GPL or the LGPL, and not to allow others to
       
    47  * use your version of this file under the terms of the MPL, indicate your
       
    48  * decision by deleting the provisions above and replace them with the notice
       
    49  * and other provisions required by the GPL or the LGPL. If you do not delete
       
    50  * the provisions above, a recipient may use your version of this file under
       
    51  * the terms of any one of the MPL, the GPL or the LGPL.
       
    52  *
       
    53  *********************************************************************** */
       
    54 /*
       
    55  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
       
    56  * Use is subject to license terms.
       
    57  */
       
    58 
       
    59 #pragma ident   "%Z%%M% %I%     %E% SMI"
       
    60 
       
    61 /* $Id: mplogic.c,v 1.15 2004/04/27 23:04:36 gerv%gerv.net Exp $ */
       
    62 
       
    63 #include "mpi-priv.h"
       
    64 #include "mplogic.h"
       
    65 
       
    66 /* {{{ Lookup table for population count */
       
    67 
       
    68 static unsigned char bitc[] = {
       
    69    0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
       
    70    1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
       
    71    1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
       
    72    2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
       
    73    1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
       
    74    2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
       
    75    2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
       
    76    3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
       
    77    1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
       
    78    2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
       
    79    2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
       
    80    3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
       
    81    2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
       
    82    3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
       
    83    3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
       
    84    4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
       
    85 };
       
    86 
       
    87 /* }}} */
       
    88 
       
    89 /*
       
    90   mpl_rsh(a, b, d)     - b = a >> d
       
    91   mpl_lsh(a, b, d)     - b = a << d
       
    92  */
       
    93 
       
    94 /* {{{ mpl_rsh(a, b, d) */
       
    95 
       
    96 mp_err mpl_rsh(const mp_int *a, mp_int *b, mp_digit d)
       
    97 {
       
    98   mp_err   res;
       
    99 
       
   100   ARGCHK(a != NULL && b != NULL, MP_BADARG);
       
   101 
       
   102   if((res = mp_copy(a, b)) != MP_OKAY)
       
   103     return res;
       
   104 
       
   105   s_mp_div_2d(b, d);
       
   106 
       
   107   return MP_OKAY;
       
   108 
       
   109 } /* end mpl_rsh() */
       
   110 
       
   111 /* }}} */
       
   112 
       
   113 /* {{{ mpl_lsh(a, b, d) */
       
   114 
       
   115 mp_err mpl_lsh(const mp_int *a, mp_int *b, mp_digit d)
       
   116 {
       
   117   mp_err   res;
       
   118 
       
   119   ARGCHK(a != NULL && b != NULL, MP_BADARG);
       
   120 
       
   121   if((res = mp_copy(a, b)) != MP_OKAY)
       
   122     return res;
       
   123 
       
   124   return s_mp_mul_2d(b, d);
       
   125 
       
   126 } /* end mpl_lsh() */
       
   127 
       
   128 /* }}} */
       
   129 
       
   130 /*------------------------------------------------------------------------*/
       
   131 /*
       
   132   mpl_set_bit
       
   133 
       
   134   Returns MP_OKAY or some error code.
       
   135   Grows a if needed to set a bit to 1.
       
   136  */
       
   137 mp_err mpl_set_bit(mp_int *a, mp_size bitNum, mp_size value)
       
   138 {
       
   139   mp_size      ix;
       
   140   mp_err       rv;
       
   141   mp_digit     mask;
       
   142 
       
   143   ARGCHK(a != NULL, MP_BADARG);
       
   144 
       
   145   ix = bitNum / MP_DIGIT_BIT;
       
   146   if (ix + 1 > MP_USED(a)) {
       
   147     rv = s_mp_pad(a, ix + 1);
       
   148     if (rv != MP_OKAY)
       
   149       return rv;
       
   150   }
       
   151 
       
   152   bitNum = bitNum % MP_DIGIT_BIT;
       
   153   mask = (mp_digit)1 << bitNum;
       
   154   if (value)
       
   155     MP_DIGIT(a,ix) |= mask;
       
   156   else
       
   157     MP_DIGIT(a,ix) &= ~mask;
       
   158   s_mp_clamp(a);
       
   159   return MP_OKAY;
       
   160 }
       
   161 
       
   162 /*
       
   163   mpl_get_bit
       
   164 
       
   165   returns 0 or 1 or some (negative) error code.
       
   166  */
       
   167 mp_err mpl_get_bit(const mp_int *a, mp_size bitNum)
       
   168 {
       
   169   mp_size      bit, ix;
       
   170   mp_err       rv;
       
   171 
       
   172   ARGCHK(a != NULL, MP_BADARG);
       
   173 
       
   174   ix = bitNum / MP_DIGIT_BIT;
       
   175   ARGCHK(ix <= MP_USED(a) - 1, MP_RANGE);
       
   176 
       
   177   bit   = bitNum % MP_DIGIT_BIT;
       
   178   rv = (mp_err)(MP_DIGIT(a, ix) >> bit) & 1;
       
   179   return rv;
       
   180 }
       
   181 
       
   182 /*
       
   183   mpl_get_bits
       
   184   - Extracts numBits bits from a, where the least significant extracted bit
       
   185   is bit lsbNum.  Returns a negative value if error occurs.
       
   186   - Because sign bit is used to indicate error, maximum number of bits to
       
   187   be returned is the lesser of (a) the number of bits in an mp_digit, or
       
   188   (b) one less than the number of bits in an mp_err.
       
   189   - lsbNum + numbits can be greater than the number of significant bits in
       
   190   integer a, as long as bit lsbNum is in the high order digit of a.
       
   191  */
       
   192 mp_err mpl_get_bits(const mp_int *a, mp_size lsbNum, mp_size numBits)
       
   193 {
       
   194   mp_size    rshift = (lsbNum % MP_DIGIT_BIT);
       
   195   mp_size    lsWndx = (lsbNum / MP_DIGIT_BIT);
       
   196   mp_digit * digit  = MP_DIGITS(a) + lsWndx;
       
   197   mp_digit   mask   = ((1 << numBits) - 1);
       
   198 
       
   199   ARGCHK(numBits < CHAR_BIT * sizeof mask, MP_BADARG);
       
   200   ARGCHK(MP_HOWMANY(lsbNum, MP_DIGIT_BIT) <= MP_USED(a), MP_RANGE);
       
   201 
       
   202   if ((numBits + lsbNum % MP_DIGIT_BIT <= MP_DIGIT_BIT) ||
       
   203       (lsWndx + 1 >= MP_USED(a))) {
       
   204     mask &= (digit[0] >> rshift);
       
   205   } else {
       
   206     mask &= ((digit[0] >> rshift) | (digit[1] << (MP_DIGIT_BIT - rshift)));
       
   207   }
       
   208   return (mp_err)mask;
       
   209 }
       
   210 
       
   211 /*
       
   212   mpl_significant_bits
       
   213   returns number of significnant bits in abs(a).
       
   214   returns 1 if value is zero.
       
   215  */
       
   216 mp_err mpl_significant_bits(const mp_int *a)
       
   217 {
       
   218   mp_err bits   = 0;
       
   219   int    ix;
       
   220 
       
   221   ARGCHK(a != NULL, MP_BADARG);
       
   222 
       
   223   ix = MP_USED(a);
       
   224   for (ix = MP_USED(a); ix > 0; ) {
       
   225     mp_digit d;
       
   226     d = MP_DIGIT(a, --ix);
       
   227     if (d) {
       
   228       while (d) {
       
   229         ++bits;
       
   230         d >>= 1;
       
   231       }
       
   232       break;
       
   233     }
       
   234   }
       
   235   bits += ix * MP_DIGIT_BIT;
       
   236   if (!bits)
       
   237     bits = 1;
       
   238   return bits;
       
   239 }
       
   240 
       
   241 /*------------------------------------------------------------------------*/
       
   242 /* HERE THERE BE DRAGONS                                                  */