ec.c revision f4e427204234da139fd0585def4b4e22502e33f0
18d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi/* Originally written by Bodo Moeller for the OpenSSL project.
28d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * ====================================================================
38d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * Copyright (c) 1998-2005 The OpenSSL Project.  All rights reserved.
48d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi *
58d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * Redistribution and use in source and binary forms, with or without
68d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * modification, are permitted provided that the following conditions
78d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * are met:
88d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi *
98d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * 1. Redistributions of source code must retain the above copyright
108d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi *    notice, this list of conditions and the following disclaimer.
118d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi *
128d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * 2. Redistributions in binary form must reproduce the above copyright
138d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi *    notice, this list of conditions and the following disclaimer in
148d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi *    the documentation and/or other materials provided with the
158d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi *    distribution.
168d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi *
178d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * 3. All advertising materials mentioning features or use of this
188d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi *    software must display the following acknowledgment:
198d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi *    "This product includes software developed by the OpenSSL Project
208d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
218d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi *
228d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
238d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi *    endorse or promote products derived from this software without
248d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi *    prior written permission. For written permission, please contact
258d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi *    openssl-core@openssl.org.
268d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi *
278d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * 5. Products derived from this software may not be called "OpenSSL"
288d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi *    nor may "OpenSSL" appear in their names without prior written
298d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi *    permission of the OpenSSL Project.
308d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi *
318d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * 6. Redistributions of any form whatsoever must retain the following
328d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi *    acknowledgment:
338d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi *    "This product includes software developed by the OpenSSL Project
348d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
358d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi *
368d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
378d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
388d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
398d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
408d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
418d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
428d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
438d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
448d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
458d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
468d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
478d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * OF THE POSSIBILITY OF SUCH DAMAGE.
488d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * ====================================================================
498d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi *
508d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * This product includes cryptographic software written by Eric Young
518d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * (eay@cryptsoft.com).  This product includes software written by Tim
528d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * Hudson (tjh@cryptsoft.com).
538d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi *
548d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi */
558d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi/* ====================================================================
568d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
578d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi *
588d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * Portions of the attached software ("Contribution") are developed by
598d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
608d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi *
618d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * The Contribution is licensed pursuant to the OpenSSL open source
628d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * license provided above.
638d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi *
648d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * The elliptic curve binary polynomial software is originally written by
658d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems
668d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi * Laboratories. */
678d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
688d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi#include <openssl/ec.h>
698d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
708d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi#include <string.h>
718d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
728d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi#include <openssl/bn.h>
738d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi#include <openssl/err.h>
748d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi#include <openssl/mem.h>
758d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi#include <openssl/obj.h>
768d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
778d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi#include "internal.h"
788d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
798d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
808d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoistatic const struct curve_data P224 = {
818d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    "NIST P-224",
828d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    28,
838d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    1,
848d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    {/* p */
858d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
868d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi     0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
878d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi     0x00, 0x00, 0x00, 0x01,
888d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi     /* a */
898d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
908d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi     0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
918d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi     0xFF, 0xFF, 0xFF, 0xFE,
928d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi     /* b */
938d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi     0xB4, 0x05, 0x0A, 0x85, 0x0C, 0x04, 0xB3, 0xAB, 0xF5, 0x41, 0x32, 0x56,
948d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi     0x50, 0x44, 0xB0, 0xB7, 0xD7, 0xBF, 0xD8, 0xBA, 0x27, 0x0B, 0x39, 0x43,
958d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi     0x23, 0x55, 0xFF, 0xB4,
968d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi     /* x */
978d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi     0xB7, 0x0E, 0x0C, 0xBD, 0x6B, 0xB4, 0xBF, 0x7F, 0x32, 0x13, 0x90, 0xB9,
988d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi     0x4A, 0x03, 0xC1, 0xD3, 0x56, 0xC2, 0x11, 0x22, 0x34, 0x32, 0x80, 0xD6,
998d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi     0x11, 0x5C, 0x1D, 0x21,
1008d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi     /* y */
1018d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi     0xbd, 0x37, 0x63, 0x88, 0xb5, 0xf7, 0x23, 0xfb, 0x4c, 0x22, 0xdf, 0xe6,
1028d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi     0xcd, 0x43, 0x75, 0xa0, 0x5a, 0x07, 0x47, 0x64, 0x44, 0xd5, 0x81, 0x99,
1038d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi     0x85, 0x00, 0x7e, 0x34,
1048d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi     /* order */
1058d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
1068d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi     0xFF, 0xFF, 0x16, 0xA2, 0xE0, 0xB8, 0xF0, 0x3E, 0x13, 0xDD, 0x29, 0x45,
1078d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi     0x5C, 0x5C, 0x2A, 0x3D,
1088d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    }};
1098d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
1108d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoistatic const struct curve_data P256 = {
1118d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    "NIST P-256",
1128d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    32,
1138d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    1,
1148d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    {/* p */
1158d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi     0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
1168d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
1178d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
1188d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi     /* a */
1198d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi     0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
1208d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
1218d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
1228d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi     /* b */
1238d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi     0x5A, 0xC6, 0x35, 0xD8, 0xAA, 0x3A, 0x93, 0xE7, 0xB3, 0xEB, 0xBD, 0x55,
1248d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi     0x76, 0x98, 0x86, 0xBC, 0x65, 0x1D, 0x06, 0xB0, 0xCC, 0x53, 0xB0, 0xF6,
1258d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi     0x3B, 0xCE, 0x3C, 0x3E, 0x27, 0xD2, 0x60, 0x4B,
1268d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi     /* x */
1278d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi     0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47, 0xF8, 0xBC, 0xE6, 0xE5,
1288d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi     0x63, 0xA4, 0x40, 0xF2, 0x77, 0x03, 0x7D, 0x81, 0x2D, 0xEB, 0x33, 0xA0,
1298d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi     0xF4, 0xA1, 0x39, 0x45, 0xD8, 0x98, 0xC2, 0x96,
1308d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi     /* y */
1318d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi     0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7, 0xeb, 0x4a,
1328d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi     0x7c, 0x0f, 0x9e, 0x16, 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0xce,
1338d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi     0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5,
1348d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi     /* order */
1358d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi     0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
1368d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi     0xFF, 0xFF, 0xFF, 0xFF, 0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84,
1378d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi     0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51}};
1388d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi
1398d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoistatic const struct curve_data P384 = {
1408d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    "NIST P-384",
1418d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    48,
1428d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    1,
1438d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi    {/* p */
1448d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
1458d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
1468d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
1478d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
1488d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi     /* a */
1498d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
1508d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
1518d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
1528d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFC,
1538d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi     /* b */
1548d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi     0xB3, 0x31, 0x2F, 0xA7, 0xE2, 0x3E, 0xE7, 0xE4, 0x98, 0x8E, 0x05, 0x6B,
1558d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi     0xE3, 0xF8, 0x2D, 0x19, 0x18, 0x1D, 0x9C, 0x6E, 0xFE, 0x81, 0x41, 0x12,
1568d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi     0x03, 0x14, 0x08, 0x8F, 0x50, 0x13, 0x87, 0x5A, 0xC6, 0x56, 0x39, 0x8D,
1578d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi     0x8A, 0x2E, 0xD1, 0x9D, 0x2A, 0x85, 0xC8, 0xED, 0xD3, 0xEC, 0x2A, 0xEF,
1588d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi     /* x */
1598d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi     0xAA, 0x87, 0xCA, 0x22, 0xBE, 0x8B, 0x05, 0x37, 0x8E, 0xB1, 0xC7, 0x1E,
1608d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi     0xF3, 0x20, 0xAD, 0x74, 0x6E, 0x1D, 0x3B, 0x62, 0x8B, 0xA7, 0x9B, 0x98,
1618d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi     0x59, 0xF7, 0x41, 0xE0, 0x82, 0x54, 0x2A, 0x38, 0x55, 0x02, 0xF2, 0x5D,
1628d2b206a675ec20ea07100c35df34e65ee1e45e8Ruchi Kandoi     0xBF, 0x55, 0x29, 0x6C, 0x3A, 0x54, 0x5E, 0x38, 0x72, 0x76, 0x0A, 0xB7,
163     /* y */
164     0x36, 0x17, 0xde, 0x4a, 0x96, 0x26, 0x2c, 0x6f, 0x5d, 0x9e, 0x98, 0xbf,
165     0x92, 0x92, 0xdc, 0x29, 0xf8, 0xf4, 0x1d, 0xbd, 0x28, 0x9a, 0x14, 0x7c,
166     0xe9, 0xda, 0x31, 0x13, 0xb5, 0xf0, 0xb8, 0xc0, 0x0a, 0x60, 0xb1, 0xce,
167     0x1d, 0x7e, 0x81, 0x9d, 0x7a, 0x43, 0x1d, 0x7c, 0x90, 0xea, 0x0e, 0x5f,
168     /* order */
169     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
170     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
171     0xC7, 0x63, 0x4D, 0x81, 0xF4, 0x37, 0x2D, 0xDF, 0x58, 0x1A, 0x0D, 0xB2,
172     0x48, 0xB0, 0xA7, 0x7A, 0xEC, 0xEC, 0x19, 0x6A, 0xCC, 0xC5, 0x29, 0x73}};
173
174static const struct curve_data P521 = {
175    "NIST P-521",
176    66,
177    1,
178    {/* p */
179     0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
180     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
181     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
182     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
183     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
184     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
185     /* a */
186     0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
187     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
188     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
189     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
190     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
191     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
192     /* b */
193     0x00, 0x51, 0x95, 0x3E, 0xB9, 0x61, 0x8E, 0x1C, 0x9A, 0x1F, 0x92, 0x9A,
194     0x21, 0xA0, 0xB6, 0x85, 0x40, 0xEE, 0xA2, 0xDA, 0x72, 0x5B, 0x99, 0xB3,
195     0x15, 0xF3, 0xB8, 0xB4, 0x89, 0x91, 0x8E, 0xF1, 0x09, 0xE1, 0x56, 0x19,
196     0x39, 0x51, 0xEC, 0x7E, 0x93, 0x7B, 0x16, 0x52, 0xC0, 0xBD, 0x3B, 0xB1,
197     0xBF, 0x07, 0x35, 0x73, 0xDF, 0x88, 0x3D, 0x2C, 0x34, 0xF1, 0xEF, 0x45,
198     0x1F, 0xD4, 0x6B, 0x50, 0x3F, 0x00,
199     /* x */
200     0x00, 0xC6, 0x85, 0x8E, 0x06, 0xB7, 0x04, 0x04, 0xE9, 0xCD, 0x9E, 0x3E,
201     0xCB, 0x66, 0x23, 0x95, 0xB4, 0x42, 0x9C, 0x64, 0x81, 0x39, 0x05, 0x3F,
202     0xB5, 0x21, 0xF8, 0x28, 0xAF, 0x60, 0x6B, 0x4D, 0x3D, 0xBA, 0xA1, 0x4B,
203     0x5E, 0x77, 0xEF, 0xE7, 0x59, 0x28, 0xFE, 0x1D, 0xC1, 0x27, 0xA2, 0xFF,
204     0xA8, 0xDE, 0x33, 0x48, 0xB3, 0xC1, 0x85, 0x6A, 0x42, 0x9B, 0xF9, 0x7E,
205     0x7E, 0x31, 0xC2, 0xE5, 0xBD, 0x66,
206     /* y */
207     0x01, 0x18, 0x39, 0x29, 0x6a, 0x78, 0x9a, 0x3b, 0xc0, 0x04, 0x5c, 0x8a,
208     0x5f, 0xb4, 0x2c, 0x7d, 0x1b, 0xd9, 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b,
209     0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17, 0x27, 0x3e, 0x66, 0x2c, 0x97, 0xee,
210     0x72, 0x99, 0x5e, 0xf4, 0x26, 0x40, 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad,
211     0x07, 0x61, 0x35, 0x3c, 0x70, 0x86, 0xa2, 0x72, 0xc2, 0x40, 0x88, 0xbe,
212     0x94, 0x76, 0x9f, 0xd1, 0x66, 0x50,
213     /* order */
214     0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
215     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
216     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x51, 0x86,
217     0x87, 0x83, 0xBF, 0x2F, 0x96, 0x6B, 0x7F, 0xCC, 0x01, 0x48, 0xF7, 0x09,
218     0xA5, 0xD0, 0x3B, 0xB5, 0xC9, 0xB8, 0x89, 0x9C, 0x47, 0xAE, 0xBB, 0x6F,
219     0xB7, 0x1E, 0x91, 0x38, 0x64, 0x09}};
220
221const struct built_in_curve OPENSSL_built_in_curves[] = {
222    {NID_secp224r1, &P224, 0},
223    {
224        NID_X9_62_prime256v1, &P256,
225#if defined(OPENSSL_64_BIT) && !defined(OPENSSL_WINDOWS)
226        EC_GFp_nistp256_method,
227#else
228        0,
229#endif
230    },
231    {NID_secp384r1, &P384, 0},
232    {NID_secp521r1, &P521, 0},
233    {NID_undef, 0, 0},
234};
235
236EC_GROUP *ec_group_new(const EC_METHOD *meth) {
237  EC_GROUP *ret;
238
239  if (meth == NULL) {
240    OPENSSL_PUT_ERROR(EC, ec_group_new, EC_R_SLOT_FULL);
241    return NULL;
242  }
243
244  if (meth->group_init == 0) {
245    OPENSSL_PUT_ERROR(EC, ec_group_new, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
246    return NULL;
247  }
248
249  ret = OPENSSL_malloc(sizeof(EC_GROUP));
250  if (ret == NULL) {
251    OPENSSL_PUT_ERROR(EC, ec_group_new, ERR_R_MALLOC_FAILURE);
252    return NULL;
253  }
254  memset(ret, 0, sizeof(EC_GROUP));
255
256  ret->meth = meth;
257  BN_init(&ret->order);
258  BN_init(&ret->cofactor);
259
260  if (!meth->group_init(ret)) {
261    OPENSSL_free(ret);
262    return NULL;
263  }
264
265  return ret;
266}
267
268EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a,
269                                 const BIGNUM *b, BN_CTX *ctx) {
270  const EC_METHOD *meth = EC_GFp_mont_method();
271  EC_GROUP *ret;
272
273  ret = ec_group_new(meth);
274  if (ret == NULL) {
275    return NULL;
276  }
277
278  if (ret->meth->group_set_curve == 0) {
279    OPENSSL_PUT_ERROR(EC, EC_GROUP_new_curve_GFp,
280                      ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
281    return 0;
282  }
283  if (!ret->meth->group_set_curve(ret, p, a, b, ctx)) {
284    EC_GROUP_free(ret);
285    return NULL;
286  }
287  return ret;
288}
289
290int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
291                           const BIGNUM *order, const BIGNUM *cofactor) {
292  if (group->curve_name != NID_undef) {
293    /* |EC_GROUP_set_generator| should only be used with |EC_GROUP|s returned
294     * by |EC_GROUP_new_curve_GFp|. */
295    return 0;
296  }
297
298  if (group->generator == NULL) {
299    group->generator = EC_POINT_new(group);
300    if (group->generator == NULL) {
301      return 0;
302    }
303  }
304
305  if (!EC_POINT_copy(group->generator, generator)) {
306    return 0;
307  }
308
309  if (order != NULL) {
310    if (!BN_copy(&group->order, order)) {
311      return 0;
312    }
313  } else {
314    BN_zero(&group->order);
315  }
316
317  if (cofactor != NULL) {
318    if (!BN_copy(&group->cofactor, cofactor)) {
319      return 0;
320    }
321  } else {
322    BN_zero(&group->cofactor);
323  }
324
325  return 1;
326}
327
328static EC_GROUP *ec_group_new_from_data(const struct built_in_curve *curve) {
329  EC_GROUP *group = NULL;
330  EC_POINT *P = NULL;
331  BN_CTX *ctx = NULL;
332  BIGNUM *p = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL, *order = NULL;
333  int ok = 0;
334  unsigned param_len;
335  const EC_METHOD *meth;
336  const struct curve_data *data;
337  const uint8_t *params;
338
339  if ((ctx = BN_CTX_new()) == NULL) {
340    OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_MALLOC_FAILURE);
341    goto err;
342  }
343
344  data = curve->data;
345  param_len = data->param_len;
346  params = data->data;
347
348  if (!(p = BN_bin2bn(params + 0 * param_len, param_len, NULL)) ||
349      !(a = BN_bin2bn(params + 1 * param_len, param_len, NULL)) ||
350      !(b = BN_bin2bn(params + 2 * param_len, param_len, NULL))) {
351    OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_BN_LIB);
352    goto err;
353  }
354
355  if (curve->method != 0) {
356    meth = curve->method();
357    if (((group = ec_group_new(meth)) == NULL) ||
358        (!(group->meth->group_set_curve(group, p, a, b, ctx)))) {
359      OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_EC_LIB);
360      goto err;
361    }
362  } else {
363    if ((group = EC_GROUP_new_curve_GFp(p, a, b, ctx)) == NULL) {
364      OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_EC_LIB);
365      goto err;
366    }
367  }
368
369  if ((P = EC_POINT_new(group)) == NULL) {
370    OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_EC_LIB);
371    goto err;
372  }
373
374  if (!(x = BN_bin2bn(params + 3 * param_len, param_len, NULL)) ||
375      !(y = BN_bin2bn(params + 4 * param_len, param_len, NULL))) {
376    OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_BN_LIB);
377    goto err;
378  }
379
380  if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx)) {
381    OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_EC_LIB);
382    goto err;
383  }
384  if (!(order = BN_bin2bn(params + 5 * param_len, param_len, NULL)) ||
385      !BN_set_word(x, (BN_ULONG)data->cofactor)) {
386    OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_BN_LIB);
387    goto err;
388  }
389
390  group->generator = P;
391  P = NULL;
392  if (!BN_copy(&group->order, order) ||
393      !BN_set_word(&group->cofactor, (BN_ULONG)data->cofactor)) {
394    OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_BN_LIB);
395    goto err;
396  }
397
398  ok = 1;
399
400err:
401  if (!ok) {
402    EC_GROUP_free(group);
403    group = NULL;
404  }
405  EC_POINT_free(P);
406  BN_CTX_free(ctx);
407  BN_free(p);
408  BN_free(a);
409  BN_free(b);
410  BN_free(order);
411  BN_free(x);
412  BN_free(y);
413  return group;
414}
415
416EC_GROUP *EC_GROUP_new_by_curve_name(int nid) {
417  unsigned i;
418  const struct built_in_curve *curve;
419  EC_GROUP *ret = NULL;
420
421  for (i = 0; OPENSSL_built_in_curves[i].nid != NID_undef; i++) {
422    curve = &OPENSSL_built_in_curves[i];
423    if (curve->nid == nid) {
424      ret = ec_group_new_from_data(curve);
425      break;
426    }
427  }
428
429  if (ret == NULL) {
430    OPENSSL_PUT_ERROR(EC, EC_GROUP_new_by_curve_name, EC_R_UNKNOWN_GROUP);
431    return NULL;
432  }
433
434  ret->curve_name = nid;
435  return ret;
436}
437
438void EC_GROUP_free(EC_GROUP *group) {
439  if (!group) {
440    return;
441  }
442
443  if (group->meth->group_finish != 0) {
444    group->meth->group_finish(group);
445  }
446
447  ec_pre_comp_free(group->pre_comp);
448
449  EC_POINT_free(group->generator);
450  BN_free(&group->order);
451  BN_free(&group->cofactor);
452
453  OPENSSL_free(group);
454}
455
456int ec_group_copy(EC_GROUP *dest, const EC_GROUP *src) {
457  if (dest->meth->group_copy == 0) {
458    OPENSSL_PUT_ERROR(EC, EC_GROUP_copy, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
459    return 0;
460  }
461  if (dest->meth != src->meth) {
462    OPENSSL_PUT_ERROR(EC, EC_GROUP_copy, EC_R_INCOMPATIBLE_OBJECTS);
463    return 0;
464  }
465  if (dest == src) {
466    return 1;
467  }
468
469  ec_pre_comp_free(dest->pre_comp);
470  dest->pre_comp = ec_pre_comp_dup(src->pre_comp);
471
472  if (src->generator != NULL) {
473    if (dest->generator == NULL) {
474      dest->generator = EC_POINT_new(dest);
475      if (dest->generator == NULL) {
476        return 0;
477      }
478    }
479    if (!EC_POINT_copy(dest->generator, src->generator)) {
480      return 0;
481    }
482  } else {
483    /* src->generator == NULL */
484    if (dest->generator != NULL) {
485      EC_POINT_clear_free(dest->generator);
486      dest->generator = NULL;
487    }
488  }
489
490  if (!BN_copy(&dest->order, &src->order) ||
491      !BN_copy(&dest->cofactor, &src->cofactor)) {
492    return 0;
493  }
494
495  dest->curve_name = src->curve_name;
496
497  return dest->meth->group_copy(dest, src);
498}
499
500EC_GROUP *EC_GROUP_dup(const EC_GROUP *a) {
501  EC_GROUP *t = NULL;
502  int ok = 0;
503
504  if (a == NULL) {
505    return NULL;
506  }
507
508  t = ec_group_new(a->meth);
509  if (t == NULL) {
510    return NULL;
511  }
512  if (!ec_group_copy(t, a)) {
513    goto err;
514  }
515
516  ok = 1;
517
518err:
519  if (!ok) {
520    EC_GROUP_free(t);
521    return NULL;
522  } else {
523    return t;
524  }
525}
526
527int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ignored) {
528  return a->curve_name == NID_undef ||
529         b->curve_name == NID_undef ||
530         a->curve_name != b->curve_name;
531}
532
533const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group) {
534  return group->generator;
535}
536
537int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx) {
538  if (!BN_copy(order, &group->order)) {
539    return 0;
540  }
541
542  return !BN_is_zero(order);
543}
544
545int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor,
546                          BN_CTX *ctx) {
547  if (!BN_copy(cofactor, &group->cofactor)) {
548    return 0;
549  }
550
551  return !BN_is_zero(&group->cofactor);
552}
553
554int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *out_p, BIGNUM *out_a,
555                           BIGNUM *out_b, BN_CTX *ctx) {
556  if (group->meth->group_get_curve == 0) {
557    OPENSSL_PUT_ERROR(EC, EC_GROUP_get_curve_GFp,
558                      ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
559    return 0;
560  }
561  return group->meth->group_get_curve(group, out_p, out_a, out_b, ctx);
562}
563
564int EC_GROUP_get_curve_name(const EC_GROUP *group) { return group->curve_name; }
565
566int EC_GROUP_get_degree(const EC_GROUP *group) {
567  if (group->meth->group_get_degree == 0) {
568    OPENSSL_PUT_ERROR(EC, EC_GROUP_get_degree,
569                      ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
570    return 0;
571  }
572  return group->meth->group_get_degree(group);
573}
574
575int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx) {
576  if (group->meth->mul == 0) {
577    /* use default */
578    return ec_wNAF_precompute_mult(group, ctx);
579  }
580
581  if (group->meth->precompute_mult != 0) {
582    return group->meth->precompute_mult(group, ctx);
583  }
584
585  return 1; /* nothing to do, so report success */
586}
587
588int EC_GROUP_have_precompute_mult(const EC_GROUP *group) {
589  if (group->meth->mul == 0) {
590    /* use default */
591    return ec_wNAF_have_precompute_mult(group);
592  }
593
594  if (group->meth->have_precompute_mult != 0) {
595    return group->meth->have_precompute_mult(group);
596  }
597
598  return 0; /* cannot tell whether precomputation has been performed */
599}
600
601EC_POINT *EC_POINT_new(const EC_GROUP *group) {
602  EC_POINT *ret;
603
604  if (group == NULL) {
605    OPENSSL_PUT_ERROR(EC, EC_POINT_new, ERR_R_PASSED_NULL_PARAMETER);
606    return NULL;
607  }
608  if (group->meth->point_init == 0) {
609    OPENSSL_PUT_ERROR(EC, EC_POINT_new, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
610    return NULL;
611  }
612
613  ret = OPENSSL_malloc(sizeof *ret);
614  if (ret == NULL) {
615    OPENSSL_PUT_ERROR(EC, EC_POINT_new, ERR_R_MALLOC_FAILURE);
616    return NULL;
617  }
618
619  ret->meth = group->meth;
620
621  if (!ret->meth->point_init(ret)) {
622    OPENSSL_free(ret);
623    return NULL;
624  }
625
626  return ret;
627}
628
629void EC_POINT_free(EC_POINT *point) {
630  if (!point) {
631    return;
632  }
633
634  if (point->meth->point_finish != 0) {
635    point->meth->point_finish(point);
636  }
637  OPENSSL_free(point);
638}
639
640void EC_POINT_clear_free(EC_POINT *point) {
641  if (!point) {
642    return;
643  }
644
645  if (point->meth->point_clear_finish != 0) {
646    point->meth->point_clear_finish(point);
647  } else if (point->meth->point_finish != 0) {
648    point->meth->point_finish(point);
649  }
650  OPENSSL_cleanse(point, sizeof *point);
651  OPENSSL_free(point);
652}
653
654int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src) {
655  if (dest->meth->point_copy == 0) {
656    OPENSSL_PUT_ERROR(EC, EC_POINT_copy, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
657    return 0;
658  }
659  if (dest->meth != src->meth) {
660    OPENSSL_PUT_ERROR(EC, EC_POINT_copy, EC_R_INCOMPATIBLE_OBJECTS);
661    return 0;
662  }
663  if (dest == src) {
664    return 1;
665  }
666  return dest->meth->point_copy(dest, src);
667}
668
669EC_POINT *EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group) {
670  EC_POINT *t;
671  int r;
672
673  if (a == NULL) {
674    return NULL;
675  }
676
677  t = EC_POINT_new(group);
678  if (t == NULL) {
679    OPENSSL_PUT_ERROR(EC, EC_POINT_dup, ERR_R_MALLOC_FAILURE);
680    return NULL;
681  }
682  r = EC_POINT_copy(t, a);
683  if (!r) {
684    EC_POINT_free(t);
685    return NULL;
686  } else {
687    return t;
688  }
689}
690
691int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point) {
692  if (group->meth->point_set_to_infinity == 0) {
693    OPENSSL_PUT_ERROR(EC, EC_POINT_set_to_infinity,
694                      ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
695    return 0;
696  }
697  if (group->meth != point->meth) {
698    OPENSSL_PUT_ERROR(EC, EC_POINT_set_to_infinity, EC_R_INCOMPATIBLE_OBJECTS);
699    return 0;
700  }
701  return group->meth->point_set_to_infinity(group, point);
702}
703
704int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) {
705  if (group->meth->is_at_infinity == 0) {
706    OPENSSL_PUT_ERROR(EC, EC_POINT_is_at_infinity,
707                      ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
708    return 0;
709  }
710  if (group->meth != point->meth) {
711    OPENSSL_PUT_ERROR(EC, EC_POINT_is_at_infinity, EC_R_INCOMPATIBLE_OBJECTS);
712    return 0;
713  }
714  return group->meth->is_at_infinity(group, point);
715}
716
717int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
718                         BN_CTX *ctx) {
719  if (group->meth->is_on_curve == 0) {
720    OPENSSL_PUT_ERROR(EC, EC_POINT_is_on_curve,
721                      ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
722    return 0;
723  }
724  if (group->meth != point->meth) {
725    OPENSSL_PUT_ERROR(EC, EC_POINT_is_on_curve, EC_R_INCOMPATIBLE_OBJECTS);
726    return 0;
727  }
728  return group->meth->is_on_curve(group, point, ctx);
729}
730
731int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b,
732                 BN_CTX *ctx) {
733  if (group->meth->point_cmp == 0) {
734    OPENSSL_PUT_ERROR(EC, EC_POINT_cmp, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
735    return -1;
736  }
737  if ((group->meth != a->meth) || (a->meth != b->meth)) {
738    OPENSSL_PUT_ERROR(EC, EC_POINT_cmp, EC_R_INCOMPATIBLE_OBJECTS);
739    return -1;
740  }
741  return group->meth->point_cmp(group, a, b, ctx);
742}
743
744int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) {
745  if (group->meth->make_affine == 0) {
746    OPENSSL_PUT_ERROR(EC, EC_POINT_make_affine,
747                      ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
748    return 0;
749  }
750  if (group->meth != point->meth) {
751    OPENSSL_PUT_ERROR(EC, EC_POINT_make_affine, EC_R_INCOMPATIBLE_OBJECTS);
752    return 0;
753  }
754  return group->meth->make_affine(group, point, ctx);
755}
756
757int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[],
758                          BN_CTX *ctx) {
759  size_t i;
760
761  if (group->meth->points_make_affine == 0) {
762    OPENSSL_PUT_ERROR(EC, EC_POINTs_make_affine,
763                      ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
764    return 0;
765  }
766  for (i = 0; i < num; i++) {
767    if (group->meth != points[i]->meth) {
768      OPENSSL_PUT_ERROR(EC, EC_POINTs_make_affine, EC_R_INCOMPATIBLE_OBJECTS);
769      return 0;
770    }
771  }
772  return group->meth->points_make_affine(group, num, points, ctx);
773}
774
775int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group,
776                                        const EC_POINT *point, BIGNUM *x,
777                                        BIGNUM *y, BN_CTX *ctx) {
778  if (group->meth->point_get_affine_coordinates == 0) {
779    OPENSSL_PUT_ERROR(EC, EC_POINT_get_affine_coordinates_GFp,
780                      ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
781    return 0;
782  }
783  if (group->meth != point->meth) {
784    OPENSSL_PUT_ERROR(EC, EC_POINT_get_affine_coordinates_GFp,
785                      EC_R_INCOMPATIBLE_OBJECTS);
786    return 0;
787  }
788  return group->meth->point_get_affine_coordinates(group, point, x, y, ctx);
789}
790
791int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
792                                        const BIGNUM *x, const BIGNUM *y,
793                                        BN_CTX *ctx) {
794  if (group->meth->point_set_affine_coordinates == 0) {
795    OPENSSL_PUT_ERROR(EC, EC_POINT_set_affine_coordinates_GFp,
796                      ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
797    return 0;
798  }
799  if (group->meth != point->meth) {
800    OPENSSL_PUT_ERROR(EC, EC_POINT_set_affine_coordinates_GFp,
801                      EC_R_INCOMPATIBLE_OBJECTS);
802    return 0;
803  }
804  return group->meth->point_set_affine_coordinates(group, point, x, y, ctx);
805}
806
807int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
808                 const EC_POINT *b, BN_CTX *ctx) {
809  if (group->meth->add == 0) {
810    OPENSSL_PUT_ERROR(EC, EC_POINT_add, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
811    return 0;
812  }
813  if ((group->meth != r->meth) || (r->meth != a->meth) ||
814      (a->meth != b->meth)) {
815    OPENSSL_PUT_ERROR(EC, EC_POINT_add, EC_R_INCOMPATIBLE_OBJECTS);
816    return 0;
817  }
818  return group->meth->add(group, r, a, b, ctx);
819}
820
821
822int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
823                 BN_CTX *ctx) {
824  if (group->meth->dbl == 0) {
825    OPENSSL_PUT_ERROR(EC, EC_POINT_dbl, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
826    return 0;
827  }
828  if ((group->meth != r->meth) || (r->meth != a->meth)) {
829    OPENSSL_PUT_ERROR(EC, EC_POINT_dbl, EC_R_INCOMPATIBLE_OBJECTS);
830    return 0;
831  }
832  return group->meth->dbl(group, r, a, ctx);
833}
834
835
836int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx) {
837  if (group->meth->invert == 0) {
838    OPENSSL_PUT_ERROR(EC, EC_POINT_invert, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
839    return 0;
840  }
841  if (group->meth != a->meth) {
842    OPENSSL_PUT_ERROR(EC, EC_POINT_invert, EC_R_INCOMPATIBLE_OBJECTS);
843    return 0;
844  }
845  return group->meth->invert(group, a, ctx);
846}
847
848int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
849                 const EC_POINT *point, const BIGNUM *p_scalar, BN_CTX *ctx) {
850  /* just a convenient interface to EC_POINTs_mul() */
851
852  const EC_POINT *points[1];
853  const BIGNUM *scalars[1];
854
855  points[0] = point;
856  scalars[0] = p_scalar;
857
858  return EC_POINTs_mul(group, r, g_scalar, (point != NULL && p_scalar != NULL),
859                       points, scalars, ctx);
860}
861
862int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
863                  size_t num, const EC_POINT *points[], const BIGNUM *scalars[],
864                  BN_CTX *ctx) {
865  if (group->meth->mul == 0) {
866    /* use default. Warning, not constant-time. */
867    return ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx);
868  }
869
870  return group->meth->mul(group, r, scalar, num, points, scalars, ctx);
871}
872
873int ec_point_set_Jprojective_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
874                                             const BIGNUM *x, const BIGNUM *y,
875                                             const BIGNUM *z, BN_CTX *ctx) {
876  if (group->meth->point_set_Jprojective_coordinates_GFp == 0) {
877    OPENSSL_PUT_ERROR(EC, ec_point_set_Jprojective_coordinates_GFp,
878                      ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
879    return 0;
880  }
881  if (group->meth != point->meth) {
882    OPENSSL_PUT_ERROR(EC, ec_point_set_Jprojective_coordinates_GFp,
883                      EC_R_INCOMPATIBLE_OBJECTS);
884    return 0;
885  }
886  return group->meth->point_set_Jprojective_coordinates_GFp(group, point, x, y,
887                                                            z, ctx);
888}
889
890void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag) {}
891
892const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group) {
893  return NULL;
894}
895
896int EC_METHOD_get_field_type(const EC_METHOD *meth) {
897  return NID_X9_62_prime_field;
898}
899
900void EC_GROUP_set_point_conversion_form(EC_GROUP *group,
901                                        point_conversion_form_t form) {
902  if (form != POINT_CONVERSION_UNCOMPRESSED) {
903    abort();
904  }
905}
906