jdk/src/jdk.crypto.ec/share/native/libsunec/impl/ec2_233.c
changeset 25859 3317bb8137f4
parent 9774 50a2b28ca54c
equal deleted inserted replaced
25858:836adbf7a2cd 25859:3317bb8137f4
       
     1 /*
       
     2  * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
       
     3  * Use is subject to license terms.
       
     4  *
       
     5  * This library is free software; you can redistribute it and/or
       
     6  * modify it under the terms of the GNU Lesser General Public
       
     7  * License as published by the Free Software Foundation; either
       
     8  * version 2.1 of the License, or (at your option) any later version.
       
     9  *
       
    10  * This library is distributed in the hope that it will be useful,
       
    11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    13  * Lesser General Public License for more details.
       
    14  *
       
    15  * You should have received a copy of the GNU Lesser General Public License
       
    16  * along with this library; if not, write to the Free Software Foundation,
       
    17  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
       
    18  *
       
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    20  * or visit www.oracle.com if you need additional information or have any
       
    21  * questions.
       
    22  */
       
    23 
       
    24 /* *********************************************************************
       
    25  *
       
    26  * The Original Code is the elliptic curve math library for binary polynomial field curves.
       
    27  *
       
    28  * The Initial Developer of the Original Code is
       
    29  * Sun Microsystems, Inc.
       
    30  * Portions created by the Initial Developer are Copyright (C) 2003
       
    31  * the Initial Developer. All Rights Reserved.
       
    32  *
       
    33  * Contributor(s):
       
    34  *   Sheueling Chang-Shantz <sheueling.chang@sun.com>,
       
    35  *   Stephen Fung <fungstep@hotmail.com>, and
       
    36  *   Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories.
       
    37  *
       
    38  *********************************************************************** */
       
    39 
       
    40 #include "ec2.h"
       
    41 #include "mp_gf2m.h"
       
    42 #include "mp_gf2m-priv.h"
       
    43 #include "mpi.h"
       
    44 #include "mpi-priv.h"
       
    45 #ifndef _KERNEL
       
    46 #include <stdlib.h>
       
    47 #endif
       
    48 
       
    49 /* Fast reduction for polynomials over a 233-bit curve. Assumes reduction
       
    50  * polynomial with terms {233, 74, 0}. */
       
    51 mp_err
       
    52 ec_GF2m_233_mod(const mp_int *a, mp_int *r, const GFMethod *meth)
       
    53 {
       
    54         mp_err res = MP_OKAY;
       
    55         mp_digit *u, z;
       
    56 
       
    57         if (a != r) {
       
    58                 MP_CHECKOK(mp_copy(a, r));
       
    59         }
       
    60 #ifdef ECL_SIXTY_FOUR_BIT
       
    61         if (MP_USED(r) < 8) {
       
    62                 MP_CHECKOK(s_mp_pad(r, 8));
       
    63         }
       
    64         u = MP_DIGITS(r);
       
    65         MP_USED(r) = 8;
       
    66 
       
    67         /* u[7] only has 18 significant bits */
       
    68         z = u[7];
       
    69         u[4] ^= (z << 33) ^ (z >> 41);
       
    70         u[3] ^= (z << 23);
       
    71         z = u[6];
       
    72         u[4] ^= (z >> 31);
       
    73         u[3] ^= (z << 33) ^ (z >> 41);
       
    74         u[2] ^= (z << 23);
       
    75         z = u[5];
       
    76         u[3] ^= (z >> 31);
       
    77         u[2] ^= (z << 33) ^ (z >> 41);
       
    78         u[1] ^= (z << 23);
       
    79         z = u[4];
       
    80         u[2] ^= (z >> 31);
       
    81         u[1] ^= (z << 33) ^ (z >> 41);
       
    82         u[0] ^= (z << 23);
       
    83         z = u[3] >> 41;                         /* z only has 23 significant bits */
       
    84         u[1] ^= (z << 10);
       
    85         u[0] ^= z;
       
    86         /* clear bits above 233 */
       
    87         u[7] = u[6] = u[5] = u[4] = 0;
       
    88         u[3] ^= z << 41;
       
    89 #else
       
    90         if (MP_USED(r) < 15) {
       
    91                 MP_CHECKOK(s_mp_pad(r, 15));
       
    92         }
       
    93         u = MP_DIGITS(r);
       
    94         MP_USED(r) = 15;
       
    95 
       
    96         /* u[14] only has 18 significant bits */
       
    97         z = u[14];
       
    98         u[9] ^= (z << 1);
       
    99         u[7] ^= (z >> 9);
       
   100         u[6] ^= (z << 23);
       
   101         z = u[13];
       
   102         u[9] ^= (z >> 31);
       
   103         u[8] ^= (z << 1);
       
   104         u[6] ^= (z >> 9);
       
   105         u[5] ^= (z << 23);
       
   106         z = u[12];
       
   107         u[8] ^= (z >> 31);
       
   108         u[7] ^= (z << 1);
       
   109         u[5] ^= (z >> 9);
       
   110         u[4] ^= (z << 23);
       
   111         z = u[11];
       
   112         u[7] ^= (z >> 31);
       
   113         u[6] ^= (z << 1);
       
   114         u[4] ^= (z >> 9);
       
   115         u[3] ^= (z << 23);
       
   116         z = u[10];
       
   117         u[6] ^= (z >> 31);
       
   118         u[5] ^= (z << 1);
       
   119         u[3] ^= (z >> 9);
       
   120         u[2] ^= (z << 23);
       
   121         z = u[9];
       
   122         u[5] ^= (z >> 31);
       
   123         u[4] ^= (z << 1);
       
   124         u[2] ^= (z >> 9);
       
   125         u[1] ^= (z << 23);
       
   126         z = u[8];
       
   127         u[4] ^= (z >> 31);
       
   128         u[3] ^= (z << 1);
       
   129         u[1] ^= (z >> 9);
       
   130         u[0] ^= (z << 23);
       
   131         z = u[7] >> 9;                          /* z only has 23 significant bits */
       
   132         u[3] ^= (z >> 22);
       
   133         u[2] ^= (z << 10);
       
   134         u[0] ^= z;
       
   135         /* clear bits above 233 */
       
   136         u[14] = u[13] = u[12] = u[11] = u[10] = u[9] = u[8] = 0;
       
   137         u[7] ^= z << 9;
       
   138 #endif
       
   139         s_mp_clamp(r);
       
   140 
       
   141   CLEANUP:
       
   142         return res;
       
   143 }
       
   144 
       
   145 /* Fast squaring for polynomials over a 233-bit curve. Assumes reduction
       
   146  * polynomial with terms {233, 74, 0}. */
       
   147 mp_err
       
   148 ec_GF2m_233_sqr(const mp_int *a, mp_int *r, const GFMethod *meth)
       
   149 {
       
   150         mp_err res = MP_OKAY;
       
   151         mp_digit *u, *v;
       
   152 
       
   153         v = MP_DIGITS(a);
       
   154 
       
   155 #ifdef ECL_SIXTY_FOUR_BIT
       
   156         if (MP_USED(a) < 4) {
       
   157                 return mp_bsqrmod(a, meth->irr_arr, r);
       
   158         }
       
   159         if (MP_USED(r) < 8) {
       
   160                 MP_CHECKOK(s_mp_pad(r, 8));
       
   161         }
       
   162         MP_USED(r) = 8;
       
   163 #else
       
   164         if (MP_USED(a) < 8) {
       
   165                 return mp_bsqrmod(a, meth->irr_arr, r);
       
   166         }
       
   167         if (MP_USED(r) < 15) {
       
   168                 MP_CHECKOK(s_mp_pad(r, 15));
       
   169         }
       
   170         MP_USED(r) = 15;
       
   171 #endif
       
   172         u = MP_DIGITS(r);
       
   173 
       
   174 #ifdef ECL_THIRTY_TWO_BIT
       
   175         u[14] = gf2m_SQR0(v[7]);
       
   176         u[13] = gf2m_SQR1(v[6]);
       
   177         u[12] = gf2m_SQR0(v[6]);
       
   178         u[11] = gf2m_SQR1(v[5]);
       
   179         u[10] = gf2m_SQR0(v[5]);
       
   180         u[9] = gf2m_SQR1(v[4]);
       
   181         u[8] = gf2m_SQR0(v[4]);
       
   182 #endif
       
   183         u[7] = gf2m_SQR1(v[3]);
       
   184         u[6] = gf2m_SQR0(v[3]);
       
   185         u[5] = gf2m_SQR1(v[2]);
       
   186         u[4] = gf2m_SQR0(v[2]);
       
   187         u[3] = gf2m_SQR1(v[1]);
       
   188         u[2] = gf2m_SQR0(v[1]);
       
   189         u[1] = gf2m_SQR1(v[0]);
       
   190         u[0] = gf2m_SQR0(v[0]);
       
   191         return ec_GF2m_233_mod(r, r, meth);
       
   192 
       
   193   CLEANUP:
       
   194         return res;
       
   195 }
       
   196 
       
   197 /* Fast multiplication for polynomials over a 233-bit curve. Assumes
       
   198  * reduction polynomial with terms {233, 74, 0}. */
       
   199 mp_err
       
   200 ec_GF2m_233_mul(const mp_int *a, const mp_int *b, mp_int *r,
       
   201                                 const GFMethod *meth)
       
   202 {
       
   203         mp_err res = MP_OKAY;
       
   204         mp_digit a3 = 0, a2 = 0, a1 = 0, a0, b3 = 0, b2 = 0, b1 = 0, b0;
       
   205 
       
   206 #ifdef ECL_THIRTY_TWO_BIT
       
   207         mp_digit a7 = 0, a6 = 0, a5 = 0, a4 = 0, b7 = 0, b6 = 0, b5 = 0, b4 =
       
   208                 0;
       
   209         mp_digit rm[8];
       
   210 #endif
       
   211 
       
   212         if (a == b) {
       
   213                 return ec_GF2m_233_sqr(a, r, meth);
       
   214         } else {
       
   215                 switch (MP_USED(a)) {
       
   216 #ifdef ECL_THIRTY_TWO_BIT
       
   217                 case 8:
       
   218                         a7 = MP_DIGIT(a, 7);
       
   219                 case 7:
       
   220                         a6 = MP_DIGIT(a, 6);
       
   221                 case 6:
       
   222                         a5 = MP_DIGIT(a, 5);
       
   223                 case 5:
       
   224                         a4 = MP_DIGIT(a, 4);
       
   225 #endif
       
   226                 case 4:
       
   227                         a3 = MP_DIGIT(a, 3);
       
   228                 case 3:
       
   229                         a2 = MP_DIGIT(a, 2);
       
   230                 case 2:
       
   231                         a1 = MP_DIGIT(a, 1);
       
   232                 default:
       
   233                         a0 = MP_DIGIT(a, 0);
       
   234                 }
       
   235                 switch (MP_USED(b)) {
       
   236 #ifdef ECL_THIRTY_TWO_BIT
       
   237                 case 8:
       
   238                         b7 = MP_DIGIT(b, 7);
       
   239                 case 7:
       
   240                         b6 = MP_DIGIT(b, 6);
       
   241                 case 6:
       
   242                         b5 = MP_DIGIT(b, 5);
       
   243                 case 5:
       
   244                         b4 = MP_DIGIT(b, 4);
       
   245 #endif
       
   246                 case 4:
       
   247                         b3 = MP_DIGIT(b, 3);
       
   248                 case 3:
       
   249                         b2 = MP_DIGIT(b, 2);
       
   250                 case 2:
       
   251                         b1 = MP_DIGIT(b, 1);
       
   252                 default:
       
   253                         b0 = MP_DIGIT(b, 0);
       
   254                 }
       
   255 #ifdef ECL_SIXTY_FOUR_BIT
       
   256                 MP_CHECKOK(s_mp_pad(r, 8));
       
   257                 s_bmul_4x4(MP_DIGITS(r), a3, a2, a1, a0, b3, b2, b1, b0);
       
   258                 MP_USED(r) = 8;
       
   259                 s_mp_clamp(r);
       
   260 #else
       
   261                 MP_CHECKOK(s_mp_pad(r, 16));
       
   262                 s_bmul_4x4(MP_DIGITS(r) + 8, a7, a6, a5, a4, b7, b6, b5, b4);
       
   263                 s_bmul_4x4(MP_DIGITS(r), a3, a2, a1, a0, b3, b2, b1, b0);
       
   264                 s_bmul_4x4(rm, a7 ^ a3, a6 ^ a2, a5 ^ a1, a4 ^ a0, b7 ^ b3,
       
   265                                    b6 ^ b2, b5 ^ b1, b4 ^ b0);
       
   266                 rm[7] ^= MP_DIGIT(r, 7) ^ MP_DIGIT(r, 15);
       
   267                 rm[6] ^= MP_DIGIT(r, 6) ^ MP_DIGIT(r, 14);
       
   268                 rm[5] ^= MP_DIGIT(r, 5) ^ MP_DIGIT(r, 13);
       
   269                 rm[4] ^= MP_DIGIT(r, 4) ^ MP_DIGIT(r, 12);
       
   270                 rm[3] ^= MP_DIGIT(r, 3) ^ MP_DIGIT(r, 11);
       
   271                 rm[2] ^= MP_DIGIT(r, 2) ^ MP_DIGIT(r, 10);
       
   272                 rm[1] ^= MP_DIGIT(r, 1) ^ MP_DIGIT(r, 9);
       
   273                 rm[0] ^= MP_DIGIT(r, 0) ^ MP_DIGIT(r, 8);
       
   274                 MP_DIGIT(r, 11) ^= rm[7];
       
   275                 MP_DIGIT(r, 10) ^= rm[6];
       
   276                 MP_DIGIT(r, 9) ^= rm[5];
       
   277                 MP_DIGIT(r, 8) ^= rm[4];
       
   278                 MP_DIGIT(r, 7) ^= rm[3];
       
   279                 MP_DIGIT(r, 6) ^= rm[2];
       
   280                 MP_DIGIT(r, 5) ^= rm[1];
       
   281                 MP_DIGIT(r, 4) ^= rm[0];
       
   282                 MP_USED(r) = 16;
       
   283                 s_mp_clamp(r);
       
   284 #endif
       
   285                 return ec_GF2m_233_mod(r, r, meth);
       
   286         }
       
   287 
       
   288   CLEANUP:
       
   289         return res;
       
   290 }
       
   291 
       
   292 /* Wire in fast field arithmetic for 233-bit curves. */
       
   293 mp_err
       
   294 ec_group_set_gf2m233(ECGroup *group, ECCurveName name)
       
   295 {
       
   296         group->meth->field_mod = &ec_GF2m_233_mod;
       
   297         group->meth->field_mul = &ec_GF2m_233_mul;
       
   298         group->meth->field_sqr = &ec_GF2m_233_sqr;
       
   299         return MP_OKAY;
       
   300 }