1d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* Originally written by Bodo Moeller for the OpenSSL project. 2d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * ==================================================================== 3d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. 4d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 5d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Redistribution and use in source and binary forms, with or without 6d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * modification, are permitted provided that the following conditions 7d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * are met: 8d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 9d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 1. Redistributions of source code must retain the above copyright 10d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * notice, this list of conditions and the following disclaimer. 11d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 12d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 2. Redistributions in binary form must reproduce the above copyright 13d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * notice, this list of conditions and the following disclaimer in 14d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * the documentation and/or other materials provided with the 15d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * distribution. 16d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 17d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 3. All advertising materials mentioning features or use of this 18d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * software must display the following acknowledgment: 19d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * "This product includes software developed by the OpenSSL Project 20d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 21d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 22d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 23d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * endorse or promote products derived from this software without 24d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * prior written permission. For written permission, please contact 25d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * openssl-core@openssl.org. 26d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 27d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 5. Products derived from this software may not be called "OpenSSL" 28d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * nor may "OpenSSL" appear in their names without prior written 29d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * permission of the OpenSSL Project. 30d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 31d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 6. Redistributions of any form whatsoever must retain the following 32d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * acknowledgment: 33d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * "This product includes software developed by the OpenSSL Project 34d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 35d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 36d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 37d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 38d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 39d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 40d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 41d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 42d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 43d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 44d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 45d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 46d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 47d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * OF THE POSSIBILITY OF SUCH DAMAGE. 48d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * ==================================================================== 49d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 50d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * This product includes cryptographic software written by Eric Young 51d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * (eay@cryptsoft.com). This product includes software written by Tim 52d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Hudson (tjh@cryptsoft.com). 53d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 54d9e397b599b13d642138480a28c14db7a136bf0Adam Langley */ 55d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* ==================================================================== 56d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. 57d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 58d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Portions of the attached software ("Contribution") are developed by 59d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. 60d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 61d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * The Contribution is licensed pursuant to the OpenSSL open source 62d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * license provided above. 63d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 64d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * The elliptic curve binary polynomial software is originally written by 65d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems 66d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Laboratories. */ 67d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 68d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/ec.h> 69d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 70d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/bn.h> 71d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/err.h> 72d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 73d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include "internal.h" 74d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 75d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 76d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic size_t ec_GFp_simple_point2oct(const EC_GROUP *group, 77d9e397b599b13d642138480a28c14db7a136bf0Adam Langley const EC_POINT *point, 78d9e397b599b13d642138480a28c14db7a136bf0Adam Langley point_conversion_form_t form, 79d9e397b599b13d642138480a28c14db7a136bf0Adam Langley uint8_t *buf, size_t len, BN_CTX *ctx) { 80d9e397b599b13d642138480a28c14db7a136bf0Adam Langley size_t ret; 81d9e397b599b13d642138480a28c14db7a136bf0Adam Langley BN_CTX *new_ctx = NULL; 82d9e397b599b13d642138480a28c14db7a136bf0Adam Langley int used_ctx = 0; 83d9e397b599b13d642138480a28c14db7a136bf0Adam Langley BIGNUM *x, *y; 84d9e397b599b13d642138480a28c14db7a136bf0Adam Langley size_t field_len, i; 85d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 86d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if ((form != POINT_CONVERSION_COMPRESSED) && 87d9e397b599b13d642138480a28c14db7a136bf0Adam Langley (form != POINT_CONVERSION_UNCOMPRESSED)) { 88d9e397b599b13d642138480a28c14db7a136bf0Adam Langley OPENSSL_PUT_ERROR(EC, ec_GFp_simple_point2oct, EC_R_INVALID_FORM); 89d9e397b599b13d642138480a28c14db7a136bf0Adam Langley goto err; 90d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 91d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 92d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (EC_POINT_is_at_infinity(group, point)) { 93d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* encodes to a single 0 octet */ 94d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (buf != NULL) { 95d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (len < 1) { 96d9e397b599b13d642138480a28c14db7a136bf0Adam Langley OPENSSL_PUT_ERROR(EC, ec_GFp_simple_point2oct, EC_R_BUFFER_TOO_SMALL); 97d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 0; 98d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 99d9e397b599b13d642138480a28c14db7a136bf0Adam Langley buf[0] = 0; 100d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 101d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 1; 102d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 103d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 104d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 105d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* ret := required output buffer length */ 106d9e397b599b13d642138480a28c14db7a136bf0Adam Langley field_len = BN_num_bytes(&group->field); 107d9e397b599b13d642138480a28c14db7a136bf0Adam Langley ret = 108d9e397b599b13d642138480a28c14db7a136bf0Adam Langley (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2 * field_len; 109d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 110d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* if 'buf' is NULL, just return required length */ 111d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (buf != NULL) { 112d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (len < ret) { 113d9e397b599b13d642138480a28c14db7a136bf0Adam Langley OPENSSL_PUT_ERROR(EC, ec_GFp_simple_point2oct, EC_R_BUFFER_TOO_SMALL); 114d9e397b599b13d642138480a28c14db7a136bf0Adam Langley goto err; 115d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 116d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 117d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (ctx == NULL) { 118d9e397b599b13d642138480a28c14db7a136bf0Adam Langley ctx = new_ctx = BN_CTX_new(); 119d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (ctx == NULL) { 120d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 0; 121d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 122d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 123d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 124d9e397b599b13d642138480a28c14db7a136bf0Adam Langley BN_CTX_start(ctx); 125d9e397b599b13d642138480a28c14db7a136bf0Adam Langley used_ctx = 1; 126d9e397b599b13d642138480a28c14db7a136bf0Adam Langley x = BN_CTX_get(ctx); 127d9e397b599b13d642138480a28c14db7a136bf0Adam Langley y = BN_CTX_get(ctx); 128d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (y == NULL) { 129d9e397b599b13d642138480a28c14db7a136bf0Adam Langley goto err; 130d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 131d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 132d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (!EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx)) { 133d9e397b599b13d642138480a28c14db7a136bf0Adam Langley goto err; 134d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 135d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 136d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if ((form == POINT_CONVERSION_COMPRESSED) && 137d9e397b599b13d642138480a28c14db7a136bf0Adam Langley BN_is_odd(y)) { 138d9e397b599b13d642138480a28c14db7a136bf0Adam Langley buf[0] = form + 1; 139d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } else { 140d9e397b599b13d642138480a28c14db7a136bf0Adam Langley buf[0] = form; 141d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 142d9e397b599b13d642138480a28c14db7a136bf0Adam Langley i = 1; 143d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 144d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (!BN_bn2bin_padded(buf + i, field_len, x)) { 145d9e397b599b13d642138480a28c14db7a136bf0Adam Langley OPENSSL_PUT_ERROR(EC, ec_GFp_simple_point2oct, ERR_R_INTERNAL_ERROR); 146d9e397b599b13d642138480a28c14db7a136bf0Adam Langley goto err; 147d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 148d9e397b599b13d642138480a28c14db7a136bf0Adam Langley i += field_len; 149d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 150d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (form == POINT_CONVERSION_UNCOMPRESSED) { 151d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (!BN_bn2bin_padded(buf + i, field_len, y)) { 152d9e397b599b13d642138480a28c14db7a136bf0Adam Langley OPENSSL_PUT_ERROR(EC, ec_GFp_simple_point2oct, ERR_R_INTERNAL_ERROR); 153d9e397b599b13d642138480a28c14db7a136bf0Adam Langley goto err; 154d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 155d9e397b599b13d642138480a28c14db7a136bf0Adam Langley i += field_len; 156d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 157d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 158d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (i != ret) { 159d9e397b599b13d642138480a28c14db7a136bf0Adam Langley OPENSSL_PUT_ERROR(EC, ec_GFp_simple_point2oct, ERR_R_INTERNAL_ERROR); 160d9e397b599b13d642138480a28c14db7a136bf0Adam Langley goto err; 161d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 162d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 163d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 164d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (used_ctx) { 165d9e397b599b13d642138480a28c14db7a136bf0Adam Langley BN_CTX_end(ctx); 166d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 167e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley BN_CTX_free(new_ctx); 168d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return ret; 169d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 170d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyerr: 171d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (used_ctx) { 172d9e397b599b13d642138480a28c14db7a136bf0Adam Langley BN_CTX_end(ctx); 173d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 174e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley BN_CTX_free(new_ctx); 175d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 0; 176d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 177d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 178d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 179d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point, 180d9e397b599b13d642138480a28c14db7a136bf0Adam Langley const uint8_t *buf, size_t len, 181d9e397b599b13d642138480a28c14db7a136bf0Adam Langley BN_CTX *ctx) { 182d9e397b599b13d642138480a28c14db7a136bf0Adam Langley point_conversion_form_t form; 183d9e397b599b13d642138480a28c14db7a136bf0Adam Langley int y_bit; 184d9e397b599b13d642138480a28c14db7a136bf0Adam Langley BN_CTX *new_ctx = NULL; 185d9e397b599b13d642138480a28c14db7a136bf0Adam Langley BIGNUM *x, *y; 186d9e397b599b13d642138480a28c14db7a136bf0Adam Langley size_t field_len, enc_len; 187d9e397b599b13d642138480a28c14db7a136bf0Adam Langley int ret = 0; 188d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 189d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (len == 0) { 190d9e397b599b13d642138480a28c14db7a136bf0Adam Langley OPENSSL_PUT_ERROR(EC, ec_GFp_simple_oct2point, EC_R_BUFFER_TOO_SMALL); 191d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 0; 192d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 193d9e397b599b13d642138480a28c14db7a136bf0Adam Langley form = buf[0]; 194d9e397b599b13d642138480a28c14db7a136bf0Adam Langley y_bit = form & 1; 195d9e397b599b13d642138480a28c14db7a136bf0Adam Langley form = form & ~1U; 196d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if ((form != 0) && (form != POINT_CONVERSION_COMPRESSED) && 197d9e397b599b13d642138480a28c14db7a136bf0Adam Langley (form != POINT_CONVERSION_UNCOMPRESSED)) { 198d9e397b599b13d642138480a28c14db7a136bf0Adam Langley OPENSSL_PUT_ERROR(EC, ec_GFp_simple_oct2point, EC_R_INVALID_ENCODING); 199d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 0; 200d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 201d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if ((form == 0 || form == POINT_CONVERSION_UNCOMPRESSED) && y_bit) { 202d9e397b599b13d642138480a28c14db7a136bf0Adam Langley OPENSSL_PUT_ERROR(EC, ec_GFp_simple_oct2point, EC_R_INVALID_ENCODING); 203d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 0; 204d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 205d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 206d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (form == 0) { 207d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (len != 1) { 208d9e397b599b13d642138480a28c14db7a136bf0Adam Langley OPENSSL_PUT_ERROR(EC, ec_GFp_simple_oct2point, EC_R_INVALID_ENCODING); 209d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 0; 210d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 211d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 212d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return EC_POINT_set_to_infinity(group, point); 213d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 214d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 215d9e397b599b13d642138480a28c14db7a136bf0Adam Langley field_len = BN_num_bytes(&group->field); 216d9e397b599b13d642138480a28c14db7a136bf0Adam Langley enc_len = 217d9e397b599b13d642138480a28c14db7a136bf0Adam Langley (form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2 * field_len; 218d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 219d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (len != enc_len) { 220d9e397b599b13d642138480a28c14db7a136bf0Adam Langley OPENSSL_PUT_ERROR(EC, ec_GFp_simple_oct2point, EC_R_INVALID_ENCODING); 221d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 0; 222d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 223d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 224d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (ctx == NULL) { 225d9e397b599b13d642138480a28c14db7a136bf0Adam Langley ctx = new_ctx = BN_CTX_new(); 226e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley if (ctx == NULL) { 227d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 0; 228e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley } 229d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 230d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 231d9e397b599b13d642138480a28c14db7a136bf0Adam Langley BN_CTX_start(ctx); 232d9e397b599b13d642138480a28c14db7a136bf0Adam Langley x = BN_CTX_get(ctx); 233d9e397b599b13d642138480a28c14db7a136bf0Adam Langley y = BN_CTX_get(ctx); 234e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley if (y == NULL) { 235d9e397b599b13d642138480a28c14db7a136bf0Adam Langley goto err; 236e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley } 237d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 238e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley if (!BN_bin2bn(buf + 1, field_len, x)) { 239d9e397b599b13d642138480a28c14db7a136bf0Adam Langley goto err; 240e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley } 241d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (BN_ucmp(x, &group->field) >= 0) { 242d9e397b599b13d642138480a28c14db7a136bf0Adam Langley OPENSSL_PUT_ERROR(EC, ec_GFp_simple_oct2point, EC_R_INVALID_ENCODING); 243d9e397b599b13d642138480a28c14db7a136bf0Adam Langley goto err; 244d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 245d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 246d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (form == POINT_CONVERSION_COMPRESSED) { 247e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley if (!EC_POINT_set_compressed_coordinates_GFp(group, point, x, y_bit, ctx)) { 248d9e397b599b13d642138480a28c14db7a136bf0Adam Langley goto err; 249e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley } 250d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } else { 251e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley if (!BN_bin2bn(buf + 1 + field_len, field_len, y)) { 252d9e397b599b13d642138480a28c14db7a136bf0Adam Langley goto err; 253e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley } 254d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (BN_ucmp(y, &group->field) >= 0) { 255d9e397b599b13d642138480a28c14db7a136bf0Adam Langley OPENSSL_PUT_ERROR(EC, ec_GFp_simple_oct2point, EC_R_INVALID_ENCODING); 256d9e397b599b13d642138480a28c14db7a136bf0Adam Langley goto err; 257d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 258d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 259e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) { 260d9e397b599b13d642138480a28c14db7a136bf0Adam Langley goto err; 261e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley } 262d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 263d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 264e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley /* test required by X9.62 */ 265e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley if (!EC_POINT_is_on_curve(group, point, ctx)) { 266d9e397b599b13d642138480a28c14db7a136bf0Adam Langley OPENSSL_PUT_ERROR(EC, ec_GFp_simple_oct2point, EC_R_POINT_IS_NOT_ON_CURVE); 267d9e397b599b13d642138480a28c14db7a136bf0Adam Langley goto err; 268d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 269d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 270d9e397b599b13d642138480a28c14db7a136bf0Adam Langley ret = 1; 271d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 272d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyerr: 273d9e397b599b13d642138480a28c14db7a136bf0Adam Langley BN_CTX_end(ctx); 274e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley BN_CTX_free(new_ctx); 275d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return ret; 276d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 277d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 278d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *point, 279d9e397b599b13d642138480a28c14db7a136bf0Adam Langley const uint8_t *buf, size_t len, BN_CTX *ctx) { 280d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (group->meth->oct2point == 0 && 281d9e397b599b13d642138480a28c14db7a136bf0Adam Langley !(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) { 282d9e397b599b13d642138480a28c14db7a136bf0Adam Langley OPENSSL_PUT_ERROR(EC, EC_POINT_oct2point, 283d9e397b599b13d642138480a28c14db7a136bf0Adam Langley ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 284d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 0; 285d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 286d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (group->meth != point->meth) { 287d9e397b599b13d642138480a28c14db7a136bf0Adam Langley OPENSSL_PUT_ERROR(EC, EC_POINT_oct2point, EC_R_INCOMPATIBLE_OBJECTS); 288d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 0; 289d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 290d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) { 291d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return ec_GFp_simple_oct2point(group, point, buf, len, ctx); 292d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 293d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 294d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return group->meth->oct2point(group, point, buf, len, ctx); 295d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 296d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 297d9e397b599b13d642138480a28c14db7a136bf0Adam Langleysize_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *point, 298d9e397b599b13d642138480a28c14db7a136bf0Adam Langley point_conversion_form_t form, uint8_t *buf, 299d9e397b599b13d642138480a28c14db7a136bf0Adam Langley size_t len, BN_CTX *ctx) { 300d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (group->meth->point2oct == 0 && 301d9e397b599b13d642138480a28c14db7a136bf0Adam Langley !(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) { 302d9e397b599b13d642138480a28c14db7a136bf0Adam Langley OPENSSL_PUT_ERROR(EC, EC_POINT_point2oct, 303d9e397b599b13d642138480a28c14db7a136bf0Adam Langley ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 304d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 0; 305d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 306d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (group->meth != point->meth) { 307d9e397b599b13d642138480a28c14db7a136bf0Adam Langley OPENSSL_PUT_ERROR(EC, EC_POINT_point2oct, EC_R_INCOMPATIBLE_OBJECTS); 308d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 0; 309d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 310d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) { 311d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return ec_GFp_simple_point2oct(group, point, form, buf, len, ctx); 312d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 313d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 314d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return group->meth->point2oct(group, point, form, buf, len, ctx); 315d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 316d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 317d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group, 318d9e397b599b13d642138480a28c14db7a136bf0Adam Langley EC_POINT *point, const BIGNUM *x_, 319d9e397b599b13d642138480a28c14db7a136bf0Adam Langley int y_bit, BN_CTX *ctx) { 320d9e397b599b13d642138480a28c14db7a136bf0Adam Langley BN_CTX *new_ctx = NULL; 321d9e397b599b13d642138480a28c14db7a136bf0Adam Langley BIGNUM *tmp1, *tmp2, *x, *y; 322d9e397b599b13d642138480a28c14db7a136bf0Adam Langley int ret = 0; 323d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 324d9e397b599b13d642138480a28c14db7a136bf0Adam Langley ERR_clear_error(); 325d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 326d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (ctx == NULL) { 327d9e397b599b13d642138480a28c14db7a136bf0Adam Langley ctx = new_ctx = BN_CTX_new(); 328d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (ctx == NULL) { 329d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 0; 330d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 331d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 332d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 333d9e397b599b13d642138480a28c14db7a136bf0Adam Langley y_bit = (y_bit != 0); 334d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 335d9e397b599b13d642138480a28c14db7a136bf0Adam Langley BN_CTX_start(ctx); 336d9e397b599b13d642138480a28c14db7a136bf0Adam Langley tmp1 = BN_CTX_get(ctx); 337d9e397b599b13d642138480a28c14db7a136bf0Adam Langley tmp2 = BN_CTX_get(ctx); 338d9e397b599b13d642138480a28c14db7a136bf0Adam Langley x = BN_CTX_get(ctx); 339d9e397b599b13d642138480a28c14db7a136bf0Adam Langley y = BN_CTX_get(ctx); 340d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (y == NULL) { 341d9e397b599b13d642138480a28c14db7a136bf0Adam Langley goto err; 342d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 343d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 344d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* Recover y. We have a Weierstrass equation 345d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * y^2 = x^3 + a*x + b, 346d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * so y is one of the square roots of x^3 + a*x + b. */ 347d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 348d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* tmp1 := x^3 */ 349d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (!BN_nnmod(x, x_, &group->field, ctx)) { 350d9e397b599b13d642138480a28c14db7a136bf0Adam Langley goto err; 351d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 352d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 353d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (group->meth->field_decode == 0) { 354d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* field_{sqr,mul} work on standard representation */ 355d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (!group->meth->field_sqr(group, tmp2, x_, ctx) || 356d9e397b599b13d642138480a28c14db7a136bf0Adam Langley !group->meth->field_mul(group, tmp1, tmp2, x_, ctx)) { 357d9e397b599b13d642138480a28c14db7a136bf0Adam Langley goto err; 358d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 359d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } else { 360d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (!BN_mod_sqr(tmp2, x_, &group->field, ctx) || 361d9e397b599b13d642138480a28c14db7a136bf0Adam Langley !BN_mod_mul(tmp1, tmp2, x_, &group->field, ctx)) { 362d9e397b599b13d642138480a28c14db7a136bf0Adam Langley goto err; 363d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 364d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 365d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 366d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* tmp1 := tmp1 + a*x */ 367d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (group->a_is_minus3) { 368d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (!BN_mod_lshift1_quick(tmp2, x, &group->field) || 369d9e397b599b13d642138480a28c14db7a136bf0Adam Langley !BN_mod_add_quick(tmp2, tmp2, x, &group->field) || 370d9e397b599b13d642138480a28c14db7a136bf0Adam Langley !BN_mod_sub_quick(tmp1, tmp1, tmp2, &group->field)) { 371d9e397b599b13d642138480a28c14db7a136bf0Adam Langley goto err; 372d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 373d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } else { 374d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (group->meth->field_decode) { 375d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (!group->meth->field_decode(group, tmp2, &group->a, ctx) || 376d9e397b599b13d642138480a28c14db7a136bf0Adam Langley !BN_mod_mul(tmp2, tmp2, x, &group->field, ctx)) { 377d9e397b599b13d642138480a28c14db7a136bf0Adam Langley goto err; 378d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 379d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } else { 380d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* field_mul works on standard representation */ 381d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (!group->meth->field_mul(group, tmp2, &group->a, x, ctx)) { 382d9e397b599b13d642138480a28c14db7a136bf0Adam Langley goto err; 383d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 384d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 385d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 386d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (!BN_mod_add_quick(tmp1, tmp1, tmp2, &group->field)) { 387d9e397b599b13d642138480a28c14db7a136bf0Adam Langley goto err; 388d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 389d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 390d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 391d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* tmp1 := tmp1 + b */ 392d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (group->meth->field_decode) { 393d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (!group->meth->field_decode(group, tmp2, &group->b, ctx) || 394d9e397b599b13d642138480a28c14db7a136bf0Adam Langley !BN_mod_add_quick(tmp1, tmp1, tmp2, &group->field)) { 395d9e397b599b13d642138480a28c14db7a136bf0Adam Langley goto err; 396d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 397d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } else { 398d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (!BN_mod_add_quick(tmp1, tmp1, &group->b, &group->field)) { 399d9e397b599b13d642138480a28c14db7a136bf0Adam Langley goto err; 400d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 401d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 402d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 403d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (!BN_mod_sqrt(y, tmp1, &group->field, ctx)) { 404d9e397b599b13d642138480a28c14db7a136bf0Adam Langley unsigned long err = ERR_peek_last_error(); 405d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 406d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (ERR_GET_LIB(err) == ERR_LIB_BN && 407d9e397b599b13d642138480a28c14db7a136bf0Adam Langley ERR_GET_REASON(err) == BN_R_NOT_A_SQUARE) { 408d9e397b599b13d642138480a28c14db7a136bf0Adam Langley ERR_clear_error(); 409d9e397b599b13d642138480a28c14db7a136bf0Adam Langley OPENSSL_PUT_ERROR(EC, ec_GFp_simple_set_compressed_coordinates, EC_R_INVALID_COMPRESSED_POINT); 410d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } else { 411d9e397b599b13d642138480a28c14db7a136bf0Adam Langley OPENSSL_PUT_ERROR(EC, ec_GFp_simple_set_compressed_coordinates, ERR_R_BN_LIB); 412d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 413d9e397b599b13d642138480a28c14db7a136bf0Adam Langley goto err; 414d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 415d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 416d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (y_bit != BN_is_odd(y)) { 417d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (BN_is_zero(y)) { 418d9e397b599b13d642138480a28c14db7a136bf0Adam Langley int kron; 419d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 420d9e397b599b13d642138480a28c14db7a136bf0Adam Langley kron = BN_kronecker(x, &group->field, ctx); 421d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (kron == -2) { 422d9e397b599b13d642138480a28c14db7a136bf0Adam Langley goto err; 423d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 424d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 425d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (kron == 1) { 426d9e397b599b13d642138480a28c14db7a136bf0Adam Langley OPENSSL_PUT_ERROR(EC, ec_GFp_simple_set_compressed_coordinates, 427d9e397b599b13d642138480a28c14db7a136bf0Adam Langley EC_R_INVALID_COMPRESSION_BIT); 428d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } else { 429d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* BN_mod_sqrt() should have cought this error (not a square) */ 430d9e397b599b13d642138480a28c14db7a136bf0Adam Langley OPENSSL_PUT_ERROR(EC, ec_GFp_simple_set_compressed_coordinates, 431d9e397b599b13d642138480a28c14db7a136bf0Adam Langley EC_R_INVALID_COMPRESSED_POINT); 432d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 433d9e397b599b13d642138480a28c14db7a136bf0Adam Langley goto err; 434d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 435d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (!BN_usub(y, &group->field, y)) { 436d9e397b599b13d642138480a28c14db7a136bf0Adam Langley goto err; 437d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 438d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 439d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (y_bit != BN_is_odd(y)) { 440d9e397b599b13d642138480a28c14db7a136bf0Adam Langley OPENSSL_PUT_ERROR(EC, ec_GFp_simple_set_compressed_coordinates, 441d9e397b599b13d642138480a28c14db7a136bf0Adam Langley ERR_R_INTERNAL_ERROR); 442d9e397b599b13d642138480a28c14db7a136bf0Adam Langley goto err; 443d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 444d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 445e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) { 446d9e397b599b13d642138480a28c14db7a136bf0Adam Langley goto err; 447e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley } 448d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 449d9e397b599b13d642138480a28c14db7a136bf0Adam Langley ret = 1; 450d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 451d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyerr: 452d9e397b599b13d642138480a28c14db7a136bf0Adam Langley BN_CTX_end(ctx); 453e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley BN_CTX_free(new_ctx); 454d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return ret; 455d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 456d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 457d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group, 458d9e397b599b13d642138480a28c14db7a136bf0Adam Langley EC_POINT *point, const BIGNUM *x, 459d9e397b599b13d642138480a28c14db7a136bf0Adam Langley int y_bit, BN_CTX *ctx) { 460d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (group->meth->point_set_compressed_coordinates == 0 && 461d9e397b599b13d642138480a28c14db7a136bf0Adam Langley !(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) { 462d9e397b599b13d642138480a28c14db7a136bf0Adam Langley OPENSSL_PUT_ERROR(EC, EC_POINT_set_compressed_coordinates_GFp, 463d9e397b599b13d642138480a28c14db7a136bf0Adam Langley ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 464d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 0; 465d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 466d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (group->meth != point->meth) { 467d9e397b599b13d642138480a28c14db7a136bf0Adam Langley OPENSSL_PUT_ERROR(EC, EC_POINT_set_compressed_coordinates_GFp, 468d9e397b599b13d642138480a28c14db7a136bf0Adam Langley EC_R_INCOMPATIBLE_OBJECTS); 469d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 0; 470d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 471d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) { 472d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return ec_GFp_simple_set_compressed_coordinates(group, point, x, y_bit, 473d9e397b599b13d642138480a28c14db7a136bf0Adam Langley ctx); 474d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 475d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return group->meth->point_set_compressed_coordinates(group, point, x, y_bit, 476d9e397b599b13d642138480a28c14db7a136bf0Adam Langley ctx); 477d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 478