jdk/src/share/native/sun/security/ec/ecp_256.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 p256 = 2^256 - 2^224 + 2^192+ 2^96 - 1.  a can be r.
       
    68  * Uses algorithm 2.29 from Hankerson, Menezes, Vanstone. Guide to
       
    69  * Elliptic Curve Cryptography. */
       
    70 mp_err
       
    71 ec_GFp_nistp256_mod(const mp_int *a, mp_int *r, const GFMethod *meth)
       
    72 {
       
    73         mp_err res = MP_OKAY;
       
    74         mp_size a_used = MP_USED(a);
       
    75         int a_bits = mpl_significant_bits(a);
       
    76         mp_digit carry;
       
    77 
       
    78 #ifdef ECL_THIRTY_TWO_BIT
       
    79         mp_digit a8=0, a9=0, a10=0, a11=0, a12=0, a13=0, a14=0, a15=0;
       
    80         mp_digit r0, r1, r2, r3, r4, r5, r6, r7;
       
    81         int r8; /* must be a signed value ! */
       
    82 #else
       
    83         mp_digit a4=0, a5=0, a6=0, a7=0;
       
    84         mp_digit a4h, a4l, a5h, a5l, a6h, a6l, a7h, a7l;
       
    85         mp_digit r0, r1, r2, r3;
       
    86         int r4; /* must be a signed value ! */
       
    87 #endif
       
    88         /* for polynomials larger than twice the field size
       
    89          * use regular reduction */
       
    90         if (a_bits < 256) {
       
    91                 if (a == r) return MP_OKAY;
       
    92                 return mp_copy(a,r);
       
    93         }
       
    94         if (a_bits > 512)  {
       
    95                 MP_CHECKOK(mp_mod(a, &meth->irr, r));
       
    96         } else {
       
    97 
       
    98 #ifdef ECL_THIRTY_TWO_BIT
       
    99                 switch (a_used) {
       
   100                 case 16:
       
   101                         a15 = MP_DIGIT(a,15);
       
   102                 case 15:
       
   103                         a14 = MP_DIGIT(a,14);
       
   104                 case 14:
       
   105                         a13 = MP_DIGIT(a,13);
       
   106                 case 13:
       
   107                         a12 = MP_DIGIT(a,12);
       
   108                 case 12:
       
   109                         a11 = MP_DIGIT(a,11);
       
   110                 case 11:
       
   111                         a10 = MP_DIGIT(a,10);
       
   112                 case 10:
       
   113                         a9 = MP_DIGIT(a,9);
       
   114                 case 9:
       
   115                         a8 = MP_DIGIT(a,8);
       
   116                 }
       
   117 
       
   118                 r0 = MP_DIGIT(a,0);
       
   119                 r1 = MP_DIGIT(a,1);
       
   120                 r2 = MP_DIGIT(a,2);
       
   121                 r3 = MP_DIGIT(a,3);
       
   122                 r4 = MP_DIGIT(a,4);
       
   123                 r5 = MP_DIGIT(a,5);
       
   124                 r6 = MP_DIGIT(a,6);
       
   125                 r7 = MP_DIGIT(a,7);
       
   126 
       
   127                 /* sum 1 */
       
   128                 MP_ADD_CARRY(r3, a11, r3, 0,     carry);
       
   129                 MP_ADD_CARRY(r4, a12, r4, carry, carry);
       
   130                 MP_ADD_CARRY(r5, a13, r5, carry, carry);
       
   131                 MP_ADD_CARRY(r6, a14, r6, carry, carry);
       
   132                 MP_ADD_CARRY(r7, a15, r7, carry, carry);
       
   133                 r8 = carry;
       
   134                 MP_ADD_CARRY(r3, a11, r3, 0,     carry);
       
   135                 MP_ADD_CARRY(r4, a12, r4, carry, carry);
       
   136                 MP_ADD_CARRY(r5, a13, r5, carry, carry);
       
   137                 MP_ADD_CARRY(r6, a14, r6, carry, carry);
       
   138                 MP_ADD_CARRY(r7, a15, r7, carry, carry);
       
   139                 r8 += carry;
       
   140                 /* sum 2 */
       
   141                 MP_ADD_CARRY(r3, a12, r3, 0,     carry);
       
   142                 MP_ADD_CARRY(r4, a13, r4, carry, carry);
       
   143                 MP_ADD_CARRY(r5, a14, r5, carry, carry);
       
   144                 MP_ADD_CARRY(r6, a15, r6, carry, carry);
       
   145                 MP_ADD_CARRY(r7,   0, r7, carry, carry);
       
   146                 r8 += carry;
       
   147                 /* combine last bottom of sum 3 with second sum 2 */
       
   148                 MP_ADD_CARRY(r0, a8,  r0, 0,     carry);
       
   149                 MP_ADD_CARRY(r1, a9,  r1, carry, carry);
       
   150                 MP_ADD_CARRY(r2, a10, r2, carry, carry);
       
   151                 MP_ADD_CARRY(r3, a12, r3, carry, carry);
       
   152                 MP_ADD_CARRY(r4, a13, r4, carry, carry);
       
   153                 MP_ADD_CARRY(r5, a14, r5, carry, carry);
       
   154                 MP_ADD_CARRY(r6, a15, r6, carry, carry);
       
   155                 MP_ADD_CARRY(r7, a15, r7, carry, carry); /* from sum 3 */
       
   156                 r8 += carry;
       
   157                 /* sum 3 (rest of it)*/
       
   158                 MP_ADD_CARRY(r6, a14, r6, 0,     carry);
       
   159                 MP_ADD_CARRY(r7,   0, r7, carry, carry);
       
   160                 r8 += carry;
       
   161                 /* sum 4 (rest of it)*/
       
   162                 MP_ADD_CARRY(r0, a9,  r0, 0,     carry);
       
   163                 MP_ADD_CARRY(r1, a10, r1, carry, carry);
       
   164                 MP_ADD_CARRY(r2, a11, r2, carry, carry);
       
   165                 MP_ADD_CARRY(r3, a13, r3, carry, carry);
       
   166                 MP_ADD_CARRY(r4, a14, r4, carry, carry);
       
   167                 MP_ADD_CARRY(r5, a15, r5, carry, carry);
       
   168                 MP_ADD_CARRY(r6, a13, r6, carry, carry);
       
   169                 MP_ADD_CARRY(r7, a8,  r7, carry, carry);
       
   170                 r8 += carry;
       
   171                 /* diff 5 */
       
   172                 MP_SUB_BORROW(r0, a11, r0, 0,     carry);
       
   173                 MP_SUB_BORROW(r1, a12, r1, carry, carry);
       
   174                 MP_SUB_BORROW(r2, a13, r2, carry, carry);
       
   175                 MP_SUB_BORROW(r3,   0, r3, carry, carry);
       
   176                 MP_SUB_BORROW(r4,   0, r4, carry, carry);
       
   177                 MP_SUB_BORROW(r5,   0, r5, carry, carry);
       
   178                 MP_SUB_BORROW(r6, a8,  r6, carry, carry);
       
   179                 MP_SUB_BORROW(r7, a10, r7, carry, carry);
       
   180                 r8 -= carry;
       
   181                 /* diff 6 */
       
   182                 MP_SUB_BORROW(r0, a12, r0, 0,     carry);
       
   183                 MP_SUB_BORROW(r1, a13, r1, carry, carry);
       
   184                 MP_SUB_BORROW(r2, a14, r2, carry, carry);
       
   185                 MP_SUB_BORROW(r3, a15, r3, carry, carry);
       
   186                 MP_SUB_BORROW(r4,   0, r4, carry, carry);
       
   187                 MP_SUB_BORROW(r5,   0, r5, carry, carry);
       
   188                 MP_SUB_BORROW(r6, a9,  r6, carry, carry);
       
   189                 MP_SUB_BORROW(r7, a11, r7, carry, carry);
       
   190                 r8 -= carry;
       
   191                 /* diff 7 */
       
   192                 MP_SUB_BORROW(r0, a13, r0, 0,     carry);
       
   193                 MP_SUB_BORROW(r1, a14, r1, carry, carry);
       
   194                 MP_SUB_BORROW(r2, a15, r2, carry, carry);
       
   195                 MP_SUB_BORROW(r3, a8,  r3, carry, carry);
       
   196                 MP_SUB_BORROW(r4, a9,  r4, carry, carry);
       
   197                 MP_SUB_BORROW(r5, a10, r5, carry, carry);
       
   198                 MP_SUB_BORROW(r6, 0,   r6, carry, carry);
       
   199                 MP_SUB_BORROW(r7, a12, r7, carry, carry);
       
   200                 r8 -= carry;
       
   201                 /* diff 8 */
       
   202                 MP_SUB_BORROW(r0, a14, r0, 0,     carry);
       
   203                 MP_SUB_BORROW(r1, a15, r1, carry, carry);
       
   204                 MP_SUB_BORROW(r2, 0,   r2, carry, carry);
       
   205                 MP_SUB_BORROW(r3, a9,  r3, carry, carry);
       
   206                 MP_SUB_BORROW(r4, a10, r4, carry, carry);
       
   207                 MP_SUB_BORROW(r5, a11, r5, carry, carry);
       
   208                 MP_SUB_BORROW(r6, 0,   r6, carry, carry);
       
   209                 MP_SUB_BORROW(r7, a13, r7, carry, carry);
       
   210                 r8 -= carry;
       
   211 
       
   212                 /* reduce the overflows */
       
   213                 while (r8 > 0) {
       
   214                         mp_digit r8_d = r8;
       
   215                         MP_ADD_CARRY(r0, r8_d,         r0, 0,     carry);
       
   216                         MP_ADD_CARRY(r1, 0,            r1, carry, carry);
       
   217                         MP_ADD_CARRY(r2, 0,            r2, carry, carry);
       
   218                         MP_ADD_CARRY(r3, -r8_d,        r3, carry, carry);
       
   219                         MP_ADD_CARRY(r4, MP_DIGIT_MAX, r4, carry, carry);
       
   220                         MP_ADD_CARRY(r5, MP_DIGIT_MAX, r5, carry, carry);
       
   221                         MP_ADD_CARRY(r6, -(r8_d+1),    r6, carry, carry);
       
   222                         MP_ADD_CARRY(r7, (r8_d-1),     r7, carry, carry);
       
   223                         r8 = carry;
       
   224                 }
       
   225 
       
   226                 /* reduce the underflows */
       
   227                 while (r8 < 0) {
       
   228                         mp_digit r8_d = -r8;
       
   229                         MP_SUB_BORROW(r0, r8_d,         r0, 0,     carry);
       
   230                         MP_SUB_BORROW(r1, 0,            r1, carry, carry);
       
   231                         MP_SUB_BORROW(r2, 0,            r2, carry, carry);
       
   232                         MP_SUB_BORROW(r3, -r8_d,        r3, carry, carry);
       
   233                         MP_SUB_BORROW(r4, MP_DIGIT_MAX, r4, carry, carry);
       
   234                         MP_SUB_BORROW(r5, MP_DIGIT_MAX, r5, carry, carry);
       
   235                         MP_SUB_BORROW(r6, -(r8_d+1),    r6, carry, carry);
       
   236                         MP_SUB_BORROW(r7, (r8_d-1),     r7, carry, carry);
       
   237                         r8 = -carry;
       
   238                 }
       
   239                 if (a != r) {
       
   240                         MP_CHECKOK(s_mp_pad(r,8));
       
   241                 }
       
   242                 MP_SIGN(r) = MP_ZPOS;
       
   243                 MP_USED(r) = 8;
       
   244 
       
   245                 MP_DIGIT(r,7) = r7;
       
   246                 MP_DIGIT(r,6) = r6;
       
   247                 MP_DIGIT(r,5) = r5;
       
   248                 MP_DIGIT(r,4) = r4;
       
   249                 MP_DIGIT(r,3) = r3;
       
   250                 MP_DIGIT(r,2) = r2;
       
   251                 MP_DIGIT(r,1) = r1;
       
   252                 MP_DIGIT(r,0) = r0;
       
   253 
       
   254                 /* final reduction if necessary */
       
   255                 if ((r7 == MP_DIGIT_MAX) &&
       
   256                         ((r6 > 1) || ((r6 == 1) &&
       
   257                         (r5 || r4 || r3 ||
       
   258                                 ((r2 == MP_DIGIT_MAX) && (r1 == MP_DIGIT_MAX)
       
   259                                   && (r0 == MP_DIGIT_MAX)))))) {
       
   260                         MP_CHECKOK(mp_sub(r, &meth->irr, r));
       
   261                 }
       
   262 #ifdef notdef
       
   263 
       
   264 
       
   265                 /* smooth the negatives */
       
   266                 while (MP_SIGN(r) != MP_ZPOS) {
       
   267                         MP_CHECKOK(mp_add(r, &meth->irr, r));
       
   268                 }
       
   269                 while (MP_USED(r) > 8) {
       
   270                         MP_CHECKOK(mp_sub(r, &meth->irr, r));
       
   271                 }
       
   272 
       
   273                 /* final reduction if necessary */
       
   274                 if (MP_DIGIT(r,7) >= MP_DIGIT(&meth->irr,7)) {
       
   275                     if (mp_cmp(r,&meth->irr) != MP_LT) {
       
   276                         MP_CHECKOK(mp_sub(r, &meth->irr, r));
       
   277                     }
       
   278                 }
       
   279 #endif
       
   280                 s_mp_clamp(r);
       
   281 #else
       
   282                 switch (a_used) {
       
   283                 case 8:
       
   284                         a7 = MP_DIGIT(a,7);
       
   285                 case 7:
       
   286                         a6 = MP_DIGIT(a,6);
       
   287                 case 6:
       
   288                         a5 = MP_DIGIT(a,5);
       
   289                 case 5:
       
   290                         a4 = MP_DIGIT(a,4);
       
   291                 }
       
   292                 a7l = a7 << 32;
       
   293                 a7h = a7 >> 32;
       
   294                 a6l = a6 << 32;
       
   295                 a6h = a6 >> 32;
       
   296                 a5l = a5 << 32;
       
   297                 a5h = a5 >> 32;
       
   298                 a4l = a4 << 32;
       
   299                 a4h = a4 >> 32;
       
   300                 r3 = MP_DIGIT(a,3);
       
   301                 r2 = MP_DIGIT(a,2);
       
   302                 r1 = MP_DIGIT(a,1);
       
   303                 r0 = MP_DIGIT(a,0);
       
   304 
       
   305                 /* sum 1 */
       
   306                 MP_ADD_CARRY(r1, a5h << 32, r1, 0,     carry);
       
   307                 MP_ADD_CARRY(r2, a6,        r2, carry, carry);
       
   308                 MP_ADD_CARRY(r3, a7,        r3, carry, carry);
       
   309                 r4 = carry;
       
   310                 MP_ADD_CARRY(r1, a5h << 32, r1, 0,     carry);
       
   311                 MP_ADD_CARRY(r2, a6,        r2, carry, carry);
       
   312                 MP_ADD_CARRY(r3, a7,        r3, carry, carry);
       
   313                 r4 += carry;
       
   314                 /* sum 2 */
       
   315                 MP_ADD_CARRY(r1, a6l,       r1, 0,     carry);
       
   316                 MP_ADD_CARRY(r2, a6h | a7l, r2, carry, carry);
       
   317                 MP_ADD_CARRY(r3, a7h,       r3, carry, carry);
       
   318                 r4 += carry;
       
   319                 MP_ADD_CARRY(r1, a6l,       r1, 0,     carry);
       
   320                 MP_ADD_CARRY(r2, a6h | a7l, r2, carry, carry);
       
   321                 MP_ADD_CARRY(r3, a7h,       r3, carry, carry);
       
   322                 r4 += carry;
       
   323 
       
   324                 /* sum 3 */
       
   325                 MP_ADD_CARRY(r0, a4,        r0, 0,     carry);
       
   326                 MP_ADD_CARRY(r1, a5l >> 32, r1, carry, carry);
       
   327                 MP_ADD_CARRY(r2, 0,         r2, carry, carry);
       
   328                 MP_ADD_CARRY(r3, a7,        r3, carry, carry);
       
   329                 r4 += carry;
       
   330                 /* sum 4 */
       
   331                 MP_ADD_CARRY(r0, a4h | a5l,     r0, 0,     carry);
       
   332                 MP_ADD_CARRY(r1, a5h|(a6h<<32), r1, carry, carry);
       
   333                 MP_ADD_CARRY(r2, a7,            r2, carry, carry);
       
   334                 MP_ADD_CARRY(r3, a6h | a4l,     r3, carry, carry);
       
   335                 r4 += carry;
       
   336                 /* diff 5 */
       
   337                 MP_SUB_BORROW(r0, a5h | a6l,    r0, 0,     carry);
       
   338                 MP_SUB_BORROW(r1, a6h,          r1, carry, carry);
       
   339                 MP_SUB_BORROW(r2, 0,            r2, carry, carry);
       
   340                 MP_SUB_BORROW(r3, (a4l>>32)|a5l,r3, carry, carry);
       
   341                 r4 -= carry;
       
   342                 /* diff 6 */
       
   343                 MP_SUB_BORROW(r0, a6,           r0, 0,     carry);
       
   344                 MP_SUB_BORROW(r1, a7,           r1, carry, carry);
       
   345                 MP_SUB_BORROW(r2, 0,            r2, carry, carry);
       
   346                 MP_SUB_BORROW(r3, a4h|(a5h<<32),r3, carry, carry);
       
   347                 r4 -= carry;
       
   348                 /* diff 7 */
       
   349                 MP_SUB_BORROW(r0, a6h|a7l,      r0, 0,     carry);
       
   350                 MP_SUB_BORROW(r1, a7h|a4l,      r1, carry, carry);
       
   351                 MP_SUB_BORROW(r2, a4h|a5l,      r2, carry, carry);
       
   352                 MP_SUB_BORROW(r3, a6l,          r3, carry, carry);
       
   353                 r4 -= carry;
       
   354                 /* diff 8 */
       
   355                 MP_SUB_BORROW(r0, a7,           r0, 0,     carry);
       
   356                 MP_SUB_BORROW(r1, a4h<<32,      r1, carry, carry);
       
   357                 MP_SUB_BORROW(r2, a5,           r2, carry, carry);
       
   358                 MP_SUB_BORROW(r3, a6h<<32,      r3, carry, carry);
       
   359                 r4 -= carry;
       
   360 
       
   361                 /* reduce the overflows */
       
   362                 while (r4 > 0) {
       
   363                         mp_digit r4_long = r4;
       
   364                         mp_digit r4l = (r4_long << 32);
       
   365                         MP_ADD_CARRY(r0, r4_long,      r0, 0,     carry);
       
   366                         MP_ADD_CARRY(r1, -r4l,         r1, carry, carry);
       
   367                         MP_ADD_CARRY(r2, MP_DIGIT_MAX, r2, carry, carry);
       
   368                         MP_ADD_CARRY(r3, r4l-r4_long-1,r3, carry, carry);
       
   369                         r4 = carry;
       
   370                 }
       
   371 
       
   372                 /* reduce the underflows */
       
   373                 while (r4 < 0) {
       
   374                         mp_digit r4_long = -r4;
       
   375                         mp_digit r4l = (r4_long << 32);
       
   376                         MP_SUB_BORROW(r0, r4_long,      r0, 0,     carry);
       
   377                         MP_SUB_BORROW(r1, -r4l,         r1, carry, carry);
       
   378                         MP_SUB_BORROW(r2, MP_DIGIT_MAX, r2, carry, carry);
       
   379                         MP_SUB_BORROW(r3, r4l-r4_long-1,r3, carry, carry);
       
   380                         r4 = -carry;
       
   381                 }
       
   382 
       
   383                 if (a != r) {
       
   384                         MP_CHECKOK(s_mp_pad(r,4));
       
   385                 }
       
   386                 MP_SIGN(r) = MP_ZPOS;
       
   387                 MP_USED(r) = 4;
       
   388 
       
   389                 MP_DIGIT(r,3) = r3;
       
   390                 MP_DIGIT(r,2) = r2;
       
   391                 MP_DIGIT(r,1) = r1;
       
   392                 MP_DIGIT(r,0) = r0;
       
   393 
       
   394                 /* final reduction if necessary */
       
   395                 if ((r3 > 0xFFFFFFFF00000001ULL) ||
       
   396                         ((r3 == 0xFFFFFFFF00000001ULL) &&
       
   397                         (r2 || (r1 >> 32)||
       
   398                                (r1 == 0xFFFFFFFFULL && r0 == MP_DIGIT_MAX)))) {
       
   399                         /* very rare, just use mp_sub */
       
   400                         MP_CHECKOK(mp_sub(r, &meth->irr, r));
       
   401                 }
       
   402 
       
   403                 s_mp_clamp(r);
       
   404 #endif
       
   405         }
       
   406 
       
   407   CLEANUP:
       
   408         return res;
       
   409 }
       
   410 
       
   411 /* Compute the square of polynomial a, reduce modulo p256. Store the
       
   412  * result in r.  r could be a.  Uses optimized modular reduction for p256.
       
   413  */
       
   414 mp_err
       
   415 ec_GFp_nistp256_sqr(const mp_int *a, mp_int *r, const GFMethod *meth)
       
   416 {
       
   417         mp_err res = MP_OKAY;
       
   418 
       
   419         MP_CHECKOK(mp_sqr(a, r));
       
   420         MP_CHECKOK(ec_GFp_nistp256_mod(r, r, meth));
       
   421   CLEANUP:
       
   422         return res;
       
   423 }
       
   424 
       
   425 /* Compute the product of two polynomials a and b, reduce modulo p256.
       
   426  * Store the result in r.  r could be a or b; a could be b.  Uses
       
   427  * optimized modular reduction for p256. */
       
   428 mp_err
       
   429 ec_GFp_nistp256_mul(const mp_int *a, const mp_int *b, mp_int *r,
       
   430                                         const GFMethod *meth)
       
   431 {
       
   432         mp_err res = MP_OKAY;
       
   433 
       
   434         MP_CHECKOK(mp_mul(a, b, r));
       
   435         MP_CHECKOK(ec_GFp_nistp256_mod(r, r, meth));
       
   436   CLEANUP:
       
   437         return res;
       
   438 }
       
   439 
       
   440 /* Wire in fast field arithmetic and precomputation of base point for
       
   441  * named curves. */
       
   442 mp_err
       
   443 ec_group_set_gfp256(ECGroup *group, ECCurveName name)
       
   444 {
       
   445         if (name == ECCurve_NIST_P256) {
       
   446                 group->meth->field_mod = &ec_GFp_nistp256_mod;
       
   447                 group->meth->field_mul = &ec_GFp_nistp256_mul;
       
   448                 group->meth->field_sqr = &ec_GFp_nistp256_sqr;
       
   449         }
       
   450         return MP_OKAY;
       
   451 }