Home | History | Annotate | Download | only in ec
      1 /* Copyright (c) 2014, Intel Corporation.
      2  *
      3  * Permission to use, copy, modify, and/or distribute this software for any
      4  * purpose with or without fee is hereby granted, provided that the above
      5  * copyright notice and this permission notice appear in all copies.
      6  *
      7  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
      8  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
      9  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
     10  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     11  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
     12  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
     13  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
     14 
     15 /* Developers and authors:
     16  * Shay Gueron (1, 2), and Vlad Krasnov (1)
     17  * (1) Intel Corporation, Israel Development Center
     18  * (2) University of Haifa
     19  * Reference:
     20  * S.Gueron and V.Krasnov, "Fast Prime Field Elliptic Curve Cryptography with
     21  *                          256 Bit Primes" */
     22 
     23 #include <openssl/ec.h>
     24 
     25 #include <assert.h>
     26 #include <stdint.h>
     27 #include <string.h>
     28 
     29 #include <openssl/bn.h>
     30 #include <openssl/crypto.h>
     31 #include <openssl/err.h>
     32 
     33 #include "../bn/internal.h"
     34 #include "../ec/internal.h"
     35 #include "../internal.h"
     36 
     37 
     38 #if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && \
     39     !defined(OPENSSL_SMALL)
     40 
     41 
     42 #if defined(__GNUC__)
     43 #define ALIGN(x) __attribute((aligned(x)))
     44 #elif defined(_MSC_VER)
     45 #define ALIGN(x) __declspec(align(x))
     46 #else
     47 #define ALIGN(x)
     48 #endif
     49 
     50 #define ALIGNPTR(p, N) ((uint8_t *)p + N - (size_t)p % N)
     51 #define P256_LIMBS (256 / BN_BITS2)
     52 
     53 typedef struct {
     54   BN_ULONG X[P256_LIMBS];
     55   BN_ULONG Y[P256_LIMBS];
     56   BN_ULONG Z[P256_LIMBS];
     57 } P256_POINT;
     58 
     59 typedef struct {
     60   BN_ULONG X[P256_LIMBS];
     61   BN_ULONG Y[P256_LIMBS];
     62 } P256_POINT_AFFINE;
     63 
     64 typedef P256_POINT_AFFINE PRECOMP256_ROW[64];
     65 
     66 /* Functions implemented in assembly */
     67 
     68 /* Modular neg: res = -a mod P */
     69 void ecp_nistz256_neg(BN_ULONG res[P256_LIMBS], const BN_ULONG a[P256_LIMBS]);
     70 /* Montgomery mul: res = a*b*2^-256 mod P */
     71 void ecp_nistz256_mul_mont(BN_ULONG res[P256_LIMBS],
     72                            const BN_ULONG a[P256_LIMBS],
     73                            const BN_ULONG b[P256_LIMBS]);
     74 /* Montgomery sqr: res = a*a*2^-256 mod P */
     75 void ecp_nistz256_sqr_mont(BN_ULONG res[P256_LIMBS],
     76                            const BN_ULONG a[P256_LIMBS]);
     77 /* Convert a number from Montgomery domain, by multiplying with 1 */
     78 void ecp_nistz256_from_mont(BN_ULONG res[P256_LIMBS],
     79                             const BN_ULONG in[P256_LIMBS]);
     80 /* Functions that perform constant time access to the precomputed tables */
     81 void ecp_nistz256_select_w5(P256_POINT *val, const P256_POINT *in_t, int index);
     82 void ecp_nistz256_select_w7(P256_POINT_AFFINE *val,
     83                             const P256_POINT_AFFINE *in_t, int index);
     84 
     85 /* One converted into the Montgomery domain */
     86 static const BN_ULONG ONE[P256_LIMBS] = {
     87     TOBN(0x00000000, 0x00000001), TOBN(0xffffffff, 0x00000000),
     88     TOBN(0xffffffff, 0xffffffff), TOBN(0x00000000, 0xfffffffe),
     89 };
     90 
     91 /* Precomputed tables for the default generator */
     92 #include "p256-x86_64-table.h"
     93 
     94 /* Recode window to a signed digit, see ecp_nistputil.c for details */
     95 static unsigned booth_recode_w5(unsigned in) {
     96   unsigned s, d;
     97 
     98   s = ~((in >> 5) - 1);
     99   d = (1 << 6) - in - 1;
    100   d = (d & s) | (in & ~s);
    101   d = (d >> 1) + (d & 1);
    102 
    103   return (d << 1) + (s & 1);
    104 }
    105 
    106 static unsigned booth_recode_w7(unsigned in) {
    107   unsigned s, d;
    108 
    109   s = ~((in >> 7) - 1);
    110   d = (1 << 8) - in - 1;
    111   d = (d & s) | (in & ~s);
    112   d = (d >> 1) + (d & 1);
    113 
    114   return (d << 1) + (s & 1);
    115 }
    116 
    117 static void copy_conditional(BN_ULONG dst[P256_LIMBS],
    118                              const BN_ULONG src[P256_LIMBS], BN_ULONG move) {
    119   BN_ULONG mask1 = ((BN_ULONG)0) - move;
    120   BN_ULONG mask2 = ~mask1;
    121 
    122   dst[0] = (src[0] & mask1) ^ (dst[0] & mask2);
    123   dst[1] = (src[1] & mask1) ^ (dst[1] & mask2);
    124   dst[2] = (src[2] & mask1) ^ (dst[2] & mask2);
    125   dst[3] = (src[3] & mask1) ^ (dst[3] & mask2);
    126   if (P256_LIMBS == 8) {
    127     dst[4] = (src[4] & mask1) ^ (dst[4] & mask2);
    128     dst[5] = (src[5] & mask1) ^ (dst[5] & mask2);
    129     dst[6] = (src[6] & mask1) ^ (dst[6] & mask2);
    130     dst[7] = (src[7] & mask1) ^ (dst[7] & mask2);
    131   }
    132 }
    133 
    134 void ecp_nistz256_point_double(P256_POINT *r, const P256_POINT *a);
    135 void ecp_nistz256_point_add(P256_POINT *r, const P256_POINT *a,
    136                             const P256_POINT *b);
    137 void ecp_nistz256_point_add_affine(P256_POINT *r, const P256_POINT *a,
    138                                    const P256_POINT_AFFINE *b);
    139 
    140 /* r = in^-1 mod p */
    141 static void ecp_nistz256_mod_inverse(BN_ULONG r[P256_LIMBS],
    142                                      const BN_ULONG in[P256_LIMBS]) {
    143   /* The poly is ffffffff 00000001 00000000 00000000 00000000 ffffffff ffffffff
    144      ffffffff
    145      We use FLT and used poly-2 as exponent */
    146   BN_ULONG p2[P256_LIMBS];
    147   BN_ULONG p4[P256_LIMBS];
    148   BN_ULONG p8[P256_LIMBS];
    149   BN_ULONG p16[P256_LIMBS];
    150   BN_ULONG p32[P256_LIMBS];
    151   BN_ULONG res[P256_LIMBS];
    152   int i;
    153 
    154   ecp_nistz256_sqr_mont(res, in);
    155   ecp_nistz256_mul_mont(p2, res, in); /* 3*p */
    156 
    157   ecp_nistz256_sqr_mont(res, p2);
    158   ecp_nistz256_sqr_mont(res, res);
    159   ecp_nistz256_mul_mont(p4, res, p2); /* f*p */
    160 
    161   ecp_nistz256_sqr_mont(res, p4);
    162   ecp_nistz256_sqr_mont(res, res);
    163   ecp_nistz256_sqr_mont(res, res);
    164   ecp_nistz256_sqr_mont(res, res);
    165   ecp_nistz256_mul_mont(p8, res, p4); /* ff*p */
    166 
    167   ecp_nistz256_sqr_mont(res, p8);
    168   for (i = 0; i < 7; i++) {
    169     ecp_nistz256_sqr_mont(res, res);
    170   }
    171   ecp_nistz256_mul_mont(p16, res, p8); /* ffff*p */
    172 
    173   ecp_nistz256_sqr_mont(res, p16);
    174   for (i = 0; i < 15; i++) {
    175     ecp_nistz256_sqr_mont(res, res);
    176   }
    177   ecp_nistz256_mul_mont(p32, res, p16); /* ffffffff*p */
    178 
    179   ecp_nistz256_sqr_mont(res, p32);
    180   for (i = 0; i < 31; i++) {
    181     ecp_nistz256_sqr_mont(res, res);
    182   }
    183   ecp_nistz256_mul_mont(res, res, in);
    184 
    185   for (i = 0; i < 32 * 4; i++) {
    186     ecp_nistz256_sqr_mont(res, res);
    187   }
    188   ecp_nistz256_mul_mont(res, res, p32);
    189 
    190   for (i = 0; i < 32; i++) {
    191     ecp_nistz256_sqr_mont(res, res);
    192   }
    193   ecp_nistz256_mul_mont(res, res, p32);
    194 
    195   for (i = 0; i < 16; i++) {
    196     ecp_nistz256_sqr_mont(res, res);
    197   }
    198   ecp_nistz256_mul_mont(res, res, p16);
    199 
    200   for (i = 0; i < 8; i++) {
    201     ecp_nistz256_sqr_mont(res, res);
    202   }
    203   ecp_nistz256_mul_mont(res, res, p8);
    204 
    205   ecp_nistz256_sqr_mont(res, res);
    206   ecp_nistz256_sqr_mont(res, res);
    207   ecp_nistz256_sqr_mont(res, res);
    208   ecp_nistz256_sqr_mont(res, res);
    209   ecp_nistz256_mul_mont(res, res, p4);
    210 
    211   ecp_nistz256_sqr_mont(res, res);
    212   ecp_nistz256_sqr_mont(res, res);
    213   ecp_nistz256_mul_mont(res, res, p2);
    214 
    215   ecp_nistz256_sqr_mont(res, res);
    216   ecp_nistz256_sqr_mont(res, res);
    217   ecp_nistz256_mul_mont(res, res, in);
    218 
    219   memcpy(r, res, sizeof(res));
    220 }
    221 
    222 /* ecp_nistz256_bignum_to_field_elem copies the contents of |in| to |out| and
    223  * returns one if it fits. Otherwise it returns zero. */
    224 static int ecp_nistz256_bignum_to_field_elem(BN_ULONG out[P256_LIMBS],
    225                                              const BIGNUM *in) {
    226   if (in->top > P256_LIMBS) {
    227     return 0;
    228   }
    229 
    230   memset(out, 0, sizeof(BN_ULONG) * P256_LIMBS);
    231   memcpy(out, in->d, sizeof(BN_ULONG) * in->top);
    232   return 1;
    233 }
    234 
    235 /* r = p * p_scalar */
    236 static int ecp_nistz256_windowed_mul(const EC_GROUP *group, P256_POINT *r,
    237                                      const EC_POINT *p, const BIGNUM *p_scalar,
    238                                      BN_CTX *ctx) {
    239   assert(p != NULL);
    240   assert(p_scalar != NULL);
    241 
    242   static const unsigned kWindowSize = 5;
    243   static const unsigned kMask = (1 << (5 /* kWindowSize */ + 1)) - 1;
    244 
    245   /* A |P256_POINT| is (3 * 32) = 96 bytes, and the 64-byte alignment should
    246    * add no more than 63 bytes of overhead. Thus, |table| should require
    247    * ~1599 ((96 * 16) + 63) bytes of stack space. */
    248   ALIGN(64) P256_POINT table[16];
    249   uint8_t p_str[33];
    250 
    251 
    252   int ret = 0;
    253   BN_CTX *new_ctx = NULL;
    254   int ctx_started = 0;
    255 
    256   if (BN_num_bits(p_scalar) > 256 || BN_is_negative(p_scalar)) {
    257     if (ctx == NULL) {
    258       new_ctx = BN_CTX_new();
    259       if (new_ctx == NULL) {
    260         OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
    261         goto err;
    262       }
    263       ctx = new_ctx;
    264     }
    265     BN_CTX_start(ctx);
    266     ctx_started = 1;
    267     BIGNUM *mod = BN_CTX_get(ctx);
    268     if (mod == NULL) {
    269       OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
    270       goto err;
    271     }
    272     if (!BN_nnmod(mod, p_scalar, &group->order, ctx)) {
    273       OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
    274       goto err;
    275     }
    276     p_scalar = mod;
    277   }
    278 
    279   int j;
    280   for (j = 0; j < p_scalar->top * BN_BYTES; j += BN_BYTES) {
    281     BN_ULONG d = p_scalar->d[j / BN_BYTES];
    282 
    283     p_str[j + 0] = d & 0xff;
    284     p_str[j + 1] = (d >> 8) & 0xff;
    285     p_str[j + 2] = (d >> 16) & 0xff;
    286     p_str[j + 3] = (d >>= 24) & 0xff;
    287     if (BN_BYTES == 8) {
    288       d >>= 8;
    289       p_str[j + 4] = d & 0xff;
    290       p_str[j + 5] = (d >> 8) & 0xff;
    291       p_str[j + 6] = (d >> 16) & 0xff;
    292       p_str[j + 7] = (d >> 24) & 0xff;
    293     }
    294   }
    295 
    296   for (; j < 33; j++) {
    297     p_str[j] = 0;
    298   }
    299 
    300   /* table[0] is implicitly (0,0,0) (the point at infinity), therefore it is
    301    * not stored. All other values are actually stored with an offset of -1 in
    302    * table. */
    303   P256_POINT *row = table;
    304 
    305   if (!ecp_nistz256_bignum_to_field_elem(row[1 - 1].X, &p->X) ||
    306       !ecp_nistz256_bignum_to_field_elem(row[1 - 1].Y, &p->Y) ||
    307       !ecp_nistz256_bignum_to_field_elem(row[1 - 1].Z, &p->Z)) {
    308     OPENSSL_PUT_ERROR(EC, EC_R_COORDINATES_OUT_OF_RANGE);
    309     goto err;
    310   }
    311 
    312   ecp_nistz256_point_double(&row[2 - 1], &row[1 - 1]);
    313   ecp_nistz256_point_add(&row[3 - 1], &row[2 - 1], &row[1 - 1]);
    314   ecp_nistz256_point_double(&row[4 - 1], &row[2 - 1]);
    315   ecp_nistz256_point_double(&row[6 - 1], &row[3 - 1]);
    316   ecp_nistz256_point_double(&row[8 - 1], &row[4 - 1]);
    317   ecp_nistz256_point_double(&row[12 - 1], &row[6 - 1]);
    318   ecp_nistz256_point_add(&row[5 - 1], &row[4 - 1], &row[1 - 1]);
    319   ecp_nistz256_point_add(&row[7 - 1], &row[6 - 1], &row[1 - 1]);
    320   ecp_nistz256_point_add(&row[9 - 1], &row[8 - 1], &row[1 - 1]);
    321   ecp_nistz256_point_add(&row[13 - 1], &row[12 - 1], &row[1 - 1]);
    322   ecp_nistz256_point_double(&row[14 - 1], &row[7 - 1]);
    323   ecp_nistz256_point_double(&row[10 - 1], &row[5 - 1]);
    324   ecp_nistz256_point_add(&row[15 - 1], &row[14 - 1], &row[1 - 1]);
    325   ecp_nistz256_point_add(&row[11 - 1], &row[10 - 1], &row[1 - 1]);
    326   ecp_nistz256_point_add(&row[16 - 1], &row[15 - 1], &row[1 - 1]);
    327 
    328   BN_ULONG tmp[P256_LIMBS];
    329   ALIGN(32) P256_POINT h;
    330   unsigned index = 255;
    331   unsigned wvalue = p_str[(index - 1) / 8];
    332   wvalue = (wvalue >> ((index - 1) % 8)) & kMask;
    333 
    334   ecp_nistz256_select_w5(r, table, booth_recode_w5(wvalue) >> 1);
    335 
    336   while (index >= 5) {
    337     if (index != 255) {
    338       unsigned off = (index - 1) / 8;
    339 
    340       wvalue = p_str[off] | p_str[off + 1] << 8;
    341       wvalue = (wvalue >> ((index - 1) % 8)) & kMask;
    342 
    343       wvalue = booth_recode_w5(wvalue);
    344 
    345       ecp_nistz256_select_w5(&h, table, wvalue >> 1);
    346 
    347       ecp_nistz256_neg(tmp, h.Y);
    348       copy_conditional(h.Y, tmp, (wvalue & 1));
    349 
    350       ecp_nistz256_point_add(r, r, &h);
    351     }
    352 
    353     index -= kWindowSize;
    354 
    355     ecp_nistz256_point_double(r, r);
    356     ecp_nistz256_point_double(r, r);
    357     ecp_nistz256_point_double(r, r);
    358     ecp_nistz256_point_double(r, r);
    359     ecp_nistz256_point_double(r, r);
    360   }
    361 
    362   /* Final window */
    363   wvalue = p_str[0];
    364   wvalue = (wvalue << 1) & kMask;
    365 
    366   wvalue = booth_recode_w5(wvalue);
    367 
    368   ecp_nistz256_select_w5(&h, table, wvalue >> 1);
    369 
    370   ecp_nistz256_neg(tmp, h.Y);
    371   copy_conditional(h.Y, tmp, wvalue & 1);
    372 
    373   ecp_nistz256_point_add(r, r, &h);
    374 
    375   ret = 1;
    376 
    377 err:
    378   if (ctx_started) {
    379     BN_CTX_end(ctx);
    380   }
    381   BN_CTX_free(new_ctx);
    382   return ret;
    383 }
    384 
    385 static int ecp_nistz256_points_mul(
    386     const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
    387     const EC_POINT *p_, const BIGNUM *p_scalar, BN_CTX *ctx) {
    388   assert((p_ != NULL) == (p_scalar != NULL));
    389 
    390   static const unsigned kWindowSize = 7;
    391   static const unsigned kMask = (1 << (7 /* kWindowSize */ + 1)) - 1;
    392 
    393   ALIGN(32) union {
    394     P256_POINT p;
    395     P256_POINT_AFFINE a;
    396   } t, p;
    397 
    398   int ret = 0;
    399   BN_CTX *new_ctx = NULL;
    400   int ctx_started = 0;
    401 
    402   /* Need 256 bits for space for all coordinates. */
    403   if (bn_wexpand(&r->X, P256_LIMBS) == NULL ||
    404       bn_wexpand(&r->Y, P256_LIMBS) == NULL ||
    405       bn_wexpand(&r->Z, P256_LIMBS) == NULL) {
    406     OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
    407     goto err;
    408   }
    409   r->X.top = P256_LIMBS;
    410   r->Y.top = P256_LIMBS;
    411   r->Z.top = P256_LIMBS;
    412 
    413   if (g_scalar != NULL) {
    414     if (BN_num_bits(g_scalar) > 256 || BN_is_negative(g_scalar)) {
    415       if (ctx == NULL) {
    416         new_ctx = BN_CTX_new();
    417         if (new_ctx == NULL) {
    418           goto err;
    419         }
    420         ctx = new_ctx;
    421       }
    422       BN_CTX_start(ctx);
    423       ctx_started = 1;
    424       BIGNUM *tmp_scalar = BN_CTX_get(ctx);
    425       if (tmp_scalar == NULL) {
    426         goto err;
    427       }
    428 
    429       if (!BN_nnmod(tmp_scalar, g_scalar, &group->order, ctx)) {
    430         OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
    431         goto err;
    432       }
    433       g_scalar = tmp_scalar;
    434     }
    435 
    436     uint8_t p_str[33] = {0};
    437     int i;
    438     for (i = 0; i < g_scalar->top * BN_BYTES; i += BN_BYTES) {
    439       BN_ULONG d = g_scalar->d[i / BN_BYTES];
    440 
    441       p_str[i + 0] = d & 0xff;
    442       p_str[i + 1] = (d >> 8) & 0xff;
    443       p_str[i + 2] = (d >> 16) & 0xff;
    444       p_str[i + 3] = (d >>= 24) & 0xff;
    445       if (BN_BYTES == 8) {
    446         d >>= 8;
    447         p_str[i + 4] = d & 0xff;
    448         p_str[i + 5] = (d >> 8) & 0xff;
    449         p_str[i + 6] = (d >> 16) & 0xff;
    450         p_str[i + 7] = (d >> 24) & 0xff;
    451       }
    452     }
    453 
    454     for (; i < (int) sizeof(p_str); i++) {
    455       p_str[i] = 0;
    456     }
    457 
    458     /* First window */
    459     unsigned wvalue = (p_str[0] << 1) & kMask;
    460     unsigned index = kWindowSize;
    461 
    462     wvalue = booth_recode_w7(wvalue);
    463 
    464     const PRECOMP256_ROW *const precomputed_table =
    465         (const PRECOMP256_ROW *)ecp_nistz256_precomputed;
    466     ecp_nistz256_select_w7(&p.a, precomputed_table[0], wvalue >> 1);
    467 
    468     ecp_nistz256_neg(p.p.Z, p.p.Y);
    469     copy_conditional(p.p.Y, p.p.Z, wvalue & 1);
    470 
    471     memcpy(p.p.Z, ONE, sizeof(ONE));
    472 
    473     for (i = 1; i < 37; i++) {
    474       unsigned off = (index - 1) / 8;
    475       wvalue = p_str[off] | p_str[off + 1] << 8;
    476       wvalue = (wvalue >> ((index - 1) % 8)) & kMask;
    477       index += kWindowSize;
    478 
    479       wvalue = booth_recode_w7(wvalue);
    480 
    481       ecp_nistz256_select_w7(&t.a, precomputed_table[i], wvalue >> 1);
    482 
    483       ecp_nistz256_neg(t.p.Z, t.a.Y);
    484       copy_conditional(t.a.Y, t.p.Z, wvalue & 1);
    485 
    486       ecp_nistz256_point_add_affine(&p.p, &p.p, &t.a);
    487     }
    488   }
    489 
    490   const int p_is_infinity = g_scalar == NULL;
    491   if (p_scalar != NULL) {
    492     P256_POINT *out = &t.p;
    493     if (p_is_infinity) {
    494       out = &p.p;
    495     }
    496 
    497     if (!ecp_nistz256_windowed_mul(group, out, p_, p_scalar, ctx)) {
    498       goto err;
    499     }
    500 
    501     if (!p_is_infinity) {
    502       ecp_nistz256_point_add(&p.p, &p.p, out);
    503     }
    504   }
    505 
    506   memcpy(r->X.d, p.p.X, sizeof(p.p.X));
    507   memcpy(r->Y.d, p.p.Y, sizeof(p.p.Y));
    508   memcpy(r->Z.d, p.p.Z, sizeof(p.p.Z));
    509 
    510   /* Not constant-time, but we're only operating on the public output. */
    511   bn_correct_top(&r->X);
    512   bn_correct_top(&r->Y);
    513   bn_correct_top(&r->Z);
    514   r->Z_is_one = BN_is_one(&r->Z);
    515 
    516   ret = 1;
    517 
    518 err:
    519   if (ctx_started) {
    520     BN_CTX_end(ctx);
    521   }
    522   BN_CTX_free(new_ctx);
    523   return ret;
    524 }
    525 
    526 static int ecp_nistz256_get_affine(const EC_GROUP *group, const EC_POINT *point,
    527                                    BIGNUM *x, BIGNUM *y, BN_CTX *ctx) {
    528   BN_ULONG z_inv2[P256_LIMBS];
    529   BN_ULONG z_inv3[P256_LIMBS];
    530   BN_ULONG x_aff[P256_LIMBS];
    531   BN_ULONG y_aff[P256_LIMBS];
    532   BN_ULONG point_x[P256_LIMBS], point_y[P256_LIMBS], point_z[P256_LIMBS];
    533 
    534   if (EC_POINT_is_at_infinity(group, point)) {
    535     OPENSSL_PUT_ERROR(EC, EC_R_POINT_AT_INFINITY);
    536     return 0;
    537   }
    538 
    539   if (!ecp_nistz256_bignum_to_field_elem(point_x, &point->X) ||
    540       !ecp_nistz256_bignum_to_field_elem(point_y, &point->Y) ||
    541       !ecp_nistz256_bignum_to_field_elem(point_z, &point->Z)) {
    542     OPENSSL_PUT_ERROR(EC, EC_R_COORDINATES_OUT_OF_RANGE);
    543     return 0;
    544   }
    545 
    546   ecp_nistz256_mod_inverse(z_inv3, point_z);
    547   ecp_nistz256_sqr_mont(z_inv2, z_inv3);
    548   ecp_nistz256_mul_mont(x_aff, z_inv2, point_x);
    549 
    550   if (x != NULL) {
    551     if (bn_wexpand(x, P256_LIMBS) == NULL) {
    552       OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
    553       return 0;
    554     }
    555     x->top = P256_LIMBS;
    556     ecp_nistz256_from_mont(x->d, x_aff);
    557     bn_correct_top(x);
    558   }
    559 
    560   if (y != NULL) {
    561     ecp_nistz256_mul_mont(z_inv3, z_inv3, z_inv2);
    562     ecp_nistz256_mul_mont(y_aff, z_inv3, point_y);
    563     if (bn_wexpand(y, P256_LIMBS) == NULL) {
    564       OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
    565       return 0;
    566     }
    567     y->top = P256_LIMBS;
    568     ecp_nistz256_from_mont(y->d, y_aff);
    569     bn_correct_top(y);
    570   }
    571 
    572   return 1;
    573 }
    574 
    575 const EC_METHOD *EC_GFp_nistz256_method(void) {
    576   static const EC_METHOD ret = {
    577       ec_GFp_mont_group_init,
    578       ec_GFp_mont_group_finish,
    579       ec_GFp_mont_group_clear_finish,
    580       ec_GFp_mont_group_copy,
    581       ec_GFp_mont_group_set_curve,
    582       ecp_nistz256_get_affine,
    583       ecp_nistz256_points_mul,
    584       0 /* check_pub_key_order */,
    585       ec_GFp_mont_field_mul,
    586       ec_GFp_mont_field_sqr,
    587       ec_GFp_mont_field_encode,
    588       ec_GFp_mont_field_decode,
    589       ec_GFp_mont_field_set_to_one,
    590   };
    591 
    592   return &ret;
    593 }
    594 
    595 #endif /* !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && \
    596           !defined(OPENSSL_SMALL) */
    597