1656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* crypto/ec/ec2_smpl.c */ 2656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* ==================================================================== 3656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. 4656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 5656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * The Elliptic Curve Public-Key Crypto Library (ECC Code) included 6656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * herein is developed by SUN MICROSYSTEMS, INC., and is contributed 7656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * to the OpenSSL project. 8656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 9656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * The ECC Code is licensed pursuant to the OpenSSL open source 10656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * license provided below. 11656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 12656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * The software is originally written by Sheueling Chang Shantz and 13656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Douglas Stebila of Sun Microsystems Laboratories. 14656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 15656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 16656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* ==================================================================== 17221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. 18656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 19656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Redistribution and use in source and binary forms, with or without 20656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * modification, are permitted provided that the following conditions 21656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * are met: 22656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 23656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 1. Redistributions of source code must retain the above copyright 24656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * notice, this list of conditions and the following disclaimer. 25656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 26656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright 27656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * notice, this list of conditions and the following disclaimer in 28656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * the documentation and/or other materials provided with the 29656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * distribution. 30656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 31656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 3. All advertising materials mentioning features or use of this 32656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * software must display the following acknowledgment: 33656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * "This product includes software developed by the OpenSSL Project 34656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 35656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 36656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 37656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * endorse or promote products derived from this software without 38656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * prior written permission. For written permission, please contact 39656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * openssl-core@openssl.org. 40656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 41656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 5. Products derived from this software may not be called "OpenSSL" 42656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * nor may "OpenSSL" appear in their names without prior written 43656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * permission of the OpenSSL Project. 44656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 45656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 6. Redistributions of any form whatsoever must retain the following 46656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * acknowledgment: 47656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * "This product includes software developed by the OpenSSL Project 48656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 49656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 50656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 51656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 52656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 53656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 54656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 55656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 56656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 57656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 58656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 59656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 60656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 61656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * OF THE POSSIBILITY OF SUCH DAMAGE. 62656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ==================================================================== 63656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 64656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * This product includes cryptographic software written by Eric Young 65656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * (eay@cryptsoft.com). This product includes software written by Tim 66656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Hudson (tjh@cryptsoft.com). 67656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 68656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 69656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 70656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/err.h> 71656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 72656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "ec_lcl.h" 73656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 74392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifndef OPENSSL_NO_EC2M 75392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 76392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifdef OPENSSL_FIPS 77392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#include <openssl/fips.h> 78392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif 79392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 80656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 81656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectconst EC_METHOD *EC_GF2m_simple_method(void) 82656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 83392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifdef OPENSSL_FIPS 84392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom return fips_ec_gf2m_simple_method(); 85392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#else 86656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project static const EC_METHOD ret = { 87392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom EC_FLAGS_DEFAULT_OCT, 88656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project NID_X9_62_characteristic_two_field, 89656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ec_GF2m_simple_group_init, 90656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ec_GF2m_simple_group_finish, 91656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ec_GF2m_simple_group_clear_finish, 92656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ec_GF2m_simple_group_copy, 93656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ec_GF2m_simple_group_set_curve, 94656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ec_GF2m_simple_group_get_curve, 95656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ec_GF2m_simple_group_get_degree, 96656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ec_GF2m_simple_group_check_discriminant, 97656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ec_GF2m_simple_point_init, 98656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ec_GF2m_simple_point_finish, 99656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ec_GF2m_simple_point_clear_finish, 100656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ec_GF2m_simple_point_copy, 101656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ec_GF2m_simple_point_set_to_infinity, 102656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 0 /* set_Jprojective_coordinates_GFp */, 103656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 0 /* get_Jprojective_coordinates_GFp */, 104656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ec_GF2m_simple_point_set_affine_coordinates, 105656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ec_GF2m_simple_point_get_affine_coordinates, 106392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 0,0,0, 107656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ec_GF2m_simple_add, 108656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ec_GF2m_simple_dbl, 109656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ec_GF2m_simple_invert, 110656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ec_GF2m_simple_is_at_infinity, 111656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ec_GF2m_simple_is_on_curve, 112656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ec_GF2m_simple_cmp, 113656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ec_GF2m_simple_make_affine, 114656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ec_GF2m_simple_points_make_affine, 115656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 116656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* the following three method functions are defined in ec2_mult.c */ 117656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ec_GF2m_simple_mul, 118656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ec_GF2m_precompute_mult, 119656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ec_GF2m_have_precompute_mult, 120656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 121656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ec_GF2m_simple_field_mul, 122656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ec_GF2m_simple_field_sqr, 123656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ec_GF2m_simple_field_div, 124656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 0 /* field_encode */, 125656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 0 /* field_decode */, 126656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 0 /* field_set_to_one */ }; 127656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 128656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return &ret; 129392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif 130656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 131656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 132656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 133656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Initialize a GF(2^m)-based EC_GROUP structure. 134656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Note that all other members are handled by EC_GROUP_new. 135656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 136656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint ec_GF2m_simple_group_init(EC_GROUP *group) 137656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 138656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_init(&group->field); 139656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_init(&group->a); 140656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_init(&group->b); 141656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 1; 142656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 143656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 144656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 145656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Free a GF(2^m)-based EC_GROUP structure. 146656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Note that all other members are handled by EC_GROUP_free. 147656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 148656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectvoid ec_GF2m_simple_group_finish(EC_GROUP *group) 149656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 150656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_free(&group->field); 151656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_free(&group->a); 152656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_free(&group->b); 153656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 154656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 155656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 156656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Clear and free a GF(2^m)-based EC_GROUP structure. 157656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Note that all other members are handled by EC_GROUP_clear_free. 158656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 159656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectvoid ec_GF2m_simple_group_clear_finish(EC_GROUP *group) 160656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 161656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_clear_free(&group->field); 162656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_clear_free(&group->a); 163656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_clear_free(&group->b); 164656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project group->poly[0] = 0; 165656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project group->poly[1] = 0; 166656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project group->poly[2] = 0; 167656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project group->poly[3] = 0; 168656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project group->poly[4] = 0; 169221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom group->poly[5] = -1; 170656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 171656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 172656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 173656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Copy a GF(2^m)-based EC_GROUP structure. 174656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Note that all other members are handled by EC_GROUP_copy. 175656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 176656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint ec_GF2m_simple_group_copy(EC_GROUP *dest, const EC_GROUP *src) 177656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 178656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int i; 179656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!BN_copy(&dest->field, &src->field)) return 0; 180656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!BN_copy(&dest->a, &src->a)) return 0; 181656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!BN_copy(&dest->b, &src->b)) return 0; 182656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project dest->poly[0] = src->poly[0]; 183656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project dest->poly[1] = src->poly[1]; 184656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project dest->poly[2] = src->poly[2]; 185656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project dest->poly[3] = src->poly[3]; 186656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project dest->poly[4] = src->poly[4]; 187221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom dest->poly[5] = src->poly[5]; 188221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (bn_wexpand(&dest->a, (int)(dest->poly[0] + BN_BITS2 - 1) / BN_BITS2) == NULL) return 0; 189221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (bn_wexpand(&dest->b, (int)(dest->poly[0] + BN_BITS2 - 1) / BN_BITS2) == NULL) return 0; 190656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project for (i = dest->a.top; i < dest->a.dmax; i++) dest->a.d[i] = 0; 191656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project for (i = dest->b.top; i < dest->b.dmax; i++) dest->b.d[i] = 0; 192656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 1; 193656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 194656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 195656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 196656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Set the curve parameters of an EC_GROUP structure. */ 197656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint ec_GF2m_simple_group_set_curve(EC_GROUP *group, 198656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) 199656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 200656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int ret = 0, i; 201656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 202656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* group->field */ 203656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!BN_copy(&group->field, p)) goto err; 204221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom i = BN_GF2m_poly2arr(&group->field, group->poly, 6) - 1; 205656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if ((i != 5) && (i != 3)) 206656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 207656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECerr(EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE, EC_R_UNSUPPORTED_FIELD); 208656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 209656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 210656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 211656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* group->a */ 212656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!BN_GF2m_mod_arr(&group->a, a, group->poly)) goto err; 21398d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom if(bn_wexpand(&group->a, (int)(group->poly[0] + BN_BITS2 - 1) / BN_BITS2) == NULL) goto err; 214656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project for (i = group->a.top; i < group->a.dmax; i++) group->a.d[i] = 0; 215656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 216656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* group->b */ 217656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!BN_GF2m_mod_arr(&group->b, b, group->poly)) goto err; 21898d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom if(bn_wexpand(&group->b, (int)(group->poly[0] + BN_BITS2 - 1) / BN_BITS2) == NULL) goto err; 219656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project for (i = group->b.top; i < group->b.dmax; i++) group->b.d[i] = 0; 220656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 221656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret = 1; 222656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project err: 223656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return ret; 224656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 225656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 226656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 227656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Get the curve parameters of an EC_GROUP structure. 228656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * If p, a, or b are NULL then there values will not be set but the method will return with success. 229656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 230656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint ec_GF2m_simple_group_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx) 231656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 232656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int ret = 0; 233656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 234656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (p != NULL) 235656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 236656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!BN_copy(p, &group->field)) return 0; 237656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 238656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 239656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (a != NULL) 240656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 241656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!BN_copy(a, &group->a)) goto err; 242656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 243656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 244656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (b != NULL) 245656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 246656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!BN_copy(b, &group->b)) goto err; 247656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 248656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 249656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret = 1; 250656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 251656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project err: 252656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return ret; 253656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 254656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 255656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 256656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Gets the degree of the field. For a curve over GF(2^m) this is the value m. */ 257656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint ec_GF2m_simple_group_get_degree(const EC_GROUP *group) 258656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 259656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return BN_num_bits(&group->field)-1; 260656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 261656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 262656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 263656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Checks the discriminant of the curve. 264656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * y^2 + x*y = x^3 + a*x^2 + b is an elliptic curve <=> b != 0 (mod p) 265656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 266656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint ec_GF2m_simple_group_check_discriminant(const EC_GROUP *group, BN_CTX *ctx) 267656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 268656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int ret = 0; 269656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIGNUM *b; 270656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_CTX *new_ctx = NULL; 271656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 272656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (ctx == NULL) 273656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 274656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ctx = new_ctx = BN_CTX_new(); 275656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (ctx == NULL) 276656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 277656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECerr(EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT, ERR_R_MALLOC_FAILURE); 278656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 279656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 280656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 281656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_CTX_start(ctx); 282656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project b = BN_CTX_get(ctx); 283656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (b == NULL) goto err; 284656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 285656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!BN_GF2m_mod_arr(b, &group->b, group->poly)) goto err; 286656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 287656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* check the discriminant: 288656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * y^2 + x*y = x^3 + a*x^2 + b is an elliptic curve <=> b != 0 (mod p) 289656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 290656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (BN_is_zero(b)) goto err; 291656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 292656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret = 1; 293656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 294656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecterr: 295656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (ctx != NULL) 296656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_CTX_end(ctx); 297656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (new_ctx != NULL) 298656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_CTX_free(new_ctx); 299656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return ret; 300656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 301656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 302656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 303656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Initializes an EC_POINT. */ 304656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint ec_GF2m_simple_point_init(EC_POINT *point) 305656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 306656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_init(&point->X); 307656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_init(&point->Y); 308656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_init(&point->Z); 309656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 1; 310656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 311656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 312656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 313656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Frees an EC_POINT. */ 314656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectvoid ec_GF2m_simple_point_finish(EC_POINT *point) 315656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 316656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_free(&point->X); 317656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_free(&point->Y); 318656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_free(&point->Z); 319656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 320656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 321656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 322656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Clears and frees an EC_POINT. */ 323656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectvoid ec_GF2m_simple_point_clear_finish(EC_POINT *point) 324656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 325656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_clear_free(&point->X); 326656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_clear_free(&point->Y); 327656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_clear_free(&point->Z); 328656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project point->Z_is_one = 0; 329656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 330656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 331656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 332656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Copy the contents of one EC_POINT into another. Assumes dest is initialized. */ 333656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint ec_GF2m_simple_point_copy(EC_POINT *dest, const EC_POINT *src) 334656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 335656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!BN_copy(&dest->X, &src->X)) return 0; 336656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!BN_copy(&dest->Y, &src->Y)) return 0; 337656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!BN_copy(&dest->Z, &src->Z)) return 0; 338656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project dest->Z_is_one = src->Z_is_one; 339656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 340656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 1; 341656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 342656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 343656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 344656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Set an EC_POINT to the point at infinity. 345656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * A point at infinity is represented by having Z=0. 346656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 347656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint ec_GF2m_simple_point_set_to_infinity(const EC_GROUP *group, EC_POINT *point) 348656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 349656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project point->Z_is_one = 0; 350656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_zero(&point->Z); 351656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 1; 352656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 353656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 354656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 355656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Set the coordinates of an EC_POINT using affine coordinates. 356656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Note that the simple implementation only uses affine coordinates. 357656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 358656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint ec_GF2m_simple_point_set_affine_coordinates(const EC_GROUP *group, EC_POINT *point, 359656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx) 360656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 361656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int ret = 0; 362656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (x == NULL || y == NULL) 363656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 364656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECerr(EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES, ERR_R_PASSED_NULL_PARAMETER); 365656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 366656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 367656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 368656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!BN_copy(&point->X, x)) goto err; 369656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_set_negative(&point->X, 0); 370656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!BN_copy(&point->Y, y)) goto err; 371656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_set_negative(&point->Y, 0); 372656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!BN_copy(&point->Z, BN_value_one())) goto err; 373656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_set_negative(&point->Z, 0); 374656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project point->Z_is_one = 1; 375656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret = 1; 376656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 377656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project err: 378656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return ret; 379656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 380656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 381656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 382656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Gets the affine coordinates of an EC_POINT. 383656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Note that the simple implementation only uses affine coordinates. 384656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 385656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint ec_GF2m_simple_point_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point, 386656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIGNUM *x, BIGNUM *y, BN_CTX *ctx) 387656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 388656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int ret = 0; 389656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 390656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (EC_POINT_is_at_infinity(group, point)) 391656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 392656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECerr(EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES, EC_R_POINT_AT_INFINITY); 393656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 394656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 395656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 396656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (BN_cmp(&point->Z, BN_value_one())) 397656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 398656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ECerr(EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 399656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 400656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 401656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (x != NULL) 402656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 403656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!BN_copy(x, &point->X)) goto err; 404656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_set_negative(x, 0); 405656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 406656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (y != NULL) 407656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 408656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!BN_copy(y, &point->Y)) goto err; 409656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_set_negative(y, 0); 410656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 411656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret = 1; 412656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 413656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project err: 414656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return ret; 415656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 416656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 417656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Computes a + b and stores the result in r. r could be a or b, a could be b. 418656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Uses algorithm A.10.2 of IEEE P1363. 419656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 420656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint ec_GF2m_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx) 421656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 422656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_CTX *new_ctx = NULL; 423656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIGNUM *x0, *y0, *x1, *y1, *x2, *y2, *s, *t; 424656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int ret = 0; 425656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 426656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (EC_POINT_is_at_infinity(group, a)) 427656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 428656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!EC_POINT_copy(r, b)) return 0; 429656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 1; 430656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 431656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 432656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (EC_POINT_is_at_infinity(group, b)) 433656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 434656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!EC_POINT_copy(r, a)) return 0; 435656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 1; 436656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 437656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 438656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (ctx == NULL) 439656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 440656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ctx = new_ctx = BN_CTX_new(); 441656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (ctx == NULL) 442656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 443656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 444656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 445656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_CTX_start(ctx); 446656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project x0 = BN_CTX_get(ctx); 447656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project y0 = BN_CTX_get(ctx); 448656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project x1 = BN_CTX_get(ctx); 449656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project y1 = BN_CTX_get(ctx); 450656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project x2 = BN_CTX_get(ctx); 451656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project y2 = BN_CTX_get(ctx); 452656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project s = BN_CTX_get(ctx); 453656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project t = BN_CTX_get(ctx); 454656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (t == NULL) goto err; 455656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 456656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (a->Z_is_one) 457656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 458656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!BN_copy(x0, &a->X)) goto err; 459656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!BN_copy(y0, &a->Y)) goto err; 460656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 461656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else 462656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 463656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!EC_POINT_get_affine_coordinates_GF2m(group, a, x0, y0, ctx)) goto err; 464656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 465656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (b->Z_is_one) 466656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 467656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!BN_copy(x1, &b->X)) goto err; 468656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!BN_copy(y1, &b->Y)) goto err; 469656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 470656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else 471656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 472656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!EC_POINT_get_affine_coordinates_GF2m(group, b, x1, y1, ctx)) goto err; 473656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 474656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 475656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 476656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (BN_GF2m_cmp(x0, x1)) 477656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 478656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!BN_GF2m_add(t, x0, x1)) goto err; 479656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!BN_GF2m_add(s, y0, y1)) goto err; 480656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!group->meth->field_div(group, s, s, t, ctx)) goto err; 481656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!group->meth->field_sqr(group, x2, s, ctx)) goto err; 482656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!BN_GF2m_add(x2, x2, &group->a)) goto err; 483656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!BN_GF2m_add(x2, x2, s)) goto err; 484656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!BN_GF2m_add(x2, x2, t)) goto err; 485656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 486656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project else 487656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 488656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (BN_GF2m_cmp(y0, y1) || BN_is_zero(x1)) 489656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 490656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!EC_POINT_set_to_infinity(group, r)) goto err; 491656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret = 1; 492656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project goto err; 493656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 494656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!group->meth->field_div(group, s, y1, x1, ctx)) goto err; 495656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!BN_GF2m_add(s, s, x1)) goto err; 496656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 497656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!group->meth->field_sqr(group, x2, s, ctx)) goto err; 498656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!BN_GF2m_add(x2, x2, s)) goto err; 499656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!BN_GF2m_add(x2, x2, &group->a)) goto err; 500656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 501656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 502656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!BN_GF2m_add(y2, x1, x2)) goto err; 503656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!group->meth->field_mul(group, y2, y2, s, ctx)) goto err; 504656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!BN_GF2m_add(y2, y2, x2)) goto err; 505656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!BN_GF2m_add(y2, y2, y1)) goto err; 506656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 507656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!EC_POINT_set_affine_coordinates_GF2m(group, r, x2, y2, ctx)) goto err; 508656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 509656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret = 1; 510656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 511656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project err: 512656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_CTX_end(ctx); 513656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (new_ctx != NULL) 514656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_CTX_free(new_ctx); 515656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return ret; 516656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 517656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 518656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 519656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Computes 2 * a and stores the result in r. r could be a. 520656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Uses algorithm A.10.2 of IEEE P1363. 521656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 522656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint ec_GF2m_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx) 523656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 524656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return ec_GF2m_simple_add(group, r, a, a, ctx); 525656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 526656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 527656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 528656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint ec_GF2m_simple_invert(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) 529656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 530656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (EC_POINT_is_at_infinity(group, point) || BN_is_zero(&point->Y)) 531656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* point is its own inverse */ 532656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 1; 533656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 534656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!EC_POINT_make_affine(group, point, ctx)) return 0; 535656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return BN_GF2m_add(&point->Y, &point->X, &point->Y); 536656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 537656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 538656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 539656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Indicates whether the given point is the point at infinity. */ 540656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint ec_GF2m_simple_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) 541656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 542656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return BN_is_zero(&point->Z); 543656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 544656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 545656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 546656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Determines whether the given EC_POINT is an actual point on the curve defined 547656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * in the EC_GROUP. A point is valid if it satisfies the Weierstrass equation: 548656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * y^2 + x*y = x^3 + a*x^2 + b. 549656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 550656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint ec_GF2m_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx) 551656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 552656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int ret = -1; 553656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_CTX *new_ctx = NULL; 554656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIGNUM *lh, *y2; 555656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *); 556656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int (*field_sqr)(const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *); 557656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 558656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (EC_POINT_is_at_infinity(group, point)) 559656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 1; 560656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 561656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project field_mul = group->meth->field_mul; 562656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project field_sqr = group->meth->field_sqr; 563656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 564656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* only support affine coordinates */ 5657b476c43f6a45574eb34697244b592e7b09f05a3Brian Carlstrom if (!point->Z_is_one) return -1; 566656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 567656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (ctx == NULL) 568656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 569656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ctx = new_ctx = BN_CTX_new(); 570656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (ctx == NULL) 571656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return -1; 572656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 573656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 574656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_CTX_start(ctx); 575656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project y2 = BN_CTX_get(ctx); 576656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project lh = BN_CTX_get(ctx); 577656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (lh == NULL) goto err; 578656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 579656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project /* We have a curve defined by a Weierstrass equation 580656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * y^2 + x*y = x^3 + a*x^2 + b. 581656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * <=> x^3 + a*x^2 + x*y + b + y^2 = 0 582656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * <=> ((x + a) * x + y ) * x + b + y^2 = 0 583656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 584656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!BN_GF2m_add(lh, &point->X, &group->a)) goto err; 585656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!field_mul(group, lh, lh, &point->X, ctx)) goto err; 586656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!BN_GF2m_add(lh, lh, &point->Y)) goto err; 587656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!field_mul(group, lh, lh, &point->X, ctx)) goto err; 588656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!BN_GF2m_add(lh, lh, &group->b)) goto err; 589656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!field_sqr(group, y2, &point->Y, ctx)) goto err; 590656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!BN_GF2m_add(lh, lh, y2)) goto err; 591656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret = BN_is_zero(lh); 592656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project err: 593656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (ctx) BN_CTX_end(ctx); 594656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (new_ctx) BN_CTX_free(new_ctx); 595656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return ret; 596656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 597656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 598656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 599656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Indicates whether two points are equal. 600656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Return values: 601656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * -1 error 602656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 0 equal (in affine coordinates) 603656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 1 not equal 604656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */ 605656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint ec_GF2m_simple_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx) 606656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 607656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIGNUM *aX, *aY, *bX, *bY; 608656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_CTX *new_ctx = NULL; 609656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int ret = -1; 610656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 611656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (EC_POINT_is_at_infinity(group, a)) 612656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 613656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return EC_POINT_is_at_infinity(group, b) ? 0 : 1; 614656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 61581c4de7869b646592127e952cda763abf8305069Brian Carlstrom 61681c4de7869b646592127e952cda763abf8305069Brian Carlstrom if (EC_POINT_is_at_infinity(group, b)) 61781c4de7869b646592127e952cda763abf8305069Brian Carlstrom return 1; 618656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 619656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (a->Z_is_one && b->Z_is_one) 620656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 621656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return ((BN_cmp(&a->X, &b->X) == 0) && BN_cmp(&a->Y, &b->Y) == 0) ? 0 : 1; 622656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 623656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 624656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (ctx == NULL) 625656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 626656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ctx = new_ctx = BN_CTX_new(); 627656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (ctx == NULL) 628656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return -1; 629656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 630656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 631656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_CTX_start(ctx); 632656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project aX = BN_CTX_get(ctx); 633656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project aY = BN_CTX_get(ctx); 634656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bX = BN_CTX_get(ctx); 635656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bY = BN_CTX_get(ctx); 636656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (bY == NULL) goto err; 637656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 638656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!EC_POINT_get_affine_coordinates_GF2m(group, a, aX, aY, ctx)) goto err; 639656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!EC_POINT_get_affine_coordinates_GF2m(group, b, bX, bY, ctx)) goto err; 640656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret = ((BN_cmp(aX, bX) == 0) && BN_cmp(aY, bY) == 0) ? 0 : 1; 641656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 642656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project err: 643656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (ctx) BN_CTX_end(ctx); 644656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (new_ctx) BN_CTX_free(new_ctx); 645656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return ret; 646656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 647656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 648656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 649656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Forces the given EC_POINT to internally use affine coordinates. */ 650656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint ec_GF2m_simple_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) 651656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 652656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_CTX *new_ctx = NULL; 653656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BIGNUM *x, *y; 654656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project int ret = 0; 655656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 656656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (point->Z_is_one || EC_POINT_is_at_infinity(group, point)) 657656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 1; 658656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 659656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (ctx == NULL) 660656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 661656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ctx = new_ctx = BN_CTX_new(); 662656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (ctx == NULL) 663656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 0; 664656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 665656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 666656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project BN_CTX_start(ctx); 667656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project x = BN_CTX_get(ctx); 668656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project y = BN_CTX_get(ctx); 669656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (y == NULL) goto err; 670656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 671656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!EC_POINT_get_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err; 672656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!BN_copy(&point->X, x)) goto err; 673656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!BN_copy(&point->Y, y)) goto err; 674656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!BN_one(&point->Z)) goto err; 675656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 676656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project ret = 1; 677656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 678656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project err: 679656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (ctx) BN_CTX_end(ctx); 680656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (new_ctx) BN_CTX_free(new_ctx); 681656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return ret; 682656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 683656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 684656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 685656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Forces each of the EC_POINTs in the given array to use affine coordinates. */ 686656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint ec_GF2m_simple_points_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], BN_CTX *ctx) 687656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 688656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project size_t i; 689656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 690656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project for (i = 0; i < num; i++) 691656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 692656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!group->meth->make_affine(group, points[i], ctx)) return 0; 693656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 694656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 695656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return 1; 696656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 697656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 698656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 699656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Wrapper to simple binary polynomial field multiplication implementation. */ 700656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint ec_GF2m_simple_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) 701656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 702656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return BN_GF2m_mod_mul_arr(r, a, b, group->poly, ctx); 703656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 704656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 705656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 706656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Wrapper to simple binary polynomial field squaring implementation. */ 707656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint ec_GF2m_simple_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *ctx) 708656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 709656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return BN_GF2m_mod_sqr_arr(r, a, group->poly, ctx); 710656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 711656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 712656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 713656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Wrapper to simple binary polynomial field division implementation. */ 714656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint ec_GF2m_simple_field_div(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) 715656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project { 716656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return BN_GF2m_mod_div(r, a, b, &group->field, ctx); 717656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 718392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom 719392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif 720