138032Speter/* crypto/ec/ec_lcl.h */
238032Speter/*
338032Speter * Originally written by Bodo Moeller for the OpenSSL project.
438032Speter */
538032Speter/* ====================================================================
638032Speter * Copyright (c) 1998-2010 The OpenSSL Project.  All rights reserved.
738032Speter *
838032Speter * Redistribution and use in source and binary forms, with or without
938032Speter * modification, are permitted provided that the following conditions
1038032Speter * are met:
1138032Speter *
1238032Speter * 1. Redistributions of source code must retain the above copyright
1338032Speter *    notice, this list of conditions and the following disclaimer.
1438032Speter *
1538032Speter * 2. Redistributions in binary form must reproduce the above copyright
1638032Speter *    notice, this list of conditions and the following disclaimer in
1738032Speter *    the documentation and/or other materials provided with the
1838032Speter *    distribution.
1938032Speter *
2038032Speter * 3. All advertising materials mentioning features or use of this
2138032Speter *    software must display the following acknowledgment:
2238032Speter *    "This product includes software developed by the OpenSSL Project
2338032Speter *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
2438032Speter *
2538032Speter * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
2638032Speter *    endorse or promote products derived from this software without
2738032Speter *    prior written permission. For written permission, please contact
2838032Speter *    openssl-core@openssl.org.
2938032Speter *
3038032Speter * 5. Products derived from this software may not be called "OpenSSL"
3138032Speter *    nor may "OpenSSL" appear in their names without prior written
3238032Speter *    permission of the OpenSSL Project.
3338032Speter *
3438032Speter * 6. Redistributions of any form whatsoever must retain the following
3538032Speter *    acknowledgment:
3638032Speter *    "This product includes software developed by the OpenSSL Project
3738032Speter *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
3838032Speter *
3938032Speter * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
4038032Speter * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4138032Speter * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
4238032Speter * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
4338032Speter * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
4438032Speter * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
4538032Speter * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
4638032Speter * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4738032Speter * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
4838032Speter * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
4938032Speter * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
5038032Speter * OF THE POSSIBILITY OF SUCH DAMAGE.
5138032Speter * ====================================================================
5238032Speter *
5338032Speter * This product includes cryptographic software written by Eric Young
5438032Speter * (eay@cryptsoft.com).  This product includes software written by Tim
5538032Speter * Hudson (tjh@cryptsoft.com).
5638032Speter *
5738032Speter */
5838032Speter/* ====================================================================
5938032Speter * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
6038032Speter *
6138032Speter * Portions of the attached software ("Contribution") are developed by
6238032Speter * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
6338032Speter *
6438032Speter * The Contribution is licensed pursuant to the OpenSSL open source
6538032Speter * license provided above.
6638032Speter *
6738032Speter * The elliptic curve binary polynomial software is originally written by
6838032Speter * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
6938032Speter *
7038032Speter */
7138032Speter
7238032Speter#include <stdlib.h>
7338032Speter
7438032Speter#include <openssl/obj_mac.h>
7538032Speter#include <openssl/ec.h>
7638032Speter#include <openssl/bn.h>
7738032Speter
7838032Speter#if defined(__SUNPRO_C)
7938032Speter# if __SUNPRO_C >= 0x520
8038032Speter#  pragma error_messages (off,E_ARRAY_OF_INCOMPLETE_NONAME,E_ARRAY_OF_INCOMPLETE)
8138032Speter# endif
8238032Speter#endif
8338032Speter
8438032Speter/* Use default functions for poin2oct, oct2point and compressed coordinates */
8538032Speter#define EC_FLAGS_DEFAULT_OCT    0x1
8638032Speter
8738032Speter/*
8838032Speter * Structure details are not part of the exported interface, so all this may
8938032Speter * change in future versions.
9038032Speter */
9138032Speter
9238032Speterstruct ec_method_st {
9338032Speter    /* Various method flags */
9438032Speter    int flags;
9538032Speter    /* used by EC_METHOD_get_field_type: */
9638032Speter    int field_type;             /* a NID */
9738032Speter    /*
9838032Speter     * used by EC_GROUP_new, EC_GROUP_free, EC_GROUP_clear_free,
9938032Speter     * EC_GROUP_copy:
10038032Speter     */
10138032Speter    int (*group_init) (EC_GROUP *);
10238032Speter    void (*group_finish) (EC_GROUP *);
10338032Speter    void (*group_clear_finish) (EC_GROUP *);
10438032Speter    int (*group_copy) (EC_GROUP *, const EC_GROUP *);
10538032Speter    /* used by EC_GROUP_set_curve_GFp, EC_GROUP_get_curve_GFp, */
10638032Speter    /* EC_GROUP_set_curve_GF2m, and EC_GROUP_get_curve_GF2m: */
10738032Speter    int (*group_set_curve) (EC_GROUP *, const BIGNUM *p, const BIGNUM *a,
10838032Speter                            const BIGNUM *b, BN_CTX *);
10938032Speter    int (*group_get_curve) (const EC_GROUP *, BIGNUM *p, BIGNUM *a, BIGNUM *b,
11038032Speter                            BN_CTX *);
11138032Speter    /* used by EC_GROUP_get_degree: */
11238032Speter    int (*group_get_degree) (const EC_GROUP *);
11338032Speter    /* used by EC_GROUP_check: */
11438032Speter    int (*group_check_discriminant) (const EC_GROUP *, BN_CTX *);
11538032Speter    /*
11638032Speter     * used by EC_POINT_new, EC_POINT_free, EC_POINT_clear_free,
11738032Speter     * EC_POINT_copy:
11838032Speter     */
11938032Speter    int (*point_init) (EC_POINT *);
12038032Speter    void (*point_finish) (EC_POINT *);
12138032Speter    void (*point_clear_finish) (EC_POINT *);
12238032Speter    int (*point_copy) (EC_POINT *, const EC_POINT *);
12338032Speter    /*-
12438032Speter     * used by EC_POINT_set_to_infinity,
12538032Speter     * EC_POINT_set_Jprojective_coordinates_GFp,
12638032Speter     * EC_POINT_get_Jprojective_coordinates_GFp,
12738032Speter     * EC_POINT_set_affine_coordinates_GFp,     ..._GF2m,
12838032Speter     * EC_POINT_get_affine_coordinates_GFp,     ..._GF2m,
12938032Speter     * EC_POINT_set_compressed_coordinates_GFp, ..._GF2m:
13038032Speter     */
13138032Speter    int (*point_set_to_infinity) (const EC_GROUP *, EC_POINT *);
13238032Speter    int (*point_set_Jprojective_coordinates_GFp) (const EC_GROUP *,
13338032Speter                                                  EC_POINT *, const BIGNUM *x,
13438032Speter                                                  const BIGNUM *y,
13538032Speter                                                  const BIGNUM *z, BN_CTX *);
13638032Speter    int (*point_get_Jprojective_coordinates_GFp) (const EC_GROUP *,
13738032Speter                                                  const EC_POINT *, BIGNUM *x,
13838032Speter                                                  BIGNUM *y, BIGNUM *z,
13938032Speter                                                  BN_CTX *);
14038032Speter    int (*point_set_affine_coordinates) (const EC_GROUP *, EC_POINT *,
14138032Speter                                         const BIGNUM *x, const BIGNUM *y,
14238032Speter                                         BN_CTX *);
14338032Speter    int (*point_get_affine_coordinates) (const EC_GROUP *, const EC_POINT *,
14438032Speter                                         BIGNUM *x, BIGNUM *y, BN_CTX *);
14538032Speter    int (*point_set_compressed_coordinates) (const EC_GROUP *, EC_POINT *,
14638032Speter                                             const BIGNUM *x, int y_bit,
14738032Speter                                             BN_CTX *);
14838032Speter    /* used by EC_POINT_point2oct, EC_POINT_oct2point: */
14938032Speter    size_t (*point2oct) (const EC_GROUP *, const EC_POINT *,
15038032Speter                         point_conversion_form_t form, unsigned char *buf,
15138032Speter                         size_t len, BN_CTX *);
15238032Speter    int (*oct2point) (const EC_GROUP *, EC_POINT *, const unsigned char *buf,
15338032Speter                      size_t len, BN_CTX *);
15438032Speter    /* used by EC_POINT_add, EC_POINT_dbl, ECP_POINT_invert: */
15538032Speter    int (*add) (const EC_GROUP *, EC_POINT *r, const EC_POINT *a,
15638032Speter                const EC_POINT *b, BN_CTX *);
15738032Speter    int (*dbl) (const EC_GROUP *, EC_POINT *r, const EC_POINT *a, BN_CTX *);
15838032Speter    int (*invert) (const EC_GROUP *, EC_POINT *, BN_CTX *);
15938032Speter    /*
16038032Speter     * used by EC_POINT_is_at_infinity, EC_POINT_is_on_curve, EC_POINT_cmp:
16138032Speter     */
16238032Speter    int (*is_at_infinity) (const EC_GROUP *, const EC_POINT *);
16338032Speter    int (*is_on_curve) (const EC_GROUP *, const EC_POINT *, BN_CTX *);
16438032Speter    int (*point_cmp) (const EC_GROUP *, const EC_POINT *a, const EC_POINT *b,
16538032Speter                      BN_CTX *);
16638032Speter    /* used by EC_POINT_make_affine, EC_POINTs_make_affine: */
16738032Speter    int (*make_affine) (const EC_GROUP *, EC_POINT *, BN_CTX *);
16838032Speter    int (*points_make_affine) (const EC_GROUP *, size_t num, EC_POINT *[],
16938032Speter                               BN_CTX *);
17038032Speter    /*
17138032Speter     * used by EC_POINTs_mul, EC_POINT_mul, EC_POINT_precompute_mult,
17238032Speter     * EC_POINT_have_precompute_mult (default implementations are used if the
17338032Speter     * 'mul' pointer is 0):
17438032Speter     */
17538032Speter    int (*mul) (const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
17638032Speter                size_t num, const EC_POINT *points[], const BIGNUM *scalars[],
17738032Speter                BN_CTX *);
17838032Speter    int (*precompute_mult) (EC_GROUP *group, BN_CTX *);
17938032Speter    int (*have_precompute_mult) (const EC_GROUP *group);
18038032Speter    /* internal functions */
18138032Speter    /*
18238032Speter     * 'field_mul', 'field_sqr', and 'field_div' can be used by 'add' and
18338032Speter     * 'dbl' so that the same implementations of point operations can be used
18438032Speter     * with different optimized implementations of expensive field
18538032Speter     * operations:
18638032Speter     */
18738032Speter    int (*field_mul) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
18838032Speter                      const BIGNUM *b, BN_CTX *);
18938032Speter    int (*field_sqr) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
19038032Speter    int (*field_div) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
19138032Speter                      const BIGNUM *b, BN_CTX *);
19238032Speter    /* e.g. to Montgomery */
19338032Speter    int (*field_encode) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
19438032Speter                         BN_CTX *);
19538032Speter    /* e.g. from Montgomery */
19638032Speter    int (*field_decode) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
19738032Speter                         BN_CTX *);
19838032Speter    int (*field_set_to_one) (const EC_GROUP *, BIGNUM *r, BN_CTX *);
19938032Speter} /* EC_METHOD */ ;
20038032Speter
20138032Spetertypedef struct ec_extra_data_st {
20238032Speter    struct ec_extra_data_st *next;
20338032Speter    void *data;
20438032Speter    void *(*dup_func) (void *);
20538032Speter    void (*free_func) (void *);
20638032Speter    void (*clear_free_func) (void *);
20738032Speter} EC_EXTRA_DATA;                /* used in EC_GROUP */
20838032Speter
20938032Speterstruct ec_group_st {
21038032Speter    const EC_METHOD *meth;
21138032Speter    EC_POINT *generator;        /* optional */
21238032Speter    BIGNUM order, cofactor;
21338032Speter    int curve_name;             /* optional NID for named curve */
21438032Speter    int asn1_flag;              /* flag to control the asn1 encoding */
21538032Speter    point_conversion_form_t asn1_form;
21638032Speter    unsigned char *seed;        /* optional seed for parameters (appears in
21738032Speter                                 * ASN1) */
21838032Speter    size_t seed_len;
21938032Speter    EC_EXTRA_DATA *extra_data;  /* linked list */
22038032Speter    /*
22138032Speter     * The following members are handled by the method functions, even if
22238032Speter     * they appear generic
22338032Speter     */
22438032Speter    /*
22538032Speter     * Field specification. For curves over GF(p), this is the modulus; for
22638032Speter     * curves over GF(2^m), this is the irreducible polynomial defining the
22738032Speter     * field.
22838032Speter     */
22938032Speter    BIGNUM field;
23038032Speter    /*
23138032Speter     * Field specification for curves over GF(2^m). The irreducible f(t) is
23238032Speter     * then of the form: t^poly[0] + t^poly[1] + ... + t^poly[k] where m =
23338032Speter     * poly[0] > poly[1] > ... > poly[k] = 0. The array is terminated with
23438032Speter     * poly[k+1]=-1. All elliptic curve irreducibles have at most 5 non-zero
23538032Speter     * terms.
23638032Speter     */
23738032Speter    int poly[6];
23838032Speter    /*
23938032Speter     * Curve coefficients. (Here the assumption is that BIGNUMs can be used
24038032Speter     * or abused for all kinds of fields, not just GF(p).) For characteristic
24138032Speter     * > 3, the curve is defined by a Weierstrass equation of the form y^2 =
24238032Speter     * x^3 + a*x + b. For characteristic 2, the curve is defined by an
24338032Speter     * equation of the form y^2 + x*y = x^3 + a*x^2 + b.
24438032Speter     */
24538032Speter    BIGNUM a, b;
24638032Speter    /* enable optimized point arithmetics for special case */
24738032Speter    int a_is_minus3;
24838032Speter    /* method-specific (e.g., Montgomery structure) */
24938032Speter    void *field_data1;
25038032Speter    /* method-specific */
25138032Speter    void *field_data2;
25238032Speter    /* method-specific */
25338032Speter    int (*field_mod_func) (BIGNUM *, const BIGNUM *, const BIGNUM *,
25438032Speter                           BN_CTX *);
25538032Speter} /* EC_GROUP */ ;
25638032Speter
25738032Speterstruct ec_key_st {
25838032Speter    int version;
25938032Speter    EC_GROUP *group;
26038032Speter    EC_POINT *pub_key;
26138032Speter    BIGNUM *priv_key;
26238032Speter    unsigned int enc_flag;
26338032Speter    point_conversion_form_t conv_form;
26438032Speter    int references;
26538032Speter    int flags;
26638032Speter    EC_EXTRA_DATA *method_data;
26738032Speter} /* EC_KEY */ ;
26838032Speter
26938032Speter/*
27038032Speter * Basically a 'mixin' for extra data, but available for EC_GROUPs/EC_KEYs
27138032Speter * only (with visibility limited to 'package' level for now). We use the
27238032Speter * function pointers as index for retrieval; this obviates global
27338032Speter * ex_data-style index tables.
27438032Speter */
27538032Speterint EC_EX_DATA_set_data(EC_EXTRA_DATA **, void *data,
27638032Speter                        void *(*dup_func) (void *),
27738032Speter                        void (*free_func) (void *),
27838032Speter                        void (*clear_free_func) (void *));
27938032Spetervoid *EC_EX_DATA_get_data(const EC_EXTRA_DATA *, void *(*dup_func) (void *),
28038032Speter                          void (*free_func) (void *),
28138032Speter                          void (*clear_free_func) (void *));
28238032Spetervoid EC_EX_DATA_free_data(EC_EXTRA_DATA **, void *(*dup_func) (void *),
28338032Speter                          void (*free_func) (void *),
28438032Speter                          void (*clear_free_func) (void *));
28538032Spetervoid EC_EX_DATA_clear_free_data(EC_EXTRA_DATA **, void *(*dup_func) (void *),
28638032Speter                                void (*free_func) (void *),
28738032Speter                                void (*clear_free_func) (void *));
28838032Spetervoid EC_EX_DATA_free_all_data(EC_EXTRA_DATA **);
28938032Spetervoid EC_EX_DATA_clear_free_all_data(EC_EXTRA_DATA **);
29038032Speter
29138032Speterstruct ec_point_st {
29238032Speter    const EC_METHOD *meth;
29338032Speter    /*
29438032Speter     * All members except 'meth' are handled by the method functions, even if
29538032Speter     * they appear generic
29638032Speter     */
29738032Speter    BIGNUM X;
29838032Speter    BIGNUM Y;
29938032Speter    BIGNUM Z;                   /* Jacobian projective coordinates: (X, Y, Z)
30038032Speter                                 * represents (X/Z^2, Y/Z^3) if Z != 0 */
30138032Speter    int Z_is_one;               /* enable optimized point arithmetics for
30238032Speter                                 * special case */
30338032Speter} /* EC_POINT */ ;
30438032Speter
30538032Speter/*
30638032Speter * method functions in ec_mult.c (ec_lib.c uses these as defaults if
30738032Speter * group->method->mul is 0)
30838032Speter */
30938032Speterint ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
31038032Speter                size_t num, const EC_POINT *points[], const BIGNUM *scalars[],
31138032Speter                BN_CTX *);
31238032Speterint ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *);
31338032Speterint ec_wNAF_have_precompute_mult(const EC_GROUP *group);
31438032Speter
31538032Speter/* method functions in ecp_smpl.c */
31638032Speterint ec_GFp_simple_group_init(EC_GROUP *);
31738032Spetervoid ec_GFp_simple_group_finish(EC_GROUP *);
31838032Spetervoid ec_GFp_simple_group_clear_finish(EC_GROUP *);
31938032Speterint ec_GFp_simple_group_copy(EC_GROUP *, const EC_GROUP *);
32038032Speterint ec_GFp_simple_group_set_curve(EC_GROUP *, const BIGNUM *p,
32138032Speter                                  const BIGNUM *a, const BIGNUM *b, BN_CTX *);
32238032Speterint ec_GFp_simple_group_get_curve(const EC_GROUP *, BIGNUM *p, BIGNUM *a,
32338032Speter                                  BIGNUM *b, BN_CTX *);
32438032Speterint ec_GFp_simple_group_get_degree(const EC_GROUP *);
32538032Speterint ec_GFp_simple_group_check_discriminant(const EC_GROUP *, BN_CTX *);
32638032Speterint ec_GFp_simple_point_init(EC_POINT *);
32738032Spetervoid ec_GFp_simple_point_finish(EC_POINT *);
32838032Spetervoid ec_GFp_simple_point_clear_finish(EC_POINT *);
32938032Speterint ec_GFp_simple_point_copy(EC_POINT *, const EC_POINT *);
33038032Speterint ec_GFp_simple_point_set_to_infinity(const EC_GROUP *, EC_POINT *);
33138032Speterint ec_GFp_simple_set_Jprojective_coordinates_GFp(const EC_GROUP *,
33238032Speter                                                  EC_POINT *, const BIGNUM *x,
33338032Speter                                                  const BIGNUM *y,
33438032Speter                                                  const BIGNUM *z, BN_CTX *);
33538032Speterint ec_GFp_simple_get_Jprojective_coordinates_GFp(const EC_GROUP *,
33638032Speter                                                  const EC_POINT *, BIGNUM *x,
33738032Speter                                                  BIGNUM *y, BIGNUM *z,
33838032Speter                                                  BN_CTX *);
33938032Speterint ec_GFp_simple_point_set_affine_coordinates(const EC_GROUP *, EC_POINT *,
34038032Speter                                               const BIGNUM *x,
34138032Speter                                               const BIGNUM *y, BN_CTX *);
34238032Speterint ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *,
34338032Speter                                               const EC_POINT *, BIGNUM *x,
34438032Speter                                               BIGNUM *y, BN_CTX *);
34538032Speterint ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *, EC_POINT *,
34638032Speter                                             const BIGNUM *x, int y_bit,
34738032Speter                                             BN_CTX *);
34838032Spetersize_t ec_GFp_simple_point2oct(const EC_GROUP *, const EC_POINT *,
34938032Speter                               point_conversion_form_t form,
35038032Speter                               unsigned char *buf, size_t len, BN_CTX *);
35138032Speterint ec_GFp_simple_oct2point(const EC_GROUP *, EC_POINT *,
35238032Speter                            const unsigned char *buf, size_t len, BN_CTX *);
35338032Speterint ec_GFp_simple_add(const EC_GROUP *, EC_POINT *r, const EC_POINT *a,
35438032Speter                      const EC_POINT *b, BN_CTX *);
35538032Speterint ec_GFp_simple_dbl(const EC_GROUP *, EC_POINT *r, const EC_POINT *a,
35638032Speter                      BN_CTX *);
35738032Speterint ec_GFp_simple_invert(const EC_GROUP *, EC_POINT *, BN_CTX *);
35838032Speterint ec_GFp_simple_is_at_infinity(const EC_GROUP *, const EC_POINT *);
35938032Speterint ec_GFp_simple_is_on_curve(const EC_GROUP *, const EC_POINT *, BN_CTX *);
36038032Speterint ec_GFp_simple_cmp(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b,
36138032Speter                      BN_CTX *);
36238032Speterint ec_GFp_simple_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *);
36338032Speterint ec_GFp_simple_points_make_affine(const EC_GROUP *, size_t num,
36438032Speter                                     EC_POINT *[], BN_CTX *);
36538032Speterint ec_GFp_simple_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
36638032Speter                            const BIGNUM *b, BN_CTX *);
36738032Speterint ec_GFp_simple_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
36838032Speter                            BN_CTX *);
36938032Speter
37038032Speter/* method functions in ecp_mont.c */
37138032Speterint ec_GFp_mont_group_init(EC_GROUP *);
37238032Speterint ec_GFp_mont_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a,
37338032Speter                                const BIGNUM *b, BN_CTX *);
37438032Spetervoid ec_GFp_mont_group_finish(EC_GROUP *);
37538032Spetervoid ec_GFp_mont_group_clear_finish(EC_GROUP *);
37638032Speterint ec_GFp_mont_group_copy(EC_GROUP *, const EC_GROUP *);
37738032Speterint ec_GFp_mont_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
37838032Speter                          const BIGNUM *b, BN_CTX *);
37938032Speterint ec_GFp_mont_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
38038032Speter                          BN_CTX *);
38138032Speterint ec_GFp_mont_field_encode(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
38238032Speter                             BN_CTX *);
38338032Speterint ec_GFp_mont_field_decode(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
38438032Speter                             BN_CTX *);
38538032Speterint ec_GFp_mont_field_set_to_one(const EC_GROUP *, BIGNUM *r, BN_CTX *);
38638032Speter
38738032Speter/* method functions in ecp_nist.c */
38838032Speterint ec_GFp_nist_group_copy(EC_GROUP *dest, const EC_GROUP *src);
38938032Speterint ec_GFp_nist_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a,
39038032Speter                                const BIGNUM *b, BN_CTX *);
39138032Speterint ec_GFp_nist_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
39238032Speter                          const BIGNUM *b, BN_CTX *);
39338032Speterint ec_GFp_nist_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
39438032Speter                          BN_CTX *);
39538032Speter
39638032Speter/* method functions in ec2_smpl.c */
39738032Speterint ec_GF2m_simple_group_init(EC_GROUP *);
39838032Spetervoid ec_GF2m_simple_group_finish(EC_GROUP *);
39938032Spetervoid ec_GF2m_simple_group_clear_finish(EC_GROUP *);
40038032Speterint ec_GF2m_simple_group_copy(EC_GROUP *, const EC_GROUP *);
40138032Speterint ec_GF2m_simple_group_set_curve(EC_GROUP *, const BIGNUM *p,
40238032Speter                                   const BIGNUM *a, const BIGNUM *b,
40338032Speter                                   BN_CTX *);
40438032Speterint ec_GF2m_simple_group_get_curve(const EC_GROUP *, BIGNUM *p, BIGNUM *a,
40538032Speter                                   BIGNUM *b, BN_CTX *);
40638032Speterint ec_GF2m_simple_group_get_degree(const EC_GROUP *);
40738032Speterint ec_GF2m_simple_group_check_discriminant(const EC_GROUP *, BN_CTX *);
40838032Speterint ec_GF2m_simple_point_init(EC_POINT *);
40938032Spetervoid ec_GF2m_simple_point_finish(EC_POINT *);
41038032Spetervoid ec_GF2m_simple_point_clear_finish(EC_POINT *);
41138032Speterint ec_GF2m_simple_point_copy(EC_POINT *, const EC_POINT *);
41238032Speterint ec_GF2m_simple_point_set_to_infinity(const EC_GROUP *, EC_POINT *);
41338032Speterint ec_GF2m_simple_point_set_affine_coordinates(const EC_GROUP *, EC_POINT *,
41438032Speter                                                const BIGNUM *x,
41538032Speter                                                const BIGNUM *y, BN_CTX *);
41638032Speterint ec_GF2m_simple_point_get_affine_coordinates(const EC_GROUP *,
41738032Speter                                                const EC_POINT *, BIGNUM *x,
41838032Speter                                                BIGNUM *y, BN_CTX *);
41938032Speterint ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *, EC_POINT *,
42038032Speter                                              const BIGNUM *x, int y_bit,
42138032Speter                                              BN_CTX *);
42238032Spetersize_t ec_GF2m_simple_point2oct(const EC_GROUP *, const EC_POINT *,
42338032Speter                                point_conversion_form_t form,
42438032Speter                                unsigned char *buf, size_t len, BN_CTX *);
42538032Speterint ec_GF2m_simple_oct2point(const EC_GROUP *, EC_POINT *,
42638032Speter                             const unsigned char *buf, size_t len, BN_CTX *);
42738032Speterint ec_GF2m_simple_add(const EC_GROUP *, EC_POINT *r, const EC_POINT *a,
42838032Speter                       const EC_POINT *b, BN_CTX *);
42938032Speterint ec_GF2m_simple_dbl(const EC_GROUP *, EC_POINT *r, const EC_POINT *a,
43038032Speter                       BN_CTX *);
43138032Speterint ec_GF2m_simple_invert(const EC_GROUP *, EC_POINT *, BN_CTX *);
43238032Speterint ec_GF2m_simple_is_at_infinity(const EC_GROUP *, const EC_POINT *);
43338032Speterint ec_GF2m_simple_is_on_curve(const EC_GROUP *, const EC_POINT *, BN_CTX *);
43438032Speterint ec_GF2m_simple_cmp(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b,
43538032Speter                       BN_CTX *);
43638032Speterint ec_GF2m_simple_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *);
43738032Speterint ec_GF2m_simple_points_make_affine(const EC_GROUP *, size_t num,
43838032Speter                                      EC_POINT *[], BN_CTX *);
43938032Speterint ec_GF2m_simple_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
44038032Speter                             const BIGNUM *b, BN_CTX *);
44138032Speterint ec_GF2m_simple_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
44238032Speter                             BN_CTX *);
44338032Speterint ec_GF2m_simple_field_div(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
44438032Speter                             const BIGNUM *b, BN_CTX *);
44538032Speter
44638032Speter/* method functions in ec2_mult.c */
44738032Speterint ec_GF2m_simple_mul(const EC_GROUP *group, EC_POINT *r,
44838032Speter                       const BIGNUM *scalar, size_t num,
44938032Speter                       const EC_POINT *points[], const BIGNUM *scalars[],
45038032Speter                       BN_CTX *);
45138032Speterint ec_GF2m_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
45238032Speterint ec_GF2m_have_precompute_mult(const EC_GROUP *group);
45338032Speter
45438032Speter#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
45538032Speter/* method functions in ecp_nistp224.c */
45638032Speterint ec_GFp_nistp224_group_init(EC_GROUP *group);
45738032Speterint ec_GFp_nistp224_group_set_curve(EC_GROUP *group, const BIGNUM *p,
45838032Speter                                    const BIGNUM *a, const BIGNUM *n,
45938032Speter                                    BN_CTX *);
46038032Speterint ec_GFp_nistp224_point_get_affine_coordinates(const EC_GROUP *group,
46138032Speter                                                 const EC_POINT *point,
46238032Speter                                                 BIGNUM *x, BIGNUM *y,
46338032Speter                                                 BN_CTX *ctx);
46438032Speterint ec_GFp_nistp224_mul(const EC_GROUP *group, EC_POINT *r,
46538032Speter                        const BIGNUM *scalar, size_t num,
46638032Speter                        const EC_POINT *points[], const BIGNUM *scalars[],
46738032Speter                        BN_CTX *);
46838032Speterint ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
46938032Speter                               const BIGNUM *scalar, size_t num,
47038032Speter                               const EC_POINT *points[],
47138032Speter                               const BIGNUM *scalars[], BN_CTX *ctx);
47238032Speterint ec_GFp_nistp224_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
47338032Speterint ec_GFp_nistp224_have_precompute_mult(const EC_GROUP *group);
47438032Speter
47538032Speter/* method functions in ecp_nistp256.c */
47638032Speterint ec_GFp_nistp256_group_init(EC_GROUP *group);
47738032Speterint ec_GFp_nistp256_group_set_curve(EC_GROUP *group, const BIGNUM *p,
47838032Speter                                    const BIGNUM *a, const BIGNUM *n,
47938032Speter                                    BN_CTX *);
48038032Speterint ec_GFp_nistp256_point_get_affine_coordinates(const EC_GROUP *group,
48138032Speter                                                 const EC_POINT *point,
48238032Speter                                                 BIGNUM *x, BIGNUM *y,
48338032Speter                                                 BN_CTX *ctx);
48438032Speterint ec_GFp_nistp256_mul(const EC_GROUP *group, EC_POINT *r,
48538032Speter                        const BIGNUM *scalar, size_t num,
48638032Speter                        const EC_POINT *points[], const BIGNUM *scalars[],
48738032Speter                        BN_CTX *);
48838032Speterint ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
48938032Speter                               const BIGNUM *scalar, size_t num,
49038032Speter                               const EC_POINT *points[],
49138032Speter                               const BIGNUM *scalars[], BN_CTX *ctx);
49238032Speterint ec_GFp_nistp256_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
49338032Speterint ec_GFp_nistp256_have_precompute_mult(const EC_GROUP *group);
49438032Speter
49538032Speter/* method functions in ecp_nistp521.c */
49638032Speterint ec_GFp_nistp521_group_init(EC_GROUP *group);
49738032Speterint ec_GFp_nistp521_group_set_curve(EC_GROUP *group, const BIGNUM *p,
49838032Speter                                    const BIGNUM *a, const BIGNUM *n,
49938032Speter                                    BN_CTX *);
50038032Speterint ec_GFp_nistp521_point_get_affine_coordinates(const EC_GROUP *group,
50138032Speter                                                 const EC_POINT *point,
50238032Speter                                                 BIGNUM *x, BIGNUM *y,
50338032Speter                                                 BN_CTX *ctx);
50438032Speterint ec_GFp_nistp521_mul(const EC_GROUP *group, EC_POINT *r,
50538032Speter                        const BIGNUM *scalar, size_t num,
50638032Speter                        const EC_POINT *points[], const BIGNUM *scalars[],
50738032Speter                        BN_CTX *);
50838032Speterint ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r,
50938032Speter                               const BIGNUM *scalar, size_t num,
51038032Speter                               const EC_POINT *points[],
51138032Speter                               const BIGNUM *scalars[], BN_CTX *ctx);
51238032Speterint ec_GFp_nistp521_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
51338032Speterint ec_GFp_nistp521_have_precompute_mult(const EC_GROUP *group);
51438032Speter
51538032Speter/* utility functions in ecp_nistputil.c */
51638032Spetervoid ec_GFp_nistp_points_make_affine_internal(size_t num, void *point_array,
51738032Speter                                              size_t felem_size,
51838032Speter                                              void *tmp_felems,
51938032Speter                                              void (*felem_one) (void *out),
52038032Speter                                              int (*felem_is_zero) (const void
52138032Speter                                                                    *in),
52238032Speter                                              void (*felem_assign) (void *out,
52338032Speter                                                                    const void
52438032Speter                                                                    *in),
52538032Speter                                              void (*felem_square) (void *out,
52638032Speter                                                                    const void
52738032Speter                                                                    *in),
52838032Speter                                              void (*felem_mul) (void *out,
52938032Speter                                                                 const void
53038032Speter                                                                 *in1,
53138032Speter                                                                 const void
53238032Speter                                                                 *in2),
53338032Speter                                              void (*felem_inv) (void *out,
53438032Speter                                                                 const void
53538032Speter                                                                 *in),
53638032Speter                                              void (*felem_contract) (void
53738032Speter                                                                      *out,
53838032Speter                                                                      const
53938032Speter                                                                      void
54038032Speter                                                                      *in));
54138032Spetervoid ec_GFp_nistp_recode_scalar_bits(unsigned char *sign,
54238032Speter                                     unsigned char *digit, unsigned char in);
54338032Speter#endif
54438032Speter