jdk/src/share/native/sun/security/ec/ecp_384.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  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       
    18  *
       
    19  * The contents of this file are subject to the Mozilla Public License Version
       
    20  * 1.1 (the "License"); you may not use this file except in compliance with
       
    21  * the License. You may obtain a copy of the License at
       
    22  * http://www.mozilla.org/MPL/
       
    23  *
       
    24  * Software distributed under the License is distributed on an "AS IS" basis,
       
    25  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
       
    26  * for the specific language governing rights and limitations under the
       
    27  * License.
       
    28  *
       
    29  * The Original Code is the elliptic curve math library for prime field curves.
       
    30  *
       
    31  * The Initial Developer of the Original Code is
       
    32  * Sun Microsystems, Inc.
       
    33  * Portions created by the Initial Developer are Copyright (C) 2003
       
    34  * the Initial Developer. All Rights Reserved.
       
    35  *
       
    36  * Contributor(s):
       
    37  *   Douglas Stebila <douglas@stebila.ca>
       
    38  *
       
    39  * Alternatively, the contents of this file may be used under the terms of
       
    40  * either the GNU General Public License Version 2 or later (the "GPL"), or
       
    41  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
       
    42  * in which case the provisions of the GPL or the LGPL are applicable instead
       
    43  * of those above. If you wish to allow use of your version of this file only
       
    44  * under the terms of either the GPL or the LGPL, and not to allow others to
       
    45  * use your version of this file under the terms of the MPL, indicate your
       
    46  * decision by deleting the provisions above and replace them with the notice
       
    47  * and other provisions required by the GPL or the LGPL. If you do not delete
       
    48  * the provisions above, a recipient may use your version of this file under
       
    49  * the terms of any one of the MPL, the GPL or the LGPL.
       
    50  *
       
    51  *********************************************************************** */
       
    52 /*
       
    53  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
       
    54  * Use is subject to license terms.
       
    55  */
       
    56 
       
    57 #pragma ident   "%Z%%M% %I%     %E% SMI"
       
    58 
       
    59 #include "ecp.h"
       
    60 #include "mpi.h"
       
    61 #include "mplogic.h"
       
    62 #include "mpi-priv.h"
       
    63 #ifndef _KERNEL
       
    64 #include <stdlib.h>
       
    65 #endif
       
    66 
       
    67 /* Fast modular reduction for p384 = 2^384 - 2^128 - 2^96 + 2^32 - 1.  a can be r.
       
    68  * Uses algorithm 2.30 from Hankerson, Menezes, Vanstone. Guide to
       
    69  * Elliptic Curve Cryptography. */
       
    70 mp_err
       
    71 ec_GFp_nistp384_mod(const mp_int *a, mp_int *r, const GFMethod *meth)
       
    72 {
       
    73         mp_err res = MP_OKAY;
       
    74         int a_bits = mpl_significant_bits(a);
       
    75         int i;
       
    76 
       
    77         /* m1, m2 are statically-allocated mp_int of exactly the size we need */
       
    78         mp_int m[10];
       
    79 
       
    80 #ifdef ECL_THIRTY_TWO_BIT
       
    81         mp_digit s[10][12];
       
    82         for (i = 0; i < 10; i++) {
       
    83                 MP_SIGN(&m[i]) = MP_ZPOS;
       
    84                 MP_ALLOC(&m[i]) = 12;
       
    85                 MP_USED(&m[i]) = 12;
       
    86                 MP_DIGITS(&m[i]) = s[i];
       
    87         }
       
    88 #else
       
    89         mp_digit s[10][6];
       
    90         for (i = 0; i < 10; i++) {
       
    91                 MP_SIGN(&m[i]) = MP_ZPOS;
       
    92                 MP_ALLOC(&m[i]) = 6;
       
    93                 MP_USED(&m[i]) = 6;
       
    94                 MP_DIGITS(&m[i]) = s[i];
       
    95         }
       
    96 #endif
       
    97 
       
    98 #ifdef ECL_THIRTY_TWO_BIT
       
    99         /* for polynomials larger than twice the field size or polynomials
       
   100          * not using all words, use regular reduction */
       
   101         if ((a_bits > 768) || (a_bits <= 736)) {
       
   102                 MP_CHECKOK(mp_mod(a, &meth->irr, r));
       
   103         } else {
       
   104                 for (i = 0; i < 12; i++) {
       
   105                         s[0][i] = MP_DIGIT(a, i);
       
   106                 }
       
   107                 s[1][0] = 0;
       
   108                 s[1][1] = 0;
       
   109                 s[1][2] = 0;
       
   110                 s[1][3] = 0;
       
   111                 s[1][4] = MP_DIGIT(a, 21);
       
   112                 s[1][5] = MP_DIGIT(a, 22);
       
   113                 s[1][6] = MP_DIGIT(a, 23);
       
   114                 s[1][7] = 0;
       
   115                 s[1][8] = 0;
       
   116                 s[1][9] = 0;
       
   117                 s[1][10] = 0;
       
   118                 s[1][11] = 0;
       
   119                 for (i = 0; i < 12; i++) {
       
   120                         s[2][i] = MP_DIGIT(a, i+12);
       
   121                 }
       
   122                 s[3][0] = MP_DIGIT(a, 21);
       
   123                 s[3][1] = MP_DIGIT(a, 22);
       
   124                 s[3][2] = MP_DIGIT(a, 23);
       
   125                 for (i = 3; i < 12; i++) {
       
   126                         s[3][i] = MP_DIGIT(a, i+9);
       
   127                 }
       
   128                 s[4][0] = 0;
       
   129                 s[4][1] = MP_DIGIT(a, 23);
       
   130                 s[4][2] = 0;
       
   131                 s[4][3] = MP_DIGIT(a, 20);
       
   132                 for (i = 4; i < 12; i++) {
       
   133                         s[4][i] = MP_DIGIT(a, i+8);
       
   134                 }
       
   135                 s[5][0] = 0;
       
   136                 s[5][1] = 0;
       
   137                 s[5][2] = 0;
       
   138                 s[5][3] = 0;
       
   139                 s[5][4] = MP_DIGIT(a, 20);
       
   140                 s[5][5] = MP_DIGIT(a, 21);
       
   141                 s[5][6] = MP_DIGIT(a, 22);
       
   142                 s[5][7] = MP_DIGIT(a, 23);
       
   143                 s[5][8] = 0;
       
   144                 s[5][9] = 0;
       
   145                 s[5][10] = 0;
       
   146                 s[5][11] = 0;
       
   147                 s[6][0] = MP_DIGIT(a, 20);
       
   148                 s[6][1] = 0;
       
   149                 s[6][2] = 0;
       
   150                 s[6][3] = MP_DIGIT(a, 21);
       
   151                 s[6][4] = MP_DIGIT(a, 22);
       
   152                 s[6][5] = MP_DIGIT(a, 23);
       
   153                 s[6][6] = 0;
       
   154                 s[6][7] = 0;
       
   155                 s[6][8] = 0;
       
   156                 s[6][9] = 0;
       
   157                 s[6][10] = 0;
       
   158                 s[6][11] = 0;
       
   159                 s[7][0] = MP_DIGIT(a, 23);
       
   160                 for (i = 1; i < 12; i++) {
       
   161                         s[7][i] = MP_DIGIT(a, i+11);
       
   162                 }
       
   163                 s[8][0] = 0;
       
   164                 s[8][1] = MP_DIGIT(a, 20);
       
   165                 s[8][2] = MP_DIGIT(a, 21);
       
   166                 s[8][3] = MP_DIGIT(a, 22);
       
   167                 s[8][4] = MP_DIGIT(a, 23);
       
   168                 s[8][5] = 0;
       
   169                 s[8][6] = 0;
       
   170                 s[8][7] = 0;
       
   171                 s[8][8] = 0;
       
   172                 s[8][9] = 0;
       
   173                 s[8][10] = 0;
       
   174                 s[8][11] = 0;
       
   175                 s[9][0] = 0;
       
   176                 s[9][1] = 0;
       
   177                 s[9][2] = 0;
       
   178                 s[9][3] = MP_DIGIT(a, 23);
       
   179                 s[9][4] = MP_DIGIT(a, 23);
       
   180                 s[9][5] = 0;
       
   181                 s[9][6] = 0;
       
   182                 s[9][7] = 0;
       
   183                 s[9][8] = 0;
       
   184                 s[9][9] = 0;
       
   185                 s[9][10] = 0;
       
   186                 s[9][11] = 0;
       
   187 
       
   188                 MP_CHECKOK(mp_add(&m[0], &m[1], r));
       
   189                 MP_CHECKOK(mp_add(r, &m[1], r));
       
   190                 MP_CHECKOK(mp_add(r, &m[2], r));
       
   191                 MP_CHECKOK(mp_add(r, &m[3], r));
       
   192                 MP_CHECKOK(mp_add(r, &m[4], r));
       
   193                 MP_CHECKOK(mp_add(r, &m[5], r));
       
   194                 MP_CHECKOK(mp_add(r, &m[6], r));
       
   195                 MP_CHECKOK(mp_sub(r, &m[7], r));
       
   196                 MP_CHECKOK(mp_sub(r, &m[8], r));
       
   197                 MP_CHECKOK(mp_submod(r, &m[9], &meth->irr, r));
       
   198                 s_mp_clamp(r);
       
   199         }
       
   200 #else
       
   201         /* for polynomials larger than twice the field size or polynomials
       
   202          * not using all words, use regular reduction */
       
   203         if ((a_bits > 768) || (a_bits <= 736)) {
       
   204                 MP_CHECKOK(mp_mod(a, &meth->irr, r));
       
   205         } else {
       
   206                 for (i = 0; i < 6; i++) {
       
   207                         s[0][i] = MP_DIGIT(a, i);
       
   208                 }
       
   209                 s[1][0] = 0;
       
   210                 s[1][1] = 0;
       
   211                 s[1][2] = (MP_DIGIT(a, 10) >> 32) | (MP_DIGIT(a, 11) << 32);
       
   212                 s[1][3] = MP_DIGIT(a, 11) >> 32;
       
   213                 s[1][4] = 0;
       
   214                 s[1][5] = 0;
       
   215                 for (i = 0; i < 6; i++) {
       
   216                         s[2][i] = MP_DIGIT(a, i+6);
       
   217                 }
       
   218                 s[3][0] = (MP_DIGIT(a, 10) >> 32) | (MP_DIGIT(a, 11) << 32);
       
   219                 s[3][1] = (MP_DIGIT(a, 11) >> 32) | (MP_DIGIT(a, 6) << 32);
       
   220                 for (i = 2; i < 6; i++) {
       
   221                         s[3][i] = (MP_DIGIT(a, i+4) >> 32) | (MP_DIGIT(a, i+5) << 32);
       
   222                 }
       
   223                 s[4][0] = (MP_DIGIT(a, 11) >> 32) << 32;
       
   224                 s[4][1] = MP_DIGIT(a, 10) << 32;
       
   225                 for (i = 2; i < 6; i++) {
       
   226                         s[4][i] = MP_DIGIT(a, i+4);
       
   227                 }
       
   228                 s[5][0] = 0;
       
   229                 s[5][1] = 0;
       
   230                 s[5][2] = MP_DIGIT(a, 10);
       
   231                 s[5][3] = MP_DIGIT(a, 11);
       
   232                 s[5][4] = 0;
       
   233                 s[5][5] = 0;
       
   234                 s[6][0] = (MP_DIGIT(a, 10) << 32) >> 32;
       
   235                 s[6][1] = (MP_DIGIT(a, 10) >> 32) << 32;
       
   236                 s[6][2] = MP_DIGIT(a, 11);
       
   237                 s[6][3] = 0;
       
   238                 s[6][4] = 0;
       
   239                 s[6][5] = 0;
       
   240                 s[7][0] = (MP_DIGIT(a, 11) >> 32) | (MP_DIGIT(a, 6) << 32);
       
   241                 for (i = 1; i < 6; i++) {
       
   242                         s[7][i] = (MP_DIGIT(a, i+5) >> 32) | (MP_DIGIT(a, i+6) << 32);
       
   243                 }
       
   244                 s[8][0] = MP_DIGIT(a, 10) << 32;
       
   245                 s[8][1] = (MP_DIGIT(a, 10) >> 32) | (MP_DIGIT(a, 11) << 32);
       
   246                 s[8][2] = MP_DIGIT(a, 11) >> 32;
       
   247                 s[8][3] = 0;
       
   248                 s[8][4] = 0;
       
   249                 s[8][5] = 0;
       
   250                 s[9][0] = 0;
       
   251                 s[9][1] = (MP_DIGIT(a, 11) >> 32) << 32;
       
   252                 s[9][2] = MP_DIGIT(a, 11) >> 32;
       
   253                 s[9][3] = 0;
       
   254                 s[9][4] = 0;
       
   255                 s[9][5] = 0;
       
   256 
       
   257                 MP_CHECKOK(mp_add(&m[0], &m[1], r));
       
   258                 MP_CHECKOK(mp_add(r, &m[1], r));
       
   259                 MP_CHECKOK(mp_add(r, &m[2], r));
       
   260                 MP_CHECKOK(mp_add(r, &m[3], r));
       
   261                 MP_CHECKOK(mp_add(r, &m[4], r));
       
   262                 MP_CHECKOK(mp_add(r, &m[5], r));
       
   263                 MP_CHECKOK(mp_add(r, &m[6], r));
       
   264                 MP_CHECKOK(mp_sub(r, &m[7], r));
       
   265                 MP_CHECKOK(mp_sub(r, &m[8], r));
       
   266                 MP_CHECKOK(mp_submod(r, &m[9], &meth->irr, r));
       
   267                 s_mp_clamp(r);
       
   268         }
       
   269 #endif
       
   270 
       
   271   CLEANUP:
       
   272         return res;
       
   273 }
       
   274 
       
   275 /* Compute the square of polynomial a, reduce modulo p384. Store the
       
   276  * result in r.  r could be a.  Uses optimized modular reduction for p384.
       
   277  */
       
   278 mp_err
       
   279 ec_GFp_nistp384_sqr(const mp_int *a, mp_int *r, const GFMethod *meth)
       
   280 {
       
   281         mp_err res = MP_OKAY;
       
   282 
       
   283         MP_CHECKOK(mp_sqr(a, r));
       
   284         MP_CHECKOK(ec_GFp_nistp384_mod(r, r, meth));
       
   285   CLEANUP:
       
   286         return res;
       
   287 }
       
   288 
       
   289 /* Compute the product of two polynomials a and b, reduce modulo p384.
       
   290  * Store the result in r.  r could be a or b; a could be b.  Uses
       
   291  * optimized modular reduction for p384. */
       
   292 mp_err
       
   293 ec_GFp_nistp384_mul(const mp_int *a, const mp_int *b, mp_int *r,
       
   294                                         const GFMethod *meth)
       
   295 {
       
   296         mp_err res = MP_OKAY;
       
   297 
       
   298         MP_CHECKOK(mp_mul(a, b, r));
       
   299         MP_CHECKOK(ec_GFp_nistp384_mod(r, r, meth));
       
   300   CLEANUP:
       
   301         return res;
       
   302 }
       
   303 
       
   304 /* Wire in fast field arithmetic and precomputation of base point for
       
   305  * named curves. */
       
   306 mp_err
       
   307 ec_group_set_gfp384(ECGroup *group, ECCurveName name)
       
   308 {
       
   309         if (name == ECCurve_NIST_P384) {
       
   310                 group->meth->field_mod = &ec_GFp_nistp384_mod;
       
   311                 group->meth->field_mul = &ec_GFp_nistp384_mul;
       
   312                 group->meth->field_sqr = &ec_GFp_nistp384_sqr;
       
   313         }
       
   314         return MP_OKAY;
       
   315 }