summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/ec
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/ec')
-rw-r--r--src/lib/libcrypto/ec/Makefile193
-rw-r--r--src/lib/libcrypto/ec/Makefile.ssl128
-rw-r--r--src/lib/libcrypto/ec/ec.h319
-rw-r--r--src/lib/libcrypto/ec/ec2_smpt.c74
-rw-r--r--src/lib/libcrypto/ec/ec_cvt.c76
-rw-r--r--src/lib/libcrypto/ec/ec_err.c114
-rw-r--r--src/lib/libcrypto/ec/ec_lcl.h241
-rw-r--r--src/lib/libcrypto/ec/ec_lib.c678
-rw-r--r--src/lib/libcrypto/ec/ec_mult.c673
-rw-r--r--src/lib/libcrypto/ec/ecp_mont.c151
-rw-r--r--src/lib/libcrypto/ec/ecp_nist.c180
-rw-r--r--src/lib/libcrypto/ec/ecp_recp.c133
-rw-r--r--src/lib/libcrypto/ec/ecp_smpl.c335
-rw-r--r--src/lib/libcrypto/ec/ectest.c643
14 files changed, 1745 insertions, 2193 deletions
diff --git a/src/lib/libcrypto/ec/Makefile b/src/lib/libcrypto/ec/Makefile
new file mode 100644
index 0000000000..42f7bb7fc8
--- /dev/null
+++ b/src/lib/libcrypto/ec/Makefile
@@ -0,0 +1,193 @@
1#
2# crypto/ec/Makefile
3#
4
5DIR= ec
6TOP= ../..
7CC= cc
8INCLUDES= -I.. -I$(TOP) -I../../include
9CFLAG=-g
10MAKEFILE= Makefile
11AR= ar r
12
13CFLAGS= $(INCLUDES) $(CFLAG)
14
15GENERAL=Makefile
16TEST=ectest.c
17APPS=
18
19LIB=$(TOP)/libcrypto.a
20LIBSRC= ec_lib.c ecp_smpl.c ecp_mont.c ecp_nist.c ec_cvt.c ec_mult.c\
21 ec_err.c ec_curve.c ec_check.c ec_print.c ec_asn1.c ec_key.c\
22 ec2_smpl.c ec2_smpt.c ec2_mult.c
23
24LIBOBJ= ec_lib.o ecp_smpl.o ecp_mont.o ecp_nist.o ec_cvt.o ec_mult.o\
25 ec_err.o ec_curve.o ec_check.o ec_print.o ec_asn1.o ec_key.o\
26 ec2_smpl.o ec2_mult.o
27
28SRC= $(LIBSRC)
29
30EXHEADER= ec.h
31HEADER= ec_lcl.h $(EXHEADER)
32
33ALL= $(GENERAL) $(SRC) $(HEADER)
34
35top:
36 (cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
37
38all: lib
39
40lib: $(LIBOBJ)
41 $(AR) $(LIB) $(LIBOBJ)
42 $(RANLIB) $(LIB) || echo Never mind.
43 @touch lib
44
45files:
46 $(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
47
48links:
49 @$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
50 @$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
51 @$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
52
53install:
54 @[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
55 @headerlist="$(EXHEADER)"; for i in $$headerlist ; \
56 do \
57 (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
58 chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
59 done;
60
61tags:
62 ctags $(SRC)
63
64tests:
65
66lint:
67 lint -DLINT $(INCLUDES) $(SRC)>fluff
68
69depend:
70 @[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
71 $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
72
73dclean:
74 $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
75 mv -f Makefile.new $(MAKEFILE)
76
77clean:
78 rm -f *.o */*.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
79
80# DO NOT DELETE THIS LINE -- make depend depends on it.
81
82ec2_mult.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
83ec2_mult.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
84ec2_mult.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
85ec2_mult.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
86ec2_mult.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
87ec2_mult.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
88ec2_mult.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
89ec2_mult.o: ../../include/openssl/symhacks.h ec2_mult.c ec_lcl.h
90ec2_smpl.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
91ec2_smpl.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
92ec2_smpl.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
93ec2_smpl.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
94ec2_smpl.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
95ec2_smpl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
96ec2_smpl.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
97ec2_smpl.o: ../../include/openssl/symhacks.h ec2_smpl.c ec2_smpt.c ec_lcl.h
98ec2_smpt.o: ec2_smpt.c
99ec_asn1.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
100ec_asn1.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
101ec_asn1.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
102ec_asn1.o: ../../include/openssl/ec.h ../../include/openssl/err.h
103ec_asn1.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
104ec_asn1.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
105ec_asn1.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
106ec_asn1.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
107ec_asn1.o: ../../include/openssl/symhacks.h ec_asn1.c ec_lcl.h
108ec_check.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
109ec_check.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
110ec_check.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
111ec_check.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
112ec_check.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
113ec_check.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
114ec_check.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
115ec_check.o: ../../include/openssl/symhacks.h ec_check.c ec_lcl.h
116ec_curve.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
117ec_curve.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
118ec_curve.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
119ec_curve.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
120ec_curve.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
121ec_curve.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
122ec_curve.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
123ec_curve.o: ../../include/openssl/symhacks.h ec_curve.c ec_lcl.h
124ec_cvt.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
125ec_cvt.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
126ec_cvt.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
127ec_cvt.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
128ec_cvt.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
129ec_cvt.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
130ec_cvt.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
131ec_cvt.o: ../../include/openssl/symhacks.h ec_cvt.c ec_lcl.h
132ec_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
133ec_err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
134ec_err.o: ../../include/openssl/ec.h ../../include/openssl/err.h
135ec_err.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
136ec_err.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
137ec_err.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
138ec_err.o: ../../include/openssl/symhacks.h ec_err.c
139ec_key.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
140ec_key.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
141ec_key.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
142ec_key.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
143ec_key.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
144ec_key.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
145ec_key.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
146ec_key.o: ../../include/openssl/symhacks.h ec_key.c ec_lcl.h
147ec_lib.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
148ec_lib.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
149ec_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
150ec_lib.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
151ec_lib.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
152ec_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
153ec_lib.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
154ec_lib.o: ../../include/openssl/symhacks.h ec_lcl.h ec_lib.c
155ec_mult.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
156ec_mult.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
157ec_mult.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
158ec_mult.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
159ec_mult.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
160ec_mult.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
161ec_mult.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
162ec_mult.o: ../../include/openssl/symhacks.h ec_lcl.h ec_mult.c
163ec_print.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
164ec_print.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
165ec_print.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
166ec_print.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
167ec_print.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
168ec_print.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
169ec_print.o: ../../include/openssl/symhacks.h ec_lcl.h ec_print.c
170ecp_mont.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
171ecp_mont.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
172ecp_mont.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
173ecp_mont.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
174ecp_mont.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
175ecp_mont.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
176ecp_mont.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
177ecp_mont.o: ../../include/openssl/symhacks.h ec_lcl.h ecp_mont.c
178ecp_nist.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
179ecp_nist.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
180ecp_nist.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
181ecp_nist.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
182ecp_nist.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
183ecp_nist.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
184ecp_nist.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
185ecp_nist.o: ../../include/openssl/symhacks.h ec_lcl.h ecp_nist.c
186ecp_smpl.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
187ecp_smpl.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
188ecp_smpl.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
189ecp_smpl.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
190ecp_smpl.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
191ecp_smpl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
192ecp_smpl.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
193ecp_smpl.o: ../../include/openssl/symhacks.h ec_lcl.h ecp_smpl.c
diff --git a/src/lib/libcrypto/ec/Makefile.ssl b/src/lib/libcrypto/ec/Makefile.ssl
new file mode 100644
index 0000000000..a2805c47a2
--- /dev/null
+++ b/src/lib/libcrypto/ec/Makefile.ssl
@@ -0,0 +1,128 @@
1#
2# crypto/ec/Makefile
3#
4
5DIR= ec
6TOP= ../..
7CC= cc
8INCLUDES= -I.. -I$(TOP) -I../../include
9CFLAG=-g
10INSTALL_PREFIX=
11OPENSSLDIR= /usr/local/ssl
12INSTALLTOP=/usr/local/ssl
13MAKE= make -f Makefile.ssl
14MAKEDEPPROG= makedepend
15MAKEDEPEND= $(TOP)/util/domd $(TOP) -MD $(MAKEDEPPROG)
16MAKEFILE= Makefile.ssl
17AR= ar r
18
19CFLAGS= $(INCLUDES) $(CFLAG)
20
21GENERAL=Makefile
22TEST=ectest.c
23APPS=
24
25LIB=$(TOP)/libcrypto.a
26LIBSRC= ec_lib.c ecp_smpl.c ecp_mont.c ecp_recp.c ecp_nist.c ec_cvt.c ec_mult.c \
27 ec_err.c
28
29LIBOBJ= ec_lib.o ecp_smpl.o ecp_mont.o ecp_recp.o ecp_nist.o ec_cvt.o ec_mult.o \
30 ec_err.o
31
32SRC= $(LIBSRC)
33
34EXHEADER= ec.h
35HEADER= ec_lcl.h $(EXHEADER)
36
37ALL= $(GENERAL) $(SRC) $(HEADER)
38
39top:
40 (cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
41
42all: lib
43
44lib: $(LIBOBJ)
45 $(AR) $(LIB) $(LIBOBJ)
46 $(RANLIB) $(LIB) || echo Never mind.
47 @touch lib
48
49files:
50 $(PERL) $(TOP)/util/files.pl Makefile.ssl >> $(TOP)/MINFO
51
52links:
53 @sh $(TOP)/util/point.sh Makefile.ssl Makefile
54 @$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
55 @$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
56 @$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
57
58install:
59 @for i in $(EXHEADER) ; \
60 do \
61 (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
62 chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
63 done;
64
65tags:
66 ctags $(SRC)
67
68tests:
69
70lint:
71 lint -DLINT $(INCLUDES) $(SRC)>fluff
72
73depend:
74 $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
75
76dclean:
77 $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
78 mv -f Makefile.new $(MAKEFILE)
79
80clean:
81 rm -f *.o */*.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
82
83# DO NOT DELETE THIS LINE -- make depend depends on it.
84
85ec_cvt.o: ../../include/openssl/bn.h ../../include/openssl/e_os2.h
86ec_cvt.o: ../../include/openssl/ec.h ../../include/openssl/opensslconf.h
87ec_cvt.o: ../../include/openssl/symhacks.h ec_cvt.c ec_lcl.h
88ec_err.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
89ec_err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
90ec_err.o: ../../include/openssl/ec.h ../../include/openssl/err.h
91ec_err.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
92ec_err.o: ../../include/openssl/opensslv.h ../../include/openssl/safestack.h
93ec_err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
94ec_err.o: ec_err.c
95ec_lib.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
96ec_lib.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
97ec_lib.o: ../../include/openssl/ec.h ../../include/openssl/err.h
98ec_lib.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
99ec_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/safestack.h
100ec_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
101ec_lib.o: ec_lcl.h ec_lib.c
102ec_mult.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
103ec_mult.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
104ec_mult.o: ../../include/openssl/ec.h ../../include/openssl/err.h
105ec_mult.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
106ec_mult.o: ../../include/openssl/opensslv.h ../../include/openssl/safestack.h
107ec_mult.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
108ec_mult.o: ec_lcl.h ec_mult.c
109ecp_mont.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
110ecp_mont.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
111ecp_mont.o: ../../include/openssl/ec.h ../../include/openssl/err.h
112ecp_mont.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
113ecp_mont.o: ../../include/openssl/opensslv.h ../../include/openssl/safestack.h
114ecp_mont.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
115ecp_mont.o: ec_lcl.h ecp_mont.c
116ecp_nist.o: ../../include/openssl/bn.h ../../include/openssl/e_os2.h
117ecp_nist.o: ../../include/openssl/ec.h ../../include/openssl/opensslconf.h
118ecp_nist.o: ../../include/openssl/symhacks.h ec_lcl.h ecp_nist.c
119ecp_recp.o: ../../include/openssl/bn.h ../../include/openssl/e_os2.h
120ecp_recp.o: ../../include/openssl/ec.h ../../include/openssl/opensslconf.h
121ecp_recp.o: ../../include/openssl/symhacks.h ec_lcl.h ecp_recp.c
122ecp_smpl.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
123ecp_smpl.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
124ecp_smpl.o: ../../include/openssl/ec.h ../../include/openssl/err.h
125ecp_smpl.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
126ecp_smpl.o: ../../include/openssl/opensslv.h ../../include/openssl/safestack.h
127ecp_smpl.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
128ecp_smpl.o: ec_lcl.h ecp_smpl.c
diff --git a/src/lib/libcrypto/ec/ec.h b/src/lib/libcrypto/ec/ec.h
index 8bc2a235b1..6d6a9b7127 100644
--- a/src/lib/libcrypto/ec/ec.h
+++ b/src/lib/libcrypto/ec/ec.h
@@ -1,9 +1,6 @@
1/* crypto/ec/ec.h */ 1/* crypto/ec/ec.h */
2/*
3 * Originally written by Bodo Moeller for the OpenSSL project.
4 */
5/* ==================================================================== 2/* ====================================================================
6 * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. 3 * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
7 * 4 *
8 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
@@ -55,48 +52,22 @@
55 * Hudson (tjh@cryptsoft.com). 52 * Hudson (tjh@cryptsoft.com).
56 * 53 *
57 */ 54 */
58/* ====================================================================
59 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
60 *
61 * Portions of the attached software ("Contribution") are developed by
62 * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
63 *
64 * The Contribution is licensed pursuant to the OpenSSL open source
65 * license provided above.
66 *
67 * The elliptic curve binary polynomial software is originally written by
68 * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
69 *
70 */
71 55
72#ifndef HEADER_EC_H 56#ifndef HEADER_EC_H
73#define HEADER_EC_H 57#define HEADER_EC_H
74 58
75#include <openssl/opensslconf.h>
76
77#ifdef OPENSSL_NO_EC 59#ifdef OPENSSL_NO_EC
78#error EC is disabled. 60#error EC is disabled.
79#endif 61#endif
80 62
81#include <openssl/asn1.h>
82#include <openssl/symhacks.h>
83#ifndef OPENSSL_NO_DEPRECATED
84#include <openssl/bn.h> 63#include <openssl/bn.h>
85#endif 64#include <openssl/symhacks.h>
86 65
87#ifdef __cplusplus 66#ifdef __cplusplus
88extern "C" { 67extern "C" {
89#elif defined(__SUNPRO_C)
90# if __SUNPRO_C >= 0x520
91# pragma error_messages (off,E_ARRAY_OF_INCOMPLETE_NONAME,E_ARRAY_OF_INCOMPLETE)
92# endif
93#endif 68#endif
94 69
95 70
96#ifndef OPENSSL_ECC_MAX_FIELD_BITS
97# define OPENSSL_ECC_MAX_FIELD_BITS 661
98#endif
99
100typedef enum { 71typedef enum {
101 /* values as defined in X9.62 (ECDSA) and elsewhere */ 72 /* values as defined in X9.62 (ECDSA) and elsewhere */
102 POINT_CONVERSION_COMPRESSED = 2, 73 POINT_CONVERSION_COMPRESSED = 2,
@@ -113,8 +84,7 @@ typedef struct ec_group_st
113 -- field definition 84 -- field definition
114 -- curve coefficients 85 -- curve coefficients
115 -- optional generator with associated information (order, cofactor) 86 -- optional generator with associated information (order, cofactor)
116 -- optional extra data (precomputed table for fast computation of multiples of generator) 87 -- optional extra data (TODO: precomputed table for fast computation of multiples of generator)
117 -- ASN1 stuff
118 */ 88 */
119 EC_GROUP; 89 EC_GROUP;
120 90
@@ -126,84 +96,40 @@ typedef struct ec_point_st EC_POINT;
126 */ 96 */
127const EC_METHOD *EC_GFp_simple_method(void); 97const EC_METHOD *EC_GFp_simple_method(void);
128const EC_METHOD *EC_GFp_mont_method(void); 98const EC_METHOD *EC_GFp_mont_method(void);
129const EC_METHOD *EC_GFp_nist_method(void); 99#if 0
130 100const EC_METHOD *EC_GFp_recp_method(void); /* TODO */
131/* EC_METHOD for curves over GF(2^m). 101const EC_METHOD *EC_GFp_nist_method(void); /* TODO */
132 */ 102#endif
133const EC_METHOD *EC_GF2m_simple_method(void);
134 103
135 104
136EC_GROUP *EC_GROUP_new(const EC_METHOD *); 105EC_GROUP *EC_GROUP_new(const EC_METHOD *);
137void EC_GROUP_free(EC_GROUP *); 106void EC_GROUP_free(EC_GROUP *);
138void EC_GROUP_clear_free(EC_GROUP *); 107void EC_GROUP_clear_free(EC_GROUP *);
139int EC_GROUP_copy(EC_GROUP *, const EC_GROUP *); 108int EC_GROUP_copy(EC_GROUP *, const EC_GROUP *);
140EC_GROUP *EC_GROUP_dup(const EC_GROUP *);
141 109
142const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *); 110const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *);
143int EC_METHOD_get_field_type(const EC_METHOD *); 111
144
145int EC_GROUP_set_generator(EC_GROUP *, const EC_POINT *generator, const BIGNUM *order, const BIGNUM *cofactor);
146const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *);
147int EC_GROUP_get_order(const EC_GROUP *, BIGNUM *order, BN_CTX *);
148int EC_GROUP_get_cofactor(const EC_GROUP *, BIGNUM *cofactor, BN_CTX *);
149
150void EC_GROUP_set_curve_name(EC_GROUP *, int nid);
151int EC_GROUP_get_curve_name(const EC_GROUP *);
152
153void EC_GROUP_set_asn1_flag(EC_GROUP *, int flag);
154int EC_GROUP_get_asn1_flag(const EC_GROUP *);
155
156void EC_GROUP_set_point_conversion_form(EC_GROUP *, point_conversion_form_t);
157point_conversion_form_t EC_GROUP_get_point_conversion_form(const EC_GROUP *);
158
159unsigned char *EC_GROUP_get0_seed(const EC_GROUP *);
160size_t EC_GROUP_get_seed_len(const EC_GROUP *);
161size_t EC_GROUP_set_seed(EC_GROUP *, const unsigned char *, size_t len);
162 112
113/* We don't have types for field specifications and field elements in general.
114 * Otherwise we could declare
115 * int EC_GROUP_set_curve(EC_GROUP *, .....);
116 */
163int EC_GROUP_set_curve_GFp(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *); 117int EC_GROUP_set_curve_GFp(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
164int EC_GROUP_get_curve_GFp(const EC_GROUP *, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *); 118int EC_GROUP_get_curve_GFp(const EC_GROUP *, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *);
165int EC_GROUP_set_curve_GF2m(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
166int EC_GROUP_get_curve_GF2m(const EC_GROUP *, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *);
167
168/* returns the number of bits needed to represent a field element */
169int EC_GROUP_get_degree(const EC_GROUP *);
170
171/* EC_GROUP_check() returns 1 if 'group' defines a valid group, 0 otherwise */
172int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx);
173/* EC_GROUP_check_discriminant() returns 1 if the discriminant of the
174 * elliptic curve is not zero, 0 otherwise */
175int EC_GROUP_check_discriminant(const EC_GROUP *, BN_CTX *);
176 119
177/* EC_GROUP_cmp() returns 0 if both groups are equal and 1 otherwise */ 120/* EC_GROUP_new_GFp() calls EC_GROUP_new() and EC_GROUP_set_GFp()
178int EC_GROUP_cmp(const EC_GROUP *, const EC_GROUP *, BN_CTX *);
179
180/* EC_GROUP_new_GF*() calls EC_GROUP_new() and EC_GROUP_set_GF*()
181 * after choosing an appropriate EC_METHOD */ 121 * after choosing an appropriate EC_METHOD */
182EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *); 122EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
183EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
184
185/* EC_GROUP_new_by_curve_name() creates a EC_GROUP structure
186 * specified by a curve name (in form of a NID) */
187EC_GROUP *EC_GROUP_new_by_curve_name(int nid);
188/* handling of internal curves */
189typedef struct {
190 int nid;
191 const char *comment;
192 } EC_builtin_curve;
193/* EC_builtin_curves(EC_builtin_curve *r, size_t size) returns number
194 * of all available curves or zero if a error occurred.
195 * In case r ist not zero nitems EC_builtin_curve structures
196 * are filled with the data of the first nitems internal groups */
197size_t EC_get_builtin_curves(EC_builtin_curve *r, size_t nitems);
198 123
199 124int EC_GROUP_set_generator(EC_GROUP *, const EC_POINT *generator, const BIGNUM *order, const BIGNUM *cofactor);
200/* EC_POINT functions */ 125EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *);
126int EC_GROUP_get_order(const EC_GROUP *, BIGNUM *order, BN_CTX *);
127int EC_GROUP_get_cofactor(const EC_GROUP *, BIGNUM *cofactor, BN_CTX *);
201 128
202EC_POINT *EC_POINT_new(const EC_GROUP *); 129EC_POINT *EC_POINT_new(const EC_GROUP *);
203void EC_POINT_free(EC_POINT *); 130void EC_POINT_free(EC_POINT *);
204void EC_POINT_clear_free(EC_POINT *); 131void EC_POINT_clear_free(EC_POINT *);
205int EC_POINT_copy(EC_POINT *, const EC_POINT *); 132int EC_POINT_copy(EC_POINT *, const EC_POINT *);
206EC_POINT *EC_POINT_dup(const EC_POINT *, const EC_GROUP *);
207 133
208const EC_METHOD *EC_POINT_method_of(const EC_POINT *); 134const EC_METHOD *EC_POINT_method_of(const EC_POINT *);
209 135
@@ -219,28 +145,11 @@ int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *, const EC_POINT *,
219int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *, EC_POINT *, 145int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *, EC_POINT *,
220 const BIGNUM *x, int y_bit, BN_CTX *); 146 const BIGNUM *x, int y_bit, BN_CTX *);
221 147
222int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *, EC_POINT *,
223 const BIGNUM *x, const BIGNUM *y, BN_CTX *);
224int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *, const EC_POINT *,
225 BIGNUM *x, BIGNUM *y, BN_CTX *);
226int EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP *, EC_POINT *,
227 const BIGNUM *x, int y_bit, BN_CTX *);
228
229size_t EC_POINT_point2oct(const EC_GROUP *, const EC_POINT *, point_conversion_form_t form, 148size_t EC_POINT_point2oct(const EC_GROUP *, const EC_POINT *, point_conversion_form_t form,
230 unsigned char *buf, size_t len, BN_CTX *); 149 unsigned char *buf, size_t len, BN_CTX *);
231int EC_POINT_oct2point(const EC_GROUP *, EC_POINT *, 150int EC_POINT_oct2point(const EC_GROUP *, EC_POINT *,
232 const unsigned char *buf, size_t len, BN_CTX *); 151 const unsigned char *buf, size_t len, BN_CTX *);
233 152
234/* other interfaces to point2oct/oct2point: */
235BIGNUM *EC_POINT_point2bn(const EC_GROUP *, const EC_POINT *,
236 point_conversion_form_t form, BIGNUM *, BN_CTX *);
237EC_POINT *EC_POINT_bn2point(const EC_GROUP *, const BIGNUM *,
238 EC_POINT *, BN_CTX *);
239char *EC_POINT_point2hex(const EC_GROUP *, const EC_POINT *,
240 point_conversion_form_t form, BN_CTX *);
241EC_POINT *EC_POINT_hex2point(const EC_GROUP *, const char *,
242 EC_POINT *, BN_CTX *);
243
244int EC_POINT_add(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *); 153int EC_POINT_add(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *);
245int EC_POINT_dbl(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, BN_CTX *); 154int EC_POINT_dbl(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, BN_CTX *);
246int EC_POINT_invert(const EC_GROUP *, EC_POINT *, BN_CTX *); 155int EC_POINT_invert(const EC_GROUP *, EC_POINT *, BN_CTX *);
@@ -255,112 +164,9 @@ int EC_POINTs_make_affine(const EC_GROUP *, size_t num, EC_POINT *[], BN_CTX *);
255 164
256int EC_POINTs_mul(const EC_GROUP *, EC_POINT *r, const BIGNUM *, size_t num, const EC_POINT *[], const BIGNUM *[], BN_CTX *); 165int EC_POINTs_mul(const EC_GROUP *, EC_POINT *r, const BIGNUM *, size_t num, const EC_POINT *[], const BIGNUM *[], BN_CTX *);
257int EC_POINT_mul(const EC_GROUP *, EC_POINT *r, const BIGNUM *, const EC_POINT *, const BIGNUM *, BN_CTX *); 166int EC_POINT_mul(const EC_GROUP *, EC_POINT *r, const BIGNUM *, const EC_POINT *, const BIGNUM *, BN_CTX *);
258
259/* EC_GROUP_precompute_mult() stores multiples of generator for faster point multiplication */
260int EC_GROUP_precompute_mult(EC_GROUP *, BN_CTX *); 167int EC_GROUP_precompute_mult(EC_GROUP *, BN_CTX *);
261/* EC_GROUP_have_precompute_mult() reports whether such precomputation has been done */
262int EC_GROUP_have_precompute_mult(const EC_GROUP *);
263
264
265 168
266/* ASN1 stuff */
267 169
268/* EC_GROUP_get_basis_type() returns the NID of the basis type
269 * used to represent the field elements */
270int EC_GROUP_get_basis_type(const EC_GROUP *);
271int EC_GROUP_get_trinomial_basis(const EC_GROUP *, unsigned int *k);
272int EC_GROUP_get_pentanomial_basis(const EC_GROUP *, unsigned int *k1,
273 unsigned int *k2, unsigned int *k3);
274
275#define OPENSSL_EC_NAMED_CURVE 0x001
276
277typedef struct ecpk_parameters_st ECPKPARAMETERS;
278
279EC_GROUP *d2i_ECPKParameters(EC_GROUP **, const unsigned char **in, long len);
280int i2d_ECPKParameters(const EC_GROUP *, unsigned char **out);
281
282#define d2i_ECPKParameters_bio(bp,x) ASN1_d2i_bio_of(EC_GROUP,NULL,d2i_ECPKParameters,bp,x)
283#define i2d_ECPKParameters_bio(bp,x) ASN1_i2d_bio_of_const(EC_GROUP,i2d_ECPKParameters,bp,x)
284#define d2i_ECPKParameters_fp(fp,x) (EC_GROUP *)ASN1_d2i_fp(NULL, \
285 (char *(*)())d2i_ECPKParameters,(fp),(unsigned char **)(x))
286#define i2d_ECPKParameters_fp(fp,x) ASN1_i2d_fp(i2d_ECPKParameters,(fp), \
287 (unsigned char *)(x))
288
289#ifndef OPENSSL_NO_BIO
290int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off);
291#endif
292#ifndef OPENSSL_NO_FP_API
293int ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off);
294#endif
295
296/* the EC_KEY stuff */
297typedef struct ec_key_st EC_KEY;
298
299/* some values for the encoding_flag */
300#define EC_PKEY_NO_PARAMETERS 0x001
301#define EC_PKEY_NO_PUBKEY 0x002
302
303EC_KEY *EC_KEY_new(void);
304EC_KEY *EC_KEY_new_by_curve_name(int nid);
305void EC_KEY_free(EC_KEY *);
306EC_KEY *EC_KEY_copy(EC_KEY *, const EC_KEY *);
307EC_KEY *EC_KEY_dup(const EC_KEY *);
308
309int EC_KEY_up_ref(EC_KEY *);
310
311const EC_GROUP *EC_KEY_get0_group(const EC_KEY *);
312int EC_KEY_set_group(EC_KEY *, const EC_GROUP *);
313const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *);
314int EC_KEY_set_private_key(EC_KEY *, const BIGNUM *);
315const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *);
316int EC_KEY_set_public_key(EC_KEY *, const EC_POINT *);
317unsigned EC_KEY_get_enc_flags(const EC_KEY *);
318void EC_KEY_set_enc_flags(EC_KEY *, unsigned int);
319point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *);
320void EC_KEY_set_conv_form(EC_KEY *, point_conversion_form_t);
321/* functions to set/get method specific data */
322void *EC_KEY_get_key_method_data(EC_KEY *,
323 void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *));
324void EC_KEY_insert_key_method_data(EC_KEY *, void *data,
325 void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *));
326/* wrapper functions for the underlying EC_GROUP object */
327void EC_KEY_set_asn1_flag(EC_KEY *, int);
328int EC_KEY_precompute_mult(EC_KEY *, BN_CTX *ctx);
329
330/* EC_KEY_generate_key() creates a ec private (public) key */
331int EC_KEY_generate_key(EC_KEY *);
332/* EC_KEY_check_key() */
333int EC_KEY_check_key(const EC_KEY *);
334
335/* de- and encoding functions for SEC1 ECPrivateKey */
336EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len);
337int i2d_ECPrivateKey(EC_KEY *a, unsigned char **out);
338/* de- and encoding functions for EC parameters */
339EC_KEY *d2i_ECParameters(EC_KEY **a, const unsigned char **in, long len);
340int i2d_ECParameters(EC_KEY *a, unsigned char **out);
341/* de- and encoding functions for EC public key
342 * (octet string, not DER -- hence 'o2i' and 'i2o') */
343EC_KEY *o2i_ECPublicKey(EC_KEY **a, const unsigned char **in, long len);
344int i2o_ECPublicKey(EC_KEY *a, unsigned char **out);
345
346#ifndef OPENSSL_NO_BIO
347int ECParameters_print(BIO *bp, const EC_KEY *x);
348int EC_KEY_print(BIO *bp, const EC_KEY *x, int off);
349#endif
350#ifndef OPENSSL_NO_FP_API
351int ECParameters_print_fp(FILE *fp, const EC_KEY *x);
352int EC_KEY_print_fp(FILE *fp, const EC_KEY *x, int off);
353#endif
354
355#define ECParameters_dup(x) ASN1_dup_of(EC_KEY,i2d_ECParameters,d2i_ECParameters,x)
356
357#ifndef __cplusplus
358#if defined(__SUNPRO_C)
359# if __SUNPRO_C >= 0x520
360# pragma error_messages (default,E_ARRAY_OF_INCOMPLETE_NONAME,E_ARRAY_OF_INCOMPLETE)
361# endif
362# endif
363#endif
364 170
365/* BEGIN ERROR CODES */ 171/* BEGIN ERROR CODES */
366/* The following lines are auto generated by the script mkerr.pl. Any changes 172/* The following lines are auto generated by the script mkerr.pl. Any changes
@@ -372,124 +178,51 @@ void ERR_load_EC_strings(void);
372 178
373/* Function codes. */ 179/* Function codes. */
374#define EC_F_COMPUTE_WNAF 143 180#define EC_F_COMPUTE_WNAF 143
375#define EC_F_D2I_ECPARAMETERS 144
376#define EC_F_D2I_ECPKPARAMETERS 145
377#define EC_F_D2I_ECPRIVATEKEY 146
378#define EC_F_ECPARAMETERS_PRINT 147
379#define EC_F_ECPARAMETERS_PRINT_FP 148
380#define EC_F_ECPKPARAMETERS_PRINT 149
381#define EC_F_ECPKPARAMETERS_PRINT_FP 150
382#define EC_F_ECP_NIST_MOD_192 203
383#define EC_F_ECP_NIST_MOD_224 204
384#define EC_F_ECP_NIST_MOD_256 205
385#define EC_F_ECP_NIST_MOD_521 206
386#define EC_F_EC_ASN1_GROUP2CURVE 153
387#define EC_F_EC_ASN1_GROUP2FIELDID 154
388#define EC_F_EC_ASN1_GROUP2PARAMETERS 155
389#define EC_F_EC_ASN1_GROUP2PKPARAMETERS 156
390#define EC_F_EC_ASN1_PARAMETERS2GROUP 157
391#define EC_F_EC_ASN1_PKPARAMETERS2GROUP 158
392#define EC_F_EC_EX_DATA_SET_DATA 211
393#define EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY 208
394#define EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT 159
395#define EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE 195
396#define EC_F_EC_GF2M_SIMPLE_OCT2POINT 160
397#define EC_F_EC_GF2M_SIMPLE_POINT2OCT 161
398#define EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES 162
399#define EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES 163
400#define EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES 164
401#define EC_F_EC_GFP_MONT_FIELD_DECODE 133 181#define EC_F_EC_GFP_MONT_FIELD_DECODE 133
402#define EC_F_EC_GFP_MONT_FIELD_ENCODE 134 182#define EC_F_EC_GFP_MONT_FIELD_ENCODE 134
403#define EC_F_EC_GFP_MONT_FIELD_MUL 131 183#define EC_F_EC_GFP_MONT_FIELD_MUL 131
404#define EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE 209
405#define EC_F_EC_GFP_MONT_FIELD_SQR 132 184#define EC_F_EC_GFP_MONT_FIELD_SQR 132
406#define EC_F_EC_GFP_MONT_GROUP_SET_CURVE 189
407#define EC_F_EC_GFP_MONT_GROUP_SET_CURVE_GFP 135
408#define EC_F_EC_GFP_NIST_FIELD_MUL 200
409#define EC_F_EC_GFP_NIST_FIELD_SQR 201
410#define EC_F_EC_GFP_NIST_GROUP_SET_CURVE 202
411#define EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT 165
412#define EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE 166
413#define EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP 100 185#define EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP 100
414#define EC_F_EC_GFP_SIMPLE_GROUP_SET_GENERATOR 101 186#define EC_F_EC_GFP_SIMPLE_GROUP_SET_GENERATOR 101
415#define EC_F_EC_GFP_SIMPLE_MAKE_AFFINE 102 187#define EC_F_EC_GFP_SIMPLE_MAKE_AFFINE 102
416#define EC_F_EC_GFP_SIMPLE_OCT2POINT 103 188#define EC_F_EC_GFP_SIMPLE_OCT2POINT 103
417#define EC_F_EC_GFP_SIMPLE_POINT2OCT 104 189#define EC_F_EC_GFP_SIMPLE_POINT2OCT 104
418#define EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE 137 190#define EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE 137
419#define EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES 167
420#define EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES_GFP 105 191#define EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES_GFP 105
421#define EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES 168
422#define EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES_GFP 128 192#define EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES_GFP 128
423#define EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES 169
424#define EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES_GFP 129 193#define EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES_GFP 129
425#define EC_F_EC_GROUP_CHECK 170
426#define EC_F_EC_GROUP_CHECK_DISCRIMINANT 171
427#define EC_F_EC_GROUP_COPY 106 194#define EC_F_EC_GROUP_COPY 106
428#define EC_F_EC_GROUP_GET0_GENERATOR 139 195#define EC_F_EC_GROUP_GET0_GENERATOR 139
429#define EC_F_EC_GROUP_GET_COFACTOR 140 196#define EC_F_EC_GROUP_GET_COFACTOR 140
430#define EC_F_EC_GROUP_GET_CURVE_GF2M 172
431#define EC_F_EC_GROUP_GET_CURVE_GFP 130 197#define EC_F_EC_GROUP_GET_CURVE_GFP 130
432#define EC_F_EC_GROUP_GET_DEGREE 173
433#define EC_F_EC_GROUP_GET_ORDER 141 198#define EC_F_EC_GROUP_GET_ORDER 141
434#define EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS 193
435#define EC_F_EC_GROUP_GET_TRINOMIAL_BASIS 194
436#define EC_F_EC_GROUP_NEW 108 199#define EC_F_EC_GROUP_NEW 108
437#define EC_F_EC_GROUP_NEW_BY_CURVE_NAME 174
438#define EC_F_EC_GROUP_NEW_FROM_DATA 175
439#define EC_F_EC_GROUP_PRECOMPUTE_MULT 142 200#define EC_F_EC_GROUP_PRECOMPUTE_MULT 142
440#define EC_F_EC_GROUP_SET_CURVE_GF2M 176
441#define EC_F_EC_GROUP_SET_CURVE_GFP 109 201#define EC_F_EC_GROUP_SET_CURVE_GFP 109
442#define EC_F_EC_GROUP_SET_EXTRA_DATA 110 202#define EC_F_EC_GROUP_SET_EXTRA_DATA 110
443#define EC_F_EC_GROUP_SET_GENERATOR 111 203#define EC_F_EC_GROUP_SET_GENERATOR 111
444#define EC_F_EC_KEY_CHECK_KEY 177
445#define EC_F_EC_KEY_COPY 178
446#define EC_F_EC_KEY_GENERATE_KEY 179
447#define EC_F_EC_KEY_NEW 182
448#define EC_F_EC_KEY_PRINT 180
449#define EC_F_EC_KEY_PRINT_FP 181
450#define EC_F_EC_POINTS_MAKE_AFFINE 136 204#define EC_F_EC_POINTS_MAKE_AFFINE 136
451#define EC_F_EC_POINTS_MUL 138 205#define EC_F_EC_POINTS_MUL 138
452#define EC_F_EC_POINT_ADD 112 206#define EC_F_EC_POINT_ADD 112
453#define EC_F_EC_POINT_CMP 113 207#define EC_F_EC_POINT_CMP 113
454#define EC_F_EC_POINT_COPY 114 208#define EC_F_EC_POINT_COPY 114
455#define EC_F_EC_POINT_DBL 115 209#define EC_F_EC_POINT_DBL 115
456#define EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M 183
457#define EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP 116 210#define EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP 116
458#define EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP 117 211#define EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP 117
459#define EC_F_EC_POINT_INVERT 210
460#define EC_F_EC_POINT_IS_AT_INFINITY 118 212#define EC_F_EC_POINT_IS_AT_INFINITY 118
461#define EC_F_EC_POINT_IS_ON_CURVE 119 213#define EC_F_EC_POINT_IS_ON_CURVE 119
462#define EC_F_EC_POINT_MAKE_AFFINE 120 214#define EC_F_EC_POINT_MAKE_AFFINE 120
463#define EC_F_EC_POINT_MUL 184
464#define EC_F_EC_POINT_NEW 121 215#define EC_F_EC_POINT_NEW 121
465#define EC_F_EC_POINT_OCT2POINT 122 216#define EC_F_EC_POINT_OCT2POINT 122
466#define EC_F_EC_POINT_POINT2OCT 123 217#define EC_F_EC_POINT_POINT2OCT 123
467#define EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M 185
468#define EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP 124 218#define EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP 124
469#define EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M 186
470#define EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP 125 219#define EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP 125
471#define EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP 126 220#define EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP 126
472#define EC_F_EC_POINT_SET_TO_INFINITY 127 221#define EC_F_EC_POINT_SET_TO_INFINITY 127
473#define EC_F_EC_PRE_COMP_DUP 207 222#define EC_F_GFP_MONT_GROUP_SET_CURVE_GFP 135
474#define EC_F_EC_PRE_COMP_NEW 196
475#define EC_F_EC_WNAF_MUL 187
476#define EC_F_EC_WNAF_PRECOMPUTE_MULT 188
477#define EC_F_I2D_ECPARAMETERS 190
478#define EC_F_I2D_ECPKPARAMETERS 191
479#define EC_F_I2D_ECPRIVATEKEY 192
480#define EC_F_I2O_ECPUBLICKEY 151
481#define EC_F_O2I_ECPUBLICKEY 152
482 223
483/* Reason codes. */ 224/* Reason codes. */
484#define EC_R_ASN1_ERROR 115
485#define EC_R_ASN1_UNKNOWN_FIELD 116
486#define EC_R_BUFFER_TOO_SMALL 100 225#define EC_R_BUFFER_TOO_SMALL 100
487#define EC_R_D2I_ECPKPARAMETERS_FAILURE 117
488#define EC_R_DISCRIMINANT_IS_ZERO 118
489#define EC_R_EC_GROUP_NEW_BY_NAME_FAILURE 119
490#define EC_R_FIELD_TOO_LARGE 138
491#define EC_R_GROUP2PKPARAMETERS_FAILURE 120
492#define EC_R_I2D_ECPKPARAMETERS_FAILURE 121
493#define EC_R_INCOMPATIBLE_OBJECTS 101 226#define EC_R_INCOMPATIBLE_OBJECTS 101
494#define EC_R_INVALID_ARGUMENT 112 227#define EC_R_INVALID_ARGUMENT 112
495#define EC_R_INVALID_COMPRESSED_POINT 110 228#define EC_R_INVALID_COMPRESSED_POINT 110
@@ -497,28 +230,12 @@ void ERR_load_EC_strings(void);
497#define EC_R_INVALID_ENCODING 102 230#define EC_R_INVALID_ENCODING 102
498#define EC_R_INVALID_FIELD 103 231#define EC_R_INVALID_FIELD 103
499#define EC_R_INVALID_FORM 104 232#define EC_R_INVALID_FORM 104
500#define EC_R_INVALID_GROUP_ORDER 122
501#define EC_R_INVALID_PENTANOMIAL_BASIS 132
502#define EC_R_INVALID_PRIVATE_KEY 123
503#define EC_R_INVALID_TRINOMIAL_BASIS 137
504#define EC_R_MISSING_PARAMETERS 124
505#define EC_R_MISSING_PRIVATE_KEY 125
506#define EC_R_NOT_A_NIST_PRIME 135
507#define EC_R_NOT_A_SUPPORTED_NIST_PRIME 136
508#define EC_R_NOT_IMPLEMENTED 126
509#define EC_R_NOT_INITIALIZED 111 233#define EC_R_NOT_INITIALIZED 111
510#define EC_R_NO_FIELD_MOD 133
511#define EC_R_PASSED_NULL_PARAMETER 134
512#define EC_R_PKPARAMETERS2GROUP_FAILURE 127
513#define EC_R_POINT_AT_INFINITY 106 234#define EC_R_POINT_AT_INFINITY 106
514#define EC_R_POINT_IS_NOT_ON_CURVE 107 235#define EC_R_POINT_IS_NOT_ON_CURVE 107
515#define EC_R_SLOT_FULL 108 236#define EC_R_SLOT_FULL 108
516#define EC_R_UNDEFINED_GENERATOR 113 237#define EC_R_UNDEFINED_GENERATOR 113
517#define EC_R_UNDEFINED_ORDER 128
518#define EC_R_UNKNOWN_GROUP 129
519#define EC_R_UNKNOWN_ORDER 114 238#define EC_R_UNKNOWN_ORDER 114
520#define EC_R_UNSUPPORTED_FIELD 131
521#define EC_R_WRONG_ORDER 130
522 239
523#ifdef __cplusplus 240#ifdef __cplusplus
524} 241}
diff --git a/src/lib/libcrypto/ec/ec2_smpt.c b/src/lib/libcrypto/ec/ec2_smpt.c
new file mode 100644
index 0000000000..59d52bf663
--- /dev/null
+++ b/src/lib/libcrypto/ec/ec2_smpt.c
@@ -0,0 +1,74 @@
1/* crypto/ec/ec2_smpt.c */
2/* This code was originally written by Douglas Stebila
3 * <dstebila@student.math.uwaterloo.ca> for the OpenSSL project.
4 */
5/* ====================================================================
6 * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * openssl-core@openssl.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59
60/* Calaculates and sets the affine coordinates of an EC_POINT from the given
61 * compressed coordinates. Uses algorithm 2.3.4 of SEC 1.
62 * Note that the simple implementation only uses affine coordinates.
63 *
64 * This algorithm is patented by Certicom Corp. under US Patent 6,141,420
65 * (for licensing information, contact licensing@certicom.com).
66 * This function is disabled by default and can be enabled by defining the
67 * preprocessor macro OPENSSL_EC_BIN_PT_COMP at Configure-time.
68 */
69int ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *point,
70 const BIGNUM *x_, int y_bit, BN_CTX *ctx)
71 {
72 ECerr(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES, ERR_R_DISABLED);
73 return 0;
74 }
diff --git a/src/lib/libcrypto/ec/ec_cvt.c b/src/lib/libcrypto/ec/ec_cvt.c
index d45640bab9..45b0ec33a0 100644
--- a/src/lib/libcrypto/ec/ec_cvt.c
+++ b/src/lib/libcrypto/ec/ec_cvt.c
@@ -1,9 +1,6 @@
1/* crypto/ec/ec_cvt.c */ 1/* crypto/ec/ec_cvt.c */
2/*
3 * Originally written by Bodo Moeller for the OpenSSL project.
4 */
5/* ==================================================================== 2/* ====================================================================
6 * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. 3 * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
7 * 4 *
8 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
@@ -55,21 +52,7 @@
55 * Hudson (tjh@cryptsoft.com). 52 * Hudson (tjh@cryptsoft.com).
56 * 53 *
57 */ 54 */
58/* ====================================================================
59 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
60 *
61 * Portions of the attached software ("Contribution") are developed by
62 * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
63 *
64 * The Contribution is licensed pursuant to the OpenSSL open source
65 * license provided above.
66 *
67 * The elliptic curve binary polynomial software is originally written by
68 * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
69 *
70 */
71 55
72#include <openssl/err.h>
73#include "ec_lcl.h" 56#include "ec_lcl.h"
74 57
75 58
@@ -77,64 +60,17 @@ EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, const BIGNUM
77 { 60 {
78 const EC_METHOD *meth; 61 const EC_METHOD *meth;
79 EC_GROUP *ret; 62 EC_GROUP *ret;
80
81 meth = EC_GFp_nist_method();
82 63
83 ret = EC_GROUP_new(meth); 64 /* Finally, this will use EC_GFp_nist_method if 'p' is a special
84 if (ret == NULL) 65 * prime with optimized modular arithmetics (for NIST curves)
85 return NULL; 66 */
86 67 meth = EC_GFp_mont_method();
87 if (!EC_GROUP_set_curve_GFp(ret, p, a, b, ctx))
88 {
89 unsigned long err;
90
91 err = ERR_peek_last_error();
92
93 if (!(ERR_GET_LIB(err) == ERR_LIB_EC &&
94 ((ERR_GET_REASON(err) == EC_R_NOT_A_NIST_PRIME) ||
95 (ERR_GET_REASON(err) == EC_R_NOT_A_SUPPORTED_NIST_PRIME))))
96 {
97 /* real error */
98
99 EC_GROUP_clear_free(ret);
100 return NULL;
101 }
102
103
104 /* not an actual error, we just cannot use EC_GFp_nist_method */
105
106 ERR_clear_error();
107
108 EC_GROUP_clear_free(ret);
109 meth = EC_GFp_mont_method();
110
111 ret = EC_GROUP_new(meth);
112 if (ret == NULL)
113 return NULL;
114
115 if (!EC_GROUP_set_curve_GFp(ret, p, a, b, ctx))
116 {
117 EC_GROUP_clear_free(ret);
118 return NULL;
119 }
120 }
121
122 return ret;
123 }
124
125
126EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
127 {
128 const EC_METHOD *meth;
129 EC_GROUP *ret;
130
131 meth = EC_GF2m_simple_method();
132 68
133 ret = EC_GROUP_new(meth); 69 ret = EC_GROUP_new(meth);
134 if (ret == NULL) 70 if (ret == NULL)
135 return NULL; 71 return NULL;
136 72
137 if (!EC_GROUP_set_curve_GF2m(ret, p, a, b, ctx)) 73 if (!EC_GROUP_set_curve_GFp(ret, p, a, b, ctx))
138 { 74 {
139 EC_GROUP_clear_free(ret); 75 EC_GROUP_clear_free(ret);
140 return NULL; 76 return NULL;
diff --git a/src/lib/libcrypto/ec/ec_err.c b/src/lib/libcrypto/ec/ec_err.c
index d04c895560..5b70f94382 100644
--- a/src/lib/libcrypto/ec/ec_err.c
+++ b/src/lib/libcrypto/ec/ec_err.c
@@ -1,6 +1,6 @@
1/* crypto/ec/ec_err.c */ 1/* crypto/ec/ec_err.c */
2/* ==================================================================== 2/* ====================================================================
3 * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved. 3 * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
@@ -71,127 +71,54 @@
71static ERR_STRING_DATA EC_str_functs[]= 71static ERR_STRING_DATA EC_str_functs[]=
72 { 72 {
73{ERR_FUNC(EC_F_COMPUTE_WNAF), "COMPUTE_WNAF"}, 73{ERR_FUNC(EC_F_COMPUTE_WNAF), "COMPUTE_WNAF"},
74{ERR_FUNC(EC_F_D2I_ECPARAMETERS), "d2i_ECParameters"},
75{ERR_FUNC(EC_F_D2I_ECPKPARAMETERS), "d2i_ECPKParameters"},
76{ERR_FUNC(EC_F_D2I_ECPRIVATEKEY), "d2i_ECPrivateKey"},
77{ERR_FUNC(EC_F_ECPARAMETERS_PRINT), "ECParameters_print"},
78{ERR_FUNC(EC_F_ECPARAMETERS_PRINT_FP), "ECParameters_print_fp"},
79{ERR_FUNC(EC_F_ECPKPARAMETERS_PRINT), "ECPKParameters_print"},
80{ERR_FUNC(EC_F_ECPKPARAMETERS_PRINT_FP), "ECPKParameters_print_fp"},
81{ERR_FUNC(EC_F_ECP_NIST_MOD_192), "ECP_NIST_MOD_192"},
82{ERR_FUNC(EC_F_ECP_NIST_MOD_224), "ECP_NIST_MOD_224"},
83{ERR_FUNC(EC_F_ECP_NIST_MOD_256), "ECP_NIST_MOD_256"},
84{ERR_FUNC(EC_F_ECP_NIST_MOD_521), "ECP_NIST_MOD_521"},
85{ERR_FUNC(EC_F_EC_ASN1_GROUP2CURVE), "EC_ASN1_GROUP2CURVE"},
86{ERR_FUNC(EC_F_EC_ASN1_GROUP2FIELDID), "EC_ASN1_GROUP2FIELDID"},
87{ERR_FUNC(EC_F_EC_ASN1_GROUP2PARAMETERS), "EC_ASN1_GROUP2PARAMETERS"},
88{ERR_FUNC(EC_F_EC_ASN1_GROUP2PKPARAMETERS), "EC_ASN1_GROUP2PKPARAMETERS"},
89{ERR_FUNC(EC_F_EC_ASN1_PARAMETERS2GROUP), "EC_ASN1_PARAMETERS2GROUP"},
90{ERR_FUNC(EC_F_EC_ASN1_PKPARAMETERS2GROUP), "EC_ASN1_PKPARAMETERS2GROUP"},
91{ERR_FUNC(EC_F_EC_EX_DATA_SET_DATA), "EC_EX_DATA_set_data"},
92{ERR_FUNC(EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY), "EC_GF2M_MONTGOMERY_POINT_MULTIPLY"},
93{ERR_FUNC(EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT), "ec_GF2m_simple_group_check_discriminant"},
94{ERR_FUNC(EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE), "ec_GF2m_simple_group_set_curve"},
95{ERR_FUNC(EC_F_EC_GF2M_SIMPLE_OCT2POINT), "ec_GF2m_simple_oct2point"},
96{ERR_FUNC(EC_F_EC_GF2M_SIMPLE_POINT2OCT), "ec_GF2m_simple_point2oct"},
97{ERR_FUNC(EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES), "ec_GF2m_simple_point_get_affine_coordinates"},
98{ERR_FUNC(EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES), "ec_GF2m_simple_point_set_affine_coordinates"},
99{ERR_FUNC(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES), "ec_GF2m_simple_set_compressed_coordinates"},
100{ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_DECODE), "ec_GFp_mont_field_decode"}, 74{ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_DECODE), "ec_GFp_mont_field_decode"},
101{ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_ENCODE), "ec_GFp_mont_field_encode"}, 75{ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_ENCODE), "ec_GFp_mont_field_encode"},
102{ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_MUL), "ec_GFp_mont_field_mul"}, 76{ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_MUL), "ec_GFp_mont_field_mul"},
103{ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE), "ec_GFp_mont_field_set_to_one"},
104{ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_SQR), "ec_GFp_mont_field_sqr"}, 77{ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_SQR), "ec_GFp_mont_field_sqr"},
105{ERR_FUNC(EC_F_EC_GFP_MONT_GROUP_SET_CURVE), "ec_GFp_mont_group_set_curve"}, 78{ERR_FUNC(EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP), "ec_GFp_simple_group_set_curve_GFp"},
106{ERR_FUNC(EC_F_EC_GFP_MONT_GROUP_SET_CURVE_GFP), "EC_GFP_MONT_GROUP_SET_CURVE_GFP"}, 79{ERR_FUNC(EC_F_EC_GFP_SIMPLE_GROUP_SET_GENERATOR), "ec_GFp_simple_group_set_generator"},
107{ERR_FUNC(EC_F_EC_GFP_NIST_FIELD_MUL), "ec_GFp_nist_field_mul"},
108{ERR_FUNC(EC_F_EC_GFP_NIST_FIELD_SQR), "ec_GFp_nist_field_sqr"},
109{ERR_FUNC(EC_F_EC_GFP_NIST_GROUP_SET_CURVE), "ec_GFp_nist_group_set_curve"},
110{ERR_FUNC(EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT), "ec_GFp_simple_group_check_discriminant"},
111{ERR_FUNC(EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE), "ec_GFp_simple_group_set_curve"},
112{ERR_FUNC(EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP), "EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP"},
113{ERR_FUNC(EC_F_EC_GFP_SIMPLE_GROUP_SET_GENERATOR), "EC_GFP_SIMPLE_GROUP_SET_GENERATOR"},
114{ERR_FUNC(EC_F_EC_GFP_SIMPLE_MAKE_AFFINE), "ec_GFp_simple_make_affine"}, 80{ERR_FUNC(EC_F_EC_GFP_SIMPLE_MAKE_AFFINE), "ec_GFp_simple_make_affine"},
115{ERR_FUNC(EC_F_EC_GFP_SIMPLE_OCT2POINT), "ec_GFp_simple_oct2point"}, 81{ERR_FUNC(EC_F_EC_GFP_SIMPLE_OCT2POINT), "ec_GFp_simple_oct2point"},
116{ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT2OCT), "ec_GFp_simple_point2oct"}, 82{ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT2OCT), "ec_GFp_simple_point2oct"},
117{ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE), "ec_GFp_simple_points_make_affine"}, 83{ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE), "ec_GFp_simple_points_make_affine"},
118{ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES), "ec_GFp_simple_point_get_affine_coordinates"}, 84{ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES_GFP), "ec_GFp_simple_point_get_affine_coordinates_GFp"},
119{ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES_GFP), "EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES_GFP"}, 85{ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES_GFP), "ec_GFp_simple_point_set_affine_coordinates_GFp"},
120{ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES), "ec_GFp_simple_point_set_affine_coordinates"}, 86{ERR_FUNC(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES_GFP), "ec_GFp_simple_set_compressed_coordinates_GFp"},
121{ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES_GFP), "EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES_GFP"},
122{ERR_FUNC(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES), "ec_GFp_simple_set_compressed_coordinates"},
123{ERR_FUNC(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES_GFP), "EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES_GFP"},
124{ERR_FUNC(EC_F_EC_GROUP_CHECK), "EC_GROUP_check"},
125{ERR_FUNC(EC_F_EC_GROUP_CHECK_DISCRIMINANT), "EC_GROUP_check_discriminant"},
126{ERR_FUNC(EC_F_EC_GROUP_COPY), "EC_GROUP_copy"}, 87{ERR_FUNC(EC_F_EC_GROUP_COPY), "EC_GROUP_copy"},
127{ERR_FUNC(EC_F_EC_GROUP_GET0_GENERATOR), "EC_GROUP_get0_generator"}, 88{ERR_FUNC(EC_F_EC_GROUP_GET0_GENERATOR), "EC_GROUP_get0_generator"},
128{ERR_FUNC(EC_F_EC_GROUP_GET_COFACTOR), "EC_GROUP_get_cofactor"}, 89{ERR_FUNC(EC_F_EC_GROUP_GET_COFACTOR), "EC_GROUP_get_cofactor"},
129{ERR_FUNC(EC_F_EC_GROUP_GET_CURVE_GF2M), "EC_GROUP_get_curve_GF2m"},
130{ERR_FUNC(EC_F_EC_GROUP_GET_CURVE_GFP), "EC_GROUP_get_curve_GFp"}, 90{ERR_FUNC(EC_F_EC_GROUP_GET_CURVE_GFP), "EC_GROUP_get_curve_GFp"},
131{ERR_FUNC(EC_F_EC_GROUP_GET_DEGREE), "EC_GROUP_get_degree"},
132{ERR_FUNC(EC_F_EC_GROUP_GET_ORDER), "EC_GROUP_get_order"}, 91{ERR_FUNC(EC_F_EC_GROUP_GET_ORDER), "EC_GROUP_get_order"},
133{ERR_FUNC(EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS), "EC_GROUP_get_pentanomial_basis"},
134{ERR_FUNC(EC_F_EC_GROUP_GET_TRINOMIAL_BASIS), "EC_GROUP_get_trinomial_basis"},
135{ERR_FUNC(EC_F_EC_GROUP_NEW), "EC_GROUP_new"}, 92{ERR_FUNC(EC_F_EC_GROUP_NEW), "EC_GROUP_new"},
136{ERR_FUNC(EC_F_EC_GROUP_NEW_BY_CURVE_NAME), "EC_GROUP_new_by_curve_name"},
137{ERR_FUNC(EC_F_EC_GROUP_NEW_FROM_DATA), "EC_GROUP_NEW_FROM_DATA"},
138{ERR_FUNC(EC_F_EC_GROUP_PRECOMPUTE_MULT), "EC_GROUP_precompute_mult"}, 93{ERR_FUNC(EC_F_EC_GROUP_PRECOMPUTE_MULT), "EC_GROUP_precompute_mult"},
139{ERR_FUNC(EC_F_EC_GROUP_SET_CURVE_GF2M), "EC_GROUP_set_curve_GF2m"},
140{ERR_FUNC(EC_F_EC_GROUP_SET_CURVE_GFP), "EC_GROUP_set_curve_GFp"}, 94{ERR_FUNC(EC_F_EC_GROUP_SET_CURVE_GFP), "EC_GROUP_set_curve_GFp"},
141{ERR_FUNC(EC_F_EC_GROUP_SET_EXTRA_DATA), "EC_GROUP_SET_EXTRA_DATA"}, 95{ERR_FUNC(EC_F_EC_GROUP_SET_EXTRA_DATA), "EC_GROUP_set_extra_data"},
142{ERR_FUNC(EC_F_EC_GROUP_SET_GENERATOR), "EC_GROUP_set_generator"}, 96{ERR_FUNC(EC_F_EC_GROUP_SET_GENERATOR), "EC_GROUP_set_generator"},
143{ERR_FUNC(EC_F_EC_KEY_CHECK_KEY), "EC_KEY_check_key"},
144{ERR_FUNC(EC_F_EC_KEY_COPY), "EC_KEY_copy"},
145{ERR_FUNC(EC_F_EC_KEY_GENERATE_KEY), "EC_KEY_generate_key"},
146{ERR_FUNC(EC_F_EC_KEY_NEW), "EC_KEY_new"},
147{ERR_FUNC(EC_F_EC_KEY_PRINT), "EC_KEY_print"},
148{ERR_FUNC(EC_F_EC_KEY_PRINT_FP), "EC_KEY_print_fp"},
149{ERR_FUNC(EC_F_EC_POINTS_MAKE_AFFINE), "EC_POINTs_make_affine"}, 97{ERR_FUNC(EC_F_EC_POINTS_MAKE_AFFINE), "EC_POINTs_make_affine"},
150{ERR_FUNC(EC_F_EC_POINTS_MUL), "EC_POINTs_mul"}, 98{ERR_FUNC(EC_F_EC_POINTS_MUL), "EC_POINTs_mul"},
151{ERR_FUNC(EC_F_EC_POINT_ADD), "EC_POINT_add"}, 99{ERR_FUNC(EC_F_EC_POINT_ADD), "EC_POINT_add"},
152{ERR_FUNC(EC_F_EC_POINT_CMP), "EC_POINT_cmp"}, 100{ERR_FUNC(EC_F_EC_POINT_CMP), "EC_POINT_cmp"},
153{ERR_FUNC(EC_F_EC_POINT_COPY), "EC_POINT_copy"}, 101{ERR_FUNC(EC_F_EC_POINT_COPY), "EC_POINT_copy"},
154{ERR_FUNC(EC_F_EC_POINT_DBL), "EC_POINT_dbl"}, 102{ERR_FUNC(EC_F_EC_POINT_DBL), "EC_POINT_dbl"},
155{ERR_FUNC(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M), "EC_POINT_get_affine_coordinates_GF2m"},
156{ERR_FUNC(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP), "EC_POINT_get_affine_coordinates_GFp"}, 103{ERR_FUNC(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP), "EC_POINT_get_affine_coordinates_GFp"},
157{ERR_FUNC(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP), "EC_POINT_get_Jprojective_coordinates_GFp"}, 104{ERR_FUNC(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP), "EC_POINT_get_Jprojective_coordinates_GFp"},
158{ERR_FUNC(EC_F_EC_POINT_INVERT), "EC_POINT_invert"},
159{ERR_FUNC(EC_F_EC_POINT_IS_AT_INFINITY), "EC_POINT_is_at_infinity"}, 105{ERR_FUNC(EC_F_EC_POINT_IS_AT_INFINITY), "EC_POINT_is_at_infinity"},
160{ERR_FUNC(EC_F_EC_POINT_IS_ON_CURVE), "EC_POINT_is_on_curve"}, 106{ERR_FUNC(EC_F_EC_POINT_IS_ON_CURVE), "EC_POINT_is_on_curve"},
161{ERR_FUNC(EC_F_EC_POINT_MAKE_AFFINE), "EC_POINT_make_affine"}, 107{ERR_FUNC(EC_F_EC_POINT_MAKE_AFFINE), "EC_POINT_make_affine"},
162{ERR_FUNC(EC_F_EC_POINT_MUL), "EC_POINT_mul"},
163{ERR_FUNC(EC_F_EC_POINT_NEW), "EC_POINT_new"}, 108{ERR_FUNC(EC_F_EC_POINT_NEW), "EC_POINT_new"},
164{ERR_FUNC(EC_F_EC_POINT_OCT2POINT), "EC_POINT_oct2point"}, 109{ERR_FUNC(EC_F_EC_POINT_OCT2POINT), "EC_POINT_oct2point"},
165{ERR_FUNC(EC_F_EC_POINT_POINT2OCT), "EC_POINT_point2oct"}, 110{ERR_FUNC(EC_F_EC_POINT_POINT2OCT), "EC_POINT_point2oct"},
166{ERR_FUNC(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M), "EC_POINT_set_affine_coordinates_GF2m"},
167{ERR_FUNC(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP), "EC_POINT_set_affine_coordinates_GFp"}, 111{ERR_FUNC(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP), "EC_POINT_set_affine_coordinates_GFp"},
168{ERR_FUNC(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M), "EC_POINT_set_compressed_coordinates_GF2m"},
169{ERR_FUNC(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP), "EC_POINT_set_compressed_coordinates_GFp"}, 112{ERR_FUNC(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP), "EC_POINT_set_compressed_coordinates_GFp"},
170{ERR_FUNC(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP), "EC_POINT_set_Jprojective_coordinates_GFp"}, 113{ERR_FUNC(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP), "EC_POINT_set_Jprojective_coordinates_GFp"},
171{ERR_FUNC(EC_F_EC_POINT_SET_TO_INFINITY), "EC_POINT_set_to_infinity"}, 114{ERR_FUNC(EC_F_EC_POINT_SET_TO_INFINITY), "EC_POINT_set_to_infinity"},
172{ERR_FUNC(EC_F_EC_PRE_COMP_DUP), "EC_PRE_COMP_DUP"}, 115{ERR_FUNC(EC_F_GFP_MONT_GROUP_SET_CURVE_GFP), "GFP_MONT_GROUP_SET_CURVE_GFP"},
173{ERR_FUNC(EC_F_EC_PRE_COMP_NEW), "EC_PRE_COMP_NEW"},
174{ERR_FUNC(EC_F_EC_WNAF_MUL), "ec_wNAF_mul"},
175{ERR_FUNC(EC_F_EC_WNAF_PRECOMPUTE_MULT), "ec_wNAF_precompute_mult"},
176{ERR_FUNC(EC_F_I2D_ECPARAMETERS), "i2d_ECParameters"},
177{ERR_FUNC(EC_F_I2D_ECPKPARAMETERS), "i2d_ECPKParameters"},
178{ERR_FUNC(EC_F_I2D_ECPRIVATEKEY), "i2d_ECPrivateKey"},
179{ERR_FUNC(EC_F_I2O_ECPUBLICKEY), "i2o_ECPublicKey"},
180{ERR_FUNC(EC_F_O2I_ECPUBLICKEY), "o2i_ECPublicKey"},
181{0,NULL} 116{0,NULL}
182 }; 117 };
183 118
184static ERR_STRING_DATA EC_str_reasons[]= 119static ERR_STRING_DATA EC_str_reasons[]=
185 { 120 {
186{ERR_REASON(EC_R_ASN1_ERROR) ,"asn1 error"},
187{ERR_REASON(EC_R_ASN1_UNKNOWN_FIELD) ,"asn1 unknown field"},
188{ERR_REASON(EC_R_BUFFER_TOO_SMALL) ,"buffer too small"}, 121{ERR_REASON(EC_R_BUFFER_TOO_SMALL) ,"buffer too small"},
189{ERR_REASON(EC_R_D2I_ECPKPARAMETERS_FAILURE),"d2i ecpkparameters failure"},
190{ERR_REASON(EC_R_DISCRIMINANT_IS_ZERO) ,"discriminant is zero"},
191{ERR_REASON(EC_R_EC_GROUP_NEW_BY_NAME_FAILURE),"ec group new by name failure"},
192{ERR_REASON(EC_R_FIELD_TOO_LARGE) ,"field too large"},
193{ERR_REASON(EC_R_GROUP2PKPARAMETERS_FAILURE),"group2pkparameters failure"},
194{ERR_REASON(EC_R_I2D_ECPKPARAMETERS_FAILURE),"i2d ecpkparameters failure"},
195{ERR_REASON(EC_R_INCOMPATIBLE_OBJECTS) ,"incompatible objects"}, 122{ERR_REASON(EC_R_INCOMPATIBLE_OBJECTS) ,"incompatible objects"},
196{ERR_REASON(EC_R_INVALID_ARGUMENT) ,"invalid argument"}, 123{ERR_REASON(EC_R_INVALID_ARGUMENT) ,"invalid argument"},
197{ERR_REASON(EC_R_INVALID_COMPRESSED_POINT),"invalid compressed point"}, 124{ERR_REASON(EC_R_INVALID_COMPRESSED_POINT),"invalid compressed point"},
@@ -199,28 +126,12 @@ static ERR_STRING_DATA EC_str_reasons[]=
199{ERR_REASON(EC_R_INVALID_ENCODING) ,"invalid encoding"}, 126{ERR_REASON(EC_R_INVALID_ENCODING) ,"invalid encoding"},
200{ERR_REASON(EC_R_INVALID_FIELD) ,"invalid field"}, 127{ERR_REASON(EC_R_INVALID_FIELD) ,"invalid field"},
201{ERR_REASON(EC_R_INVALID_FORM) ,"invalid form"}, 128{ERR_REASON(EC_R_INVALID_FORM) ,"invalid form"},
202{ERR_REASON(EC_R_INVALID_GROUP_ORDER) ,"invalid group order"},
203{ERR_REASON(EC_R_INVALID_PENTANOMIAL_BASIS),"invalid pentanomial basis"},
204{ERR_REASON(EC_R_INVALID_PRIVATE_KEY) ,"invalid private key"},
205{ERR_REASON(EC_R_INVALID_TRINOMIAL_BASIS),"invalid trinomial basis"},
206{ERR_REASON(EC_R_MISSING_PARAMETERS) ,"missing parameters"},
207{ERR_REASON(EC_R_MISSING_PRIVATE_KEY) ,"missing private key"},
208{ERR_REASON(EC_R_NOT_A_NIST_PRIME) ,"not a NIST prime"},
209{ERR_REASON(EC_R_NOT_A_SUPPORTED_NIST_PRIME),"not a supported NIST prime"},
210{ERR_REASON(EC_R_NOT_IMPLEMENTED) ,"not implemented"},
211{ERR_REASON(EC_R_NOT_INITIALIZED) ,"not initialized"}, 129{ERR_REASON(EC_R_NOT_INITIALIZED) ,"not initialized"},
212{ERR_REASON(EC_R_NO_FIELD_MOD) ,"no field mod"},
213{ERR_REASON(EC_R_PASSED_NULL_PARAMETER) ,"passed null parameter"},
214{ERR_REASON(EC_R_PKPARAMETERS2GROUP_FAILURE),"pkparameters2group failure"},
215{ERR_REASON(EC_R_POINT_AT_INFINITY) ,"point at infinity"}, 130{ERR_REASON(EC_R_POINT_AT_INFINITY) ,"point at infinity"},
216{ERR_REASON(EC_R_POINT_IS_NOT_ON_CURVE) ,"point is not on curve"}, 131{ERR_REASON(EC_R_POINT_IS_NOT_ON_CURVE) ,"point is not on curve"},
217{ERR_REASON(EC_R_SLOT_FULL) ,"slot full"}, 132{ERR_REASON(EC_R_SLOT_FULL) ,"slot full"},
218{ERR_REASON(EC_R_UNDEFINED_GENERATOR) ,"undefined generator"}, 133{ERR_REASON(EC_R_UNDEFINED_GENERATOR) ,"undefined generator"},
219{ERR_REASON(EC_R_UNDEFINED_ORDER) ,"undefined order"},
220{ERR_REASON(EC_R_UNKNOWN_GROUP) ,"unknown group"},
221{ERR_REASON(EC_R_UNKNOWN_ORDER) ,"unknown order"}, 134{ERR_REASON(EC_R_UNKNOWN_ORDER) ,"unknown order"},
222{ERR_REASON(EC_R_UNSUPPORTED_FIELD) ,"unsupported field"},
223{ERR_REASON(EC_R_WRONG_ORDER) ,"wrong order"},
224{0,NULL} 135{0,NULL}
225 }; 136 };
226 137
@@ -228,12 +139,15 @@ static ERR_STRING_DATA EC_str_reasons[]=
228 139
229void ERR_load_EC_strings(void) 140void ERR_load_EC_strings(void)
230 { 141 {
231#ifndef OPENSSL_NO_ERR 142 static int init=1;
232 143
233 if (ERR_func_error_string(EC_str_functs[0].error) == NULL) 144 if (init)
234 { 145 {
146 init=0;
147#ifndef OPENSSL_NO_ERR
235 ERR_load_strings(0,EC_str_functs); 148 ERR_load_strings(0,EC_str_functs);
236 ERR_load_strings(0,EC_str_reasons); 149 ERR_load_strings(0,EC_str_reasons);
237 }
238#endif 150#endif
151
152 }
239 } 153 }
diff --git a/src/lib/libcrypto/ec/ec_lcl.h b/src/lib/libcrypto/ec/ec_lcl.h
index fdd7aa2755..cc4cf27755 100644
--- a/src/lib/libcrypto/ec/ec_lcl.h
+++ b/src/lib/libcrypto/ec/ec_lcl.h
@@ -1,9 +1,6 @@
1/* crypto/ec/ec_lcl.h */ 1/* crypto/ec/ec_lcl.h */
2/*
3 * Originally written by Bodo Moeller for the OpenSSL project.
4 */
5/* ==================================================================== 2/* ====================================================================
6 * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. 3 * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
7 * 4 *
8 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
@@ -55,56 +52,35 @@
55 * Hudson (tjh@cryptsoft.com). 52 * Hudson (tjh@cryptsoft.com).
56 * 53 *
57 */ 54 */
58/* ====================================================================
59 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
60 *
61 * Portions of the attached software ("Contribution") are developed by
62 * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
63 *
64 * The Contribution is licensed pursuant to the OpenSSL open source
65 * license provided above.
66 *
67 * The elliptic curve binary polynomial software is originally written by
68 * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
69 *
70 */
71 55
72 56
73#include <stdlib.h> 57#include <stdlib.h>
74 58
75#include <openssl/obj_mac.h>
76#include <openssl/ec.h> 59#include <openssl/ec.h>
77#include <openssl/bn.h>
78 60
79#if defined(__SUNPRO_C)
80# if __SUNPRO_C >= 0x520
81# pragma error_messages (off,E_ARRAY_OF_INCOMPLETE_NONAME,E_ARRAY_OF_INCOMPLETE)
82# endif
83#endif
84 61
85/* Structure details are not part of the exported interface, 62/* Structure details are not part of the exported interface,
86 * so all this may change in future versions. */ 63 * so all this may change in future versions. */
87 64
88struct ec_method_st { 65struct ec_method_st {
89 /* used by EC_METHOD_get_field_type: */
90 int field_type; /* a NID */
91
92 /* used by EC_GROUP_new, EC_GROUP_free, EC_GROUP_clear_free, EC_GROUP_copy: */ 66 /* used by EC_GROUP_new, EC_GROUP_free, EC_GROUP_clear_free, EC_GROUP_copy: */
93 int (*group_init)(EC_GROUP *); 67 int (*group_init)(EC_GROUP *);
94 void (*group_finish)(EC_GROUP *); 68 void (*group_finish)(EC_GROUP *);
95 void (*group_clear_finish)(EC_GROUP *); 69 void (*group_clear_finish)(EC_GROUP *);
96 int (*group_copy)(EC_GROUP *, const EC_GROUP *); 70 int (*group_copy)(EC_GROUP *, const EC_GROUP *);
97 71
98 /* used by EC_GROUP_set_curve_GFp, EC_GROUP_get_curve_GFp, */ 72 /* used by EC_GROUP_set_curve_GFp and EC_GROUP_get_curve_GFp: */
99 /* EC_GROUP_set_curve_GF2m, and EC_GROUP_get_curve_GF2m: */ 73 int (*group_set_curve_GFp)(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
100 int (*group_set_curve)(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *); 74 int (*group_get_curve_GFp)(const EC_GROUP *, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *);
101 int (*group_get_curve)(const EC_GROUP *, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *);
102 75
103 /* used by EC_GROUP_get_degree: */ 76 /* used by EC_GROUP_set_generator, EC_GROUP_get0_generator,
104 int (*group_get_degree)(const EC_GROUP *); 77 * EC_GROUP_get_order, EC_GROUP_get_cofactor:
105 78 */
106 /* used by EC_GROUP_check: */ 79 int (*group_set_generator)(EC_GROUP *, const EC_POINT *generator,
107 int (*group_check_discriminant)(const EC_GROUP *, BN_CTX *); 80 const BIGNUM *order, const BIGNUM *cofactor);
81 EC_POINT *(*group_get0_generator)(const EC_GROUP *);
82 int (*group_get_order)(const EC_GROUP *, BIGNUM *order, BN_CTX *);
83 int (*group_get_cofactor)(const EC_GROUP *, BIGNUM *cofactor, BN_CTX *);
108 84
109 /* used by EC_POINT_new, EC_POINT_free, EC_POINT_clear_free, EC_POINT_copy: */ 85 /* used by EC_POINT_new, EC_POINT_free, EC_POINT_clear_free, EC_POINT_copy: */
110 int (*point_init)(EC_POINT *); 86 int (*point_init)(EC_POINT *);
@@ -113,22 +89,20 @@ struct ec_method_st {
113 int (*point_copy)(EC_POINT *, const EC_POINT *); 89 int (*point_copy)(EC_POINT *, const EC_POINT *);
114 90
115 /* used by EC_POINT_set_to_infinity, 91 /* used by EC_POINT_set_to_infinity,
116 * EC_POINT_set_Jprojective_coordinates_GFp, 92 * EC_POINT_set_Jprojective_coordinates_GFp, EC_POINT_get_Jprojective_coordinates_GFp,
117 * EC_POINT_get_Jprojective_coordinates_GFp, 93 * EC_POINT_set_affine_coordinates_GFp, EC_POINT_get_affine_coordinates_GFp,
118 * EC_POINT_set_affine_coordinates_GFp, ..._GF2m, 94 * EC_POINT_set_compressed_coordinates_GFp:
119 * EC_POINT_get_affine_coordinates_GFp, ..._GF2m,
120 * EC_POINT_set_compressed_coordinates_GFp, ..._GF2m:
121 */ 95 */
122 int (*point_set_to_infinity)(const EC_GROUP *, EC_POINT *); 96 int (*point_set_to_infinity)(const EC_GROUP *, EC_POINT *);
123 int (*point_set_Jprojective_coordinates_GFp)(const EC_GROUP *, EC_POINT *, 97 int (*point_set_Jprojective_coordinates_GFp)(const EC_GROUP *, EC_POINT *,
124 const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *); 98 const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *);
125 int (*point_get_Jprojective_coordinates_GFp)(const EC_GROUP *, const EC_POINT *, 99 int (*point_get_Jprojective_coordinates_GFp)(const EC_GROUP *, const EC_POINT *,
126 BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *); 100 BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *);
127 int (*point_set_affine_coordinates)(const EC_GROUP *, EC_POINT *, 101 int (*point_set_affine_coordinates_GFp)(const EC_GROUP *, EC_POINT *,
128 const BIGNUM *x, const BIGNUM *y, BN_CTX *); 102 const BIGNUM *x, const BIGNUM *y, BN_CTX *);
129 int (*point_get_affine_coordinates)(const EC_GROUP *, const EC_POINT *, 103 int (*point_get_affine_coordinates_GFp)(const EC_GROUP *, const EC_POINT *,
130 BIGNUM *x, BIGNUM *y, BN_CTX *); 104 BIGNUM *x, BIGNUM *y, BN_CTX *);
131 int (*point_set_compressed_coordinates)(const EC_GROUP *, EC_POINT *, 105 int (*point_set_compressed_coordinates_GFp)(const EC_GROUP *, EC_POINT *,
132 const BIGNUM *x, int y_bit, BN_CTX *); 106 const BIGNUM *x, int y_bit, BN_CTX *);
133 107
134 /* used by EC_POINT_point2oct, EC_POINT_oct2point: */ 108 /* used by EC_POINT_point2oct, EC_POINT_oct2point: */
@@ -151,65 +125,34 @@ struct ec_method_st {
151 int (*make_affine)(const EC_GROUP *, EC_POINT *, BN_CTX *); 125 int (*make_affine)(const EC_GROUP *, EC_POINT *, BN_CTX *);
152 int (*points_make_affine)(const EC_GROUP *, size_t num, EC_POINT *[], BN_CTX *); 126 int (*points_make_affine)(const EC_GROUP *, size_t num, EC_POINT *[], BN_CTX *);
153 127
154 /* used by EC_POINTs_mul, EC_POINT_mul, EC_POINT_precompute_mult, EC_POINT_have_precompute_mult
155 * (default implementations are used if the 'mul' pointer is 0): */
156 int (*mul)(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
157 size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *);
158 int (*precompute_mult)(EC_GROUP *group, BN_CTX *);
159 int (*have_precompute_mult)(const EC_GROUP *group);
160
161 128
162 /* internal functions */ 129 /* internal functions */
163 130
164 /* 'field_mul', 'field_sqr', and 'field_div' can be used by 'add' and 'dbl' so that 131 /* 'field_mul' and 'field_sqr' can be used by 'add' and 'dbl' so that
165 * the same implementations of point operations can be used with different 132 * the same implementations of point operations can be used with different
166 * optimized implementations of expensive field operations: */ 133 * optimized implementations of expensive field operations: */
167 int (*field_mul)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *); 134 int (*field_mul)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
168 int (*field_sqr)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *); 135 int (*field_sqr)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
169 int (*field_div)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
170 136
171 int (*field_encode)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *); /* e.g. to Montgomery */ 137 int (*field_encode)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *); /* e.g. to Montgomery */
172 int (*field_decode)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *); /* e.g. from Montgomery */ 138 int (*field_decode)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *); /* e.g. from Montgomery */
173 int (*field_set_to_one)(const EC_GROUP *, BIGNUM *r, BN_CTX *); 139 int (*field_set_to_one)(const EC_GROUP *, BIGNUM *r, BN_CTX *);
174} /* EC_METHOD */; 140} /* EC_METHOD */;
175 141
176typedef struct ec_extra_data_st {
177 struct ec_extra_data_st *next;
178 void *data;
179 void *(*dup_func)(void *);
180 void (*free_func)(void *);
181 void (*clear_free_func)(void *);
182} EC_EXTRA_DATA; /* used in EC_GROUP */
183 142
184struct ec_group_st { 143struct ec_group_st {
185 const EC_METHOD *meth; 144 const EC_METHOD *meth;
186 145
187 EC_POINT *generator; /* optional */ 146 void *extra_data;
188 BIGNUM order, cofactor; 147 void *(*extra_data_dup_func)(void *);
189 148 void (*extra_data_free_func)(void *);
190 int curve_name;/* optional NID for named curve */ 149 void (*extra_data_clear_free_func)(void *);
191 int asn1_flag; /* flag to control the asn1 encoding */
192 point_conversion_form_t asn1_form;
193
194 unsigned char *seed; /* optional seed for parameters (appears in ASN1) */
195 size_t seed_len;
196 150
197 EC_EXTRA_DATA *extra_data; /* linked list */ 151 /* All members except 'meth' and 'extra_data...' are handled by
198 152 * the method functions, even if they appear generic */
199 /* The following members are handled by the method functions,
200 * even if they appear generic */
201 153
202 BIGNUM field; /* Field specification. 154 BIGNUM field; /* Field specification.
203 * For curves over GF(p), this is the modulus; 155 * For curves over GF(p), this is the modulus. */
204 * for curves over GF(2^m), this is the
205 * irreducible polynomial defining the field.
206 */
207
208 unsigned int poly[5]; /* Field specification for curves over GF(2^m).
209 * The irreducible f(t) is then of the form:
210 * t^poly[0] + t^poly[1] + ... + t^poly[k]
211 * where m = poly[0] > poly[1] > ... > poly[k] = 0.
212 */
213 156
214 BIGNUM a, b; /* Curve coefficients. 157 BIGNUM a, b; /* Curve coefficients.
215 * (Here the assumption is that BIGNUMs can be used 158 * (Here the assumption is that BIGNUMs can be used
@@ -217,49 +160,29 @@ struct ec_group_st {
217 * For characteristic > 3, the curve is defined 160 * For characteristic > 3, the curve is defined
218 * by a Weierstrass equation of the form 161 * by a Weierstrass equation of the form
219 * y^2 = x^3 + a*x + b. 162 * y^2 = x^3 + a*x + b.
220 * For characteristic 2, the curve is defined by
221 * an equation of the form
222 * y^2 + x*y = x^3 + a*x^2 + b.
223 */ 163 */
224
225 int a_is_minus3; /* enable optimized point arithmetics for special case */ 164 int a_is_minus3; /* enable optimized point arithmetics for special case */
226 165
166 EC_POINT *generator; /* optional */
167 BIGNUM order, cofactor;
168
227 void *field_data1; /* method-specific (e.g., Montgomery structure) */ 169 void *field_data1; /* method-specific (e.g., Montgomery structure) */
228 void *field_data2; /* method-specific */ 170 void *field_data2; /* method-specific */
229 int (*field_mod_func)(BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *); /* method-specific */
230} /* EC_GROUP */; 171} /* EC_GROUP */;
231 172
232struct ec_key_st {
233 int version;
234
235 EC_GROUP *group;
236
237 EC_POINT *pub_key;
238 BIGNUM *priv_key;
239
240 unsigned int enc_flag;
241 point_conversion_form_t conv_form;
242 173
243 int references; 174/* Basically a 'mixin' for extra data, but available for EC_GROUPs only
244
245 EC_EXTRA_DATA *method_data;
246} /* EC_KEY */;
247
248/* Basically a 'mixin' for extra data, but available for EC_GROUPs/EC_KEYs only
249 * (with visibility limited to 'package' level for now). 175 * (with visibility limited to 'package' level for now).
250 * We use the function pointers as index for retrieval; this obviates 176 * We use the function pointers as index for retrieval; this obviates
251 * global ex_data-style index tables. 177 * global ex_data-style index tables.
252 */ 178 * (Currently, we have one slot only, but is is possible to extend this
253int EC_EX_DATA_set_data(EC_EXTRA_DATA **, void *data, 179 * if necessary.) */
254 void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *)); 180int EC_GROUP_set_extra_data(EC_GROUP *, void *extra_data, void *(*extra_data_dup_func)(void *),
255void *EC_EX_DATA_get_data(const EC_EXTRA_DATA *, 181 void (*extra_data_free_func)(void *), void (*extra_data_clear_free_func)(void *));
256 void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *)); 182void *EC_GROUP_get_extra_data(const EC_GROUP *, void *(*extra_data_dup_func)(void *),
257void EC_EX_DATA_free_data(EC_EXTRA_DATA **, 183 void (*extra_data_free_func)(void *), void (*extra_data_clear_free_func)(void *));
258 void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *)); 184void EC_GROUP_free_extra_data(EC_GROUP *);
259void EC_EX_DATA_clear_free_data(EC_EXTRA_DATA **, 185void EC_GROUP_clear_free_extra_data(EC_GROUP *);
260 void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *));
261void EC_EX_DATA_free_all_data(EC_EXTRA_DATA **);
262void EC_EX_DATA_clear_free_all_data(EC_EXTRA_DATA **);
263 186
264 187
265 188
@@ -278,23 +201,18 @@ struct ec_point_st {
278 201
279 202
280 203
281/* method functions in ec_mult.c
282 * (ec_lib.c uses these as defaults if group->method->mul is 0) */
283int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
284 size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *);
285int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *);
286int ec_wNAF_have_precompute_mult(const EC_GROUP *group);
287
288
289/* method functions in ecp_smpl.c */ 204/* method functions in ecp_smpl.c */
290int ec_GFp_simple_group_init(EC_GROUP *); 205int ec_GFp_simple_group_init(EC_GROUP *);
291void ec_GFp_simple_group_finish(EC_GROUP *); 206void ec_GFp_simple_group_finish(EC_GROUP *);
292void ec_GFp_simple_group_clear_finish(EC_GROUP *); 207void ec_GFp_simple_group_clear_finish(EC_GROUP *);
293int ec_GFp_simple_group_copy(EC_GROUP *, const EC_GROUP *); 208int ec_GFp_simple_group_copy(EC_GROUP *, const EC_GROUP *);
294int ec_GFp_simple_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *); 209int ec_GFp_simple_group_set_curve_GFp(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
295int ec_GFp_simple_group_get_curve(const EC_GROUP *, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *); 210int ec_GFp_simple_group_get_curve_GFp(const EC_GROUP *, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *);
296int ec_GFp_simple_group_get_degree(const EC_GROUP *); 211int ec_GFp_simple_group_set_generator(EC_GROUP *, const EC_POINT *generator,
297int ec_GFp_simple_group_check_discriminant(const EC_GROUP *, BN_CTX *); 212 const BIGNUM *order, const BIGNUM *cofactor);
213EC_POINT *ec_GFp_simple_group_get0_generator(const EC_GROUP *);
214int ec_GFp_simple_group_get_order(const EC_GROUP *, BIGNUM *order, BN_CTX *);
215int ec_GFp_simple_group_get_cofactor(const EC_GROUP *, BIGNUM *cofactor, BN_CTX *);
298int ec_GFp_simple_point_init(EC_POINT *); 216int ec_GFp_simple_point_init(EC_POINT *);
299void ec_GFp_simple_point_finish(EC_POINT *); 217void ec_GFp_simple_point_finish(EC_POINT *);
300void ec_GFp_simple_point_clear_finish(EC_POINT *); 218void ec_GFp_simple_point_clear_finish(EC_POINT *);
@@ -304,11 +222,11 @@ int ec_GFp_simple_set_Jprojective_coordinates_GFp(const EC_GROUP *, EC_POINT *,
304 const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *); 222 const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *);
305int ec_GFp_simple_get_Jprojective_coordinates_GFp(const EC_GROUP *, const EC_POINT *, 223int ec_GFp_simple_get_Jprojective_coordinates_GFp(const EC_GROUP *, const EC_POINT *,
306 BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *); 224 BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *);
307int ec_GFp_simple_point_set_affine_coordinates(const EC_GROUP *, EC_POINT *, 225int ec_GFp_simple_point_set_affine_coordinates_GFp(const EC_GROUP *, EC_POINT *,
308 const BIGNUM *x, const BIGNUM *y, BN_CTX *); 226 const BIGNUM *x, const BIGNUM *y, BN_CTX *);
309int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *, const EC_POINT *, 227int ec_GFp_simple_point_get_affine_coordinates_GFp(const EC_GROUP *, const EC_POINT *,
310 BIGNUM *x, BIGNUM *y, BN_CTX *); 228 BIGNUM *x, BIGNUM *y, BN_CTX *);
311int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *, EC_POINT *, 229int ec_GFp_simple_set_compressed_coordinates_GFp(const EC_GROUP *, EC_POINT *,
312 const BIGNUM *x, int y_bit, BN_CTX *); 230 const BIGNUM *x, int y_bit, BN_CTX *);
313size_t ec_GFp_simple_point2oct(const EC_GROUP *, const EC_POINT *, point_conversion_form_t form, 231size_t ec_GFp_simple_point2oct(const EC_GROUP *, const EC_POINT *, point_conversion_form_t form,
314 unsigned char *buf, size_t len, BN_CTX *); 232 unsigned char *buf, size_t len, BN_CTX *);
@@ -328,7 +246,7 @@ int ec_GFp_simple_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX
328 246
329/* method functions in ecp_mont.c */ 247/* method functions in ecp_mont.c */
330int ec_GFp_mont_group_init(EC_GROUP *); 248int ec_GFp_mont_group_init(EC_GROUP *);
331int ec_GFp_mont_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *); 249int ec_GFp_mont_group_set_curve_GFp(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
332void ec_GFp_mont_group_finish(EC_GROUP *); 250void ec_GFp_mont_group_finish(EC_GROUP *);
333void ec_GFp_mont_group_clear_finish(EC_GROUP *); 251void ec_GFp_mont_group_clear_finish(EC_GROUP *);
334int ec_GFp_mont_group_copy(EC_GROUP *, const EC_GROUP *); 252int ec_GFp_mont_group_copy(EC_GROUP *, const EC_GROUP *);
@@ -339,52 +257,21 @@ int ec_GFp_mont_field_decode(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CT
339int ec_GFp_mont_field_set_to_one(const EC_GROUP *, BIGNUM *r, BN_CTX *); 257int ec_GFp_mont_field_set_to_one(const EC_GROUP *, BIGNUM *r, BN_CTX *);
340 258
341 259
260/* method functions in ecp_recp.c */
261int ec_GFp_recp_group_init(EC_GROUP *);
262int ec_GFp_recp_group_set_curve_GFp(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
263void ec_GFp_recp_group_finish(EC_GROUP *);
264void ec_GFp_recp_group_clear_finish(EC_GROUP *);
265int ec_GFp_recp_group_copy(EC_GROUP *, const EC_GROUP *);
266int ec_GFp_recp_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
267int ec_GFp_recp_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
268
269
342/* method functions in ecp_nist.c */ 270/* method functions in ecp_nist.c */
343int ec_GFp_nist_group_copy(EC_GROUP *dest, const EC_GROUP *src); 271int ec_GFp_nist_group_init(EC_GROUP *);
344int ec_GFp_nist_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *); 272int ec_GFp_nist_group_set_curve_GFp(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
273void ec_GFp_nist_group_finish(EC_GROUP *);
274void ec_GFp_nist_group_clear_finish(EC_GROUP *);
275int ec_GFp_nist_group_copy(EC_GROUP *, const EC_GROUP *);
345int ec_GFp_nist_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *); 276int ec_GFp_nist_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
346int ec_GFp_nist_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *); 277int ec_GFp_nist_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
347
348
349/* method functions in ec2_smpl.c */
350int ec_GF2m_simple_group_init(EC_GROUP *);
351void ec_GF2m_simple_group_finish(EC_GROUP *);
352void ec_GF2m_simple_group_clear_finish(EC_GROUP *);
353int ec_GF2m_simple_group_copy(EC_GROUP *, const EC_GROUP *);
354int ec_GF2m_simple_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
355int ec_GF2m_simple_group_get_curve(const EC_GROUP *, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *);
356int ec_GF2m_simple_group_get_degree(const EC_GROUP *);
357int ec_GF2m_simple_group_check_discriminant(const EC_GROUP *, BN_CTX *);
358int ec_GF2m_simple_point_init(EC_POINT *);
359void ec_GF2m_simple_point_finish(EC_POINT *);
360void ec_GF2m_simple_point_clear_finish(EC_POINT *);
361int ec_GF2m_simple_point_copy(EC_POINT *, const EC_POINT *);
362int ec_GF2m_simple_point_set_to_infinity(const EC_GROUP *, EC_POINT *);
363int ec_GF2m_simple_point_set_affine_coordinates(const EC_GROUP *, EC_POINT *,
364 const BIGNUM *x, const BIGNUM *y, BN_CTX *);
365int ec_GF2m_simple_point_get_affine_coordinates(const EC_GROUP *, const EC_POINT *,
366 BIGNUM *x, BIGNUM *y, BN_CTX *);
367int ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *, EC_POINT *,
368 const BIGNUM *x, int y_bit, BN_CTX *);
369size_t ec_GF2m_simple_point2oct(const EC_GROUP *, const EC_POINT *, point_conversion_form_t form,
370 unsigned char *buf, size_t len, BN_CTX *);
371int ec_GF2m_simple_oct2point(const EC_GROUP *, EC_POINT *,
372 const unsigned char *buf, size_t len, BN_CTX *);
373int ec_GF2m_simple_add(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *);
374int ec_GF2m_simple_dbl(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, BN_CTX *);
375int ec_GF2m_simple_invert(const EC_GROUP *, EC_POINT *, BN_CTX *);
376int ec_GF2m_simple_is_at_infinity(const EC_GROUP *, const EC_POINT *);
377int ec_GF2m_simple_is_on_curve(const EC_GROUP *, const EC_POINT *, BN_CTX *);
378int ec_GF2m_simple_cmp(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b, BN_CTX *);
379int ec_GF2m_simple_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *);
380int ec_GF2m_simple_points_make_affine(const EC_GROUP *, size_t num, EC_POINT *[], BN_CTX *);
381int ec_GF2m_simple_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
382int ec_GF2m_simple_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
383int ec_GF2m_simple_field_div(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
384
385
386/* method functions in ec2_mult.c */
387int ec_GF2m_simple_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
388 size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *);
389int ec_GF2m_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
390int ec_GF2m_have_precompute_mult(const EC_GROUP *group);
diff --git a/src/lib/libcrypto/ec/ec_lib.c b/src/lib/libcrypto/ec/ec_lib.c
index 5af84376c6..deb522060f 100644
--- a/src/lib/libcrypto/ec/ec_lib.c
+++ b/src/lib/libcrypto/ec/ec_lib.c
@@ -1,9 +1,6 @@
1/* crypto/ec/ec_lib.c */ 1/* crypto/ec/ec_lib.c */
2/*
3 * Originally written by Bodo Moeller for the OpenSSL project.
4 */
5/* ==================================================================== 2/* ====================================================================
6 * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. 3 * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
7 * 4 *
8 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
@@ -55,11 +52,6 @@
55 * Hudson (tjh@cryptsoft.com). 52 * Hudson (tjh@cryptsoft.com).
56 * 53 *
57 */ 54 */
58/* ====================================================================
59 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
60 * Binary polynomial ECC support in OpenSSL originally developed by
61 * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
62 */
63 55
64#include <string.h> 56#include <string.h>
65 57
@@ -98,18 +90,10 @@ EC_GROUP *EC_GROUP_new(const EC_METHOD *meth)
98 ret->meth = meth; 90 ret->meth = meth;
99 91
100 ret->extra_data = NULL; 92 ret->extra_data = NULL;
101 93 ret->extra_data_dup_func = 0;
102 ret->generator = NULL; 94 ret->extra_data_free_func = 0;
103 BN_init(&ret->order); 95 ret->extra_data_clear_free_func = 0;
104 BN_init(&ret->cofactor); 96
105
106 ret->curve_name = 0;
107 ret->asn1_flag = 0;
108 ret->asn1_form = POINT_CONVERSION_UNCOMPRESSED;
109
110 ret->seed = NULL;
111 ret->seed_len = 0;
112
113 if (!meth->group_init(ret)) 97 if (!meth->group_init(ret))
114 { 98 {
115 OPENSSL_free(ret); 99 OPENSSL_free(ret);
@@ -127,15 +111,7 @@ void EC_GROUP_free(EC_GROUP *group)
127 if (group->meth->group_finish != 0) 111 if (group->meth->group_finish != 0)
128 group->meth->group_finish(group); 112 group->meth->group_finish(group);
129 113
130 EC_EX_DATA_free_all_data(&group->extra_data); 114 EC_GROUP_free_extra_data(group);
131
132 if (group->generator != NULL)
133 EC_POINT_free(group->generator);
134 BN_free(&group->order);
135 BN_free(&group->cofactor);
136
137 if (group->seed)
138 OPENSSL_free(group->seed);
139 115
140 OPENSSL_free(group); 116 OPENSSL_free(group);
141 } 117 }
@@ -147,21 +123,10 @@ void EC_GROUP_clear_free(EC_GROUP *group)
147 123
148 if (group->meth->group_clear_finish != 0) 124 if (group->meth->group_clear_finish != 0)
149 group->meth->group_clear_finish(group); 125 group->meth->group_clear_finish(group);
150 else if (group->meth->group_finish != 0) 126 else if (group->meth != NULL && group->meth->group_finish != 0)
151 group->meth->group_finish(group); 127 group->meth->group_finish(group);
152 128
153 EC_EX_DATA_clear_free_all_data(&group->extra_data); 129 EC_GROUP_clear_free_extra_data(group);
154
155 if (group->generator != NULL)
156 EC_POINT_clear_free(group->generator);
157 BN_clear_free(&group->order);
158 BN_clear_free(&group->cofactor);
159
160 if (group->seed)
161 {
162 OPENSSL_cleanse(group->seed, group->seed_len);
163 OPENSSL_free(group->seed);
164 }
165 130
166 OPENSSL_cleanse(group, sizeof *group); 131 OPENSSL_cleanse(group, sizeof *group);
167 OPENSSL_free(group); 132 OPENSSL_free(group);
@@ -170,8 +135,6 @@ void EC_GROUP_clear_free(EC_GROUP *group)
170 135
171int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src) 136int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src)
172 { 137 {
173 EC_EXTRA_DATA *d;
174
175 if (dest->meth->group_copy == 0) 138 if (dest->meth->group_copy == 0)
176 { 139 {
177 ECerr(EC_F_EC_GROUP_COPY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 140 ECerr(EC_F_EC_GROUP_COPY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
@@ -185,507 +148,161 @@ int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src)
185 if (dest == src) 148 if (dest == src)
186 return 1; 149 return 1;
187 150
188 EC_EX_DATA_free_all_data(&dest->extra_data); 151 EC_GROUP_clear_free_extra_data(dest);
189 152 if (src->extra_data_dup_func)
190 for (d = src->extra_data; d != NULL; d = d->next)
191 { 153 {
192 void *t = d->dup_func(d->data); 154 if (src->extra_data != NULL)
193
194 if (t == NULL)
195 return 0;
196 if (!EC_EX_DATA_set_data(&dest->extra_data, t, d->dup_func, d->free_func, d->clear_free_func))
197 return 0;
198 }
199
200 if (src->generator != NULL)
201 {
202 if (dest->generator == NULL)
203 {
204 dest->generator = EC_POINT_new(dest);
205 if (dest->generator == NULL) return 0;
206 }
207 if (!EC_POINT_copy(dest->generator, src->generator)) return 0;
208 }
209 else
210 {
211 /* src->generator == NULL */
212 if (dest->generator != NULL)
213 { 155 {
214 EC_POINT_clear_free(dest->generator); 156 dest->extra_data = src->extra_data_dup_func(src->extra_data);
215 dest->generator = NULL; 157 if (dest->extra_data == NULL)
158 return 0;
216 } 159 }
217 }
218
219 if (!BN_copy(&dest->order, &src->order)) return 0;
220 if (!BN_copy(&dest->cofactor, &src->cofactor)) return 0;
221 160
222 dest->curve_name = src->curve_name; 161 dest->extra_data_dup_func = src->extra_data_dup_func;
223 dest->asn1_flag = src->asn1_flag; 162 dest->extra_data_free_func = src->extra_data_free_func;
224 dest->asn1_form = src->asn1_form; 163 dest->extra_data_clear_free_func = src->extra_data_clear_free_func;
225
226 if (src->seed)
227 {
228 if (dest->seed)
229 OPENSSL_free(dest->seed);
230 dest->seed = OPENSSL_malloc(src->seed_len);
231 if (dest->seed == NULL)
232 return 0;
233 if (!memcpy(dest->seed, src->seed, src->seed_len))
234 return 0;
235 dest->seed_len = src->seed_len;
236 }
237 else
238 {
239 if (dest->seed)
240 OPENSSL_free(dest->seed);
241 dest->seed = NULL;
242 dest->seed_len = 0;
243 } 164 }
244
245 165
246 return dest->meth->group_copy(dest, src); 166 return dest->meth->group_copy(dest, src);
247 } 167 }
248 168
249 169
250EC_GROUP *EC_GROUP_dup(const EC_GROUP *a)
251 {
252 EC_GROUP *t = NULL;
253 int ok = 0;
254
255 if (a == NULL) return NULL;
256
257 if ((t = EC_GROUP_new(a->meth)) == NULL) return(NULL);
258 if (!EC_GROUP_copy(t, a)) goto err;
259
260 ok = 1;
261
262 err:
263 if (!ok)
264 {
265 if (t) EC_GROUP_free(t);
266 return NULL;
267 }
268 else return t;
269 }
270
271
272const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group) 170const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group)
273 { 171 {
274 return group->meth; 172 return group->meth;
275 } 173 }
276 174
277 175
278int EC_METHOD_get_field_type(const EC_METHOD *meth)
279 {
280 return meth->field_type;
281 }
282
283
284int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, const BIGNUM *order, const BIGNUM *cofactor)
285 {
286 if (generator == NULL)
287 {
288 ECerr(EC_F_EC_GROUP_SET_GENERATOR, ERR_R_PASSED_NULL_PARAMETER);
289 return 0 ;
290 }
291
292 if (group->generator == NULL)
293 {
294 group->generator = EC_POINT_new(group);
295 if (group->generator == NULL) return 0;
296 }
297 if (!EC_POINT_copy(group->generator, generator)) return 0;
298
299 if (order != NULL)
300 { if (!BN_copy(&group->order, order)) return 0; }
301 else
302 BN_zero(&group->order);
303
304 if (cofactor != NULL)
305 { if (!BN_copy(&group->cofactor, cofactor)) return 0; }
306 else
307 BN_zero(&group->cofactor);
308
309 return 1;
310 }
311
312
313const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group)
314 {
315 return group->generator;
316 }
317
318
319int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx)
320 {
321 if (!BN_copy(order, &group->order))
322 return 0;
323
324 return !BN_is_zero(order);
325 }
326
327
328int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, BN_CTX *ctx)
329 {
330 if (!BN_copy(cofactor, &group->cofactor))
331 return 0;
332
333 return !BN_is_zero(&group->cofactor);
334 }
335
336
337void EC_GROUP_set_curve_name(EC_GROUP *group, int nid)
338 {
339 group->curve_name = nid;
340 }
341
342
343int EC_GROUP_get_curve_name(const EC_GROUP *group)
344 {
345 return group->curve_name;
346 }
347
348
349void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag)
350 {
351 group->asn1_flag = flag;
352 }
353
354
355int EC_GROUP_get_asn1_flag(const EC_GROUP *group)
356 {
357 return group->asn1_flag;
358 }
359
360
361void EC_GROUP_set_point_conversion_form(EC_GROUP *group,
362 point_conversion_form_t form)
363 {
364 group->asn1_form = form;
365 }
366
367
368point_conversion_form_t EC_GROUP_get_point_conversion_form(const EC_GROUP *group)
369 {
370 return group->asn1_form;
371 }
372
373
374size_t EC_GROUP_set_seed(EC_GROUP *group, const unsigned char *p, size_t len)
375 {
376 if (group->seed)
377 {
378 OPENSSL_free(group->seed);
379 group->seed = NULL;
380 group->seed_len = 0;
381 }
382
383 if (!len || !p)
384 return 1;
385
386 if ((group->seed = OPENSSL_malloc(len)) == NULL)
387 return 0;
388 memcpy(group->seed, p, len);
389 group->seed_len = len;
390
391 return len;
392 }
393
394
395unsigned char *EC_GROUP_get0_seed(const EC_GROUP *group)
396 {
397 return group->seed;
398 }
399
400
401size_t EC_GROUP_get_seed_len(const EC_GROUP *group)
402 {
403 return group->seed_len;
404 }
405
406
407int EC_GROUP_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) 176int EC_GROUP_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
408 { 177 {
409 if (group->meth->group_set_curve == 0) 178 if (group->meth->group_set_curve_GFp == 0)
410 { 179 {
411 ECerr(EC_F_EC_GROUP_SET_CURVE_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 180 ECerr(EC_F_EC_GROUP_SET_CURVE_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
412 return 0; 181 return 0;
413 } 182 }
414 return group->meth->group_set_curve(group, p, a, b, ctx); 183 return group->meth->group_set_curve_GFp(group, p, a, b, ctx);
415 } 184 }
416 185
417 186
418int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx) 187int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx)
419 { 188 {
420 if (group->meth->group_get_curve == 0) 189 if (group->meth->group_get_curve_GFp == 0)
421 { 190 {
422 ECerr(EC_F_EC_GROUP_GET_CURVE_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 191 ECerr(EC_F_EC_GROUP_GET_CURVE_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
423 return 0; 192 return 0;
424 } 193 }
425 return group->meth->group_get_curve(group, p, a, b, ctx); 194 return group->meth->group_get_curve_GFp(group, p, a, b, ctx);
426 } 195 }
427 196
428 197
429int EC_GROUP_set_curve_GF2m(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) 198int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, const BIGNUM *order, const BIGNUM *cofactor)
430 { 199 {
431 if (group->meth->group_set_curve == 0) 200 if (group->meth->group_set_generator == 0)
432 { 201 {
433 ECerr(EC_F_EC_GROUP_SET_CURVE_GF2M, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 202 ECerr(EC_F_EC_GROUP_SET_GENERATOR, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
434 return 0; 203 return 0;
435 } 204 }
436 return group->meth->group_set_curve(group, p, a, b, ctx); 205 return group->meth->group_set_generator(group, generator, order, cofactor);
437 } 206 }
438 207
439 208
440int EC_GROUP_get_curve_GF2m(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx) 209EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group)
441 { 210 {
442 if (group->meth->group_get_curve == 0) 211 if (group->meth->group_get0_generator == 0)
443 { 212 {
444 ECerr(EC_F_EC_GROUP_GET_CURVE_GF2M, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 213 ECerr(EC_F_EC_GROUP_GET0_GENERATOR, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
445 return 0; 214 return 0;
446 } 215 }
447 return group->meth->group_get_curve(group, p, a, b, ctx); 216 return group->meth->group_get0_generator(group);
448 } 217 }
449 218
450 219
451int EC_GROUP_get_degree(const EC_GROUP *group) 220int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx)
452 { 221 {
453 if (group->meth->group_get_degree == 0) 222 if (group->meth->group_get_order == 0)
454 { 223 {
455 ECerr(EC_F_EC_GROUP_GET_DEGREE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 224 ECerr(EC_F_EC_GROUP_GET_ORDER, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
456 return 0; 225 return 0;
457 } 226 }
458 return group->meth->group_get_degree(group); 227 return group->meth->group_get_order(group, order, ctx);
459 } 228 }
460 229
461 230
462int EC_GROUP_check_discriminant(const EC_GROUP *group, BN_CTX *ctx) 231int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, BN_CTX *ctx)
463 { 232 {
464 if (group->meth->group_check_discriminant == 0) 233 if (group->meth->group_get_cofactor == 0)
465 { 234 {
466 ECerr(EC_F_EC_GROUP_CHECK_DISCRIMINANT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 235 ECerr(EC_F_EC_GROUP_GET_COFACTOR, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
467 return 0; 236 return 0;
468 } 237 }
469 return group->meth->group_check_discriminant(group, ctx); 238 return group->meth->group_get_cofactor(group, cofactor, ctx);
470 } 239 }
471 240
472 241
473int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx) 242/* this has 'package' visibility */
243int EC_GROUP_set_extra_data(EC_GROUP *group, void *extra_data, void *(*extra_data_dup_func)(void *),
244 void (*extra_data_free_func)(void *), void (*extra_data_clear_free_func)(void *))
474 { 245 {
475 int r = 0; 246 if ((group->extra_data != NULL)
476 BIGNUM *a1, *a2, *a3, *b1, *b2, *b3; 247 || (group->extra_data_dup_func != 0)
477 BN_CTX *ctx_new = NULL; 248 || (group->extra_data_free_func != 0)
478 249 || (group->extra_data_clear_free_func != 0))
479 /* compare the field types*/
480 if (EC_METHOD_get_field_type(EC_GROUP_method_of(a)) !=
481 EC_METHOD_get_field_type(EC_GROUP_method_of(b)))
482 return 1;
483 /* compare the curve name (if present) */
484 if (EC_GROUP_get_curve_name(a) && EC_GROUP_get_curve_name(b) &&
485 EC_GROUP_get_curve_name(a) == EC_GROUP_get_curve_name(b))
486 return 0;
487
488 if (!ctx)
489 ctx_new = ctx = BN_CTX_new();
490 if (!ctx)
491 return -1;
492
493 BN_CTX_start(ctx);
494 a1 = BN_CTX_get(ctx);
495 a2 = BN_CTX_get(ctx);
496 a3 = BN_CTX_get(ctx);
497 b1 = BN_CTX_get(ctx);
498 b2 = BN_CTX_get(ctx);
499 b3 = BN_CTX_get(ctx);
500 if (!b3)
501 { 250 {
502 BN_CTX_end(ctx); 251 ECerr(EC_F_EC_GROUP_SET_EXTRA_DATA, EC_R_SLOT_FULL);
503 if (ctx_new) 252 return 0;
504 BN_CTX_free(ctx);
505 return -1;
506 }
507
508 /* XXX This approach assumes that the external representation
509 * of curves over the same field type is the same.
510 */
511 if (!a->meth->group_get_curve(a, a1, a2, a3, ctx) ||
512 !b->meth->group_get_curve(b, b1, b2, b3, ctx))
513 r = 1;
514
515 if (r || BN_cmp(a1, b1) || BN_cmp(a2, b2) || BN_cmp(a3, b3))
516 r = 1;
517
518 /* XXX EC_POINT_cmp() assumes that the methods are equal */
519 if (r || EC_POINT_cmp(a, EC_GROUP_get0_generator(a),
520 EC_GROUP_get0_generator(b), ctx))
521 r = 1;
522
523 if (!r)
524 {
525 /* compare the order and cofactor */
526 if (!EC_GROUP_get_order(a, a1, ctx) ||
527 !EC_GROUP_get_order(b, b1, ctx) ||
528 !EC_GROUP_get_cofactor(a, a2, ctx) ||
529 !EC_GROUP_get_cofactor(b, b2, ctx))
530 {
531 BN_CTX_end(ctx);
532 if (ctx_new)
533 BN_CTX_free(ctx);
534 return -1;
535 }
536 if (BN_cmp(a1, b1) || BN_cmp(a2, b2))
537 r = 1;
538 } 253 }
539 254
540 BN_CTX_end(ctx); 255 group->extra_data = extra_data;
541 if (ctx_new) 256 group->extra_data_dup_func = extra_data_dup_func;
542 BN_CTX_free(ctx); 257 group->extra_data_free_func = extra_data_free_func;
543 258 group->extra_data_clear_free_func = extra_data_clear_free_func;
544 return r; 259 return 1;
545 } 260 }
546 261
547 262
548/* this has 'package' visibility */ 263/* this has 'package' visibility */
549int EC_EX_DATA_set_data(EC_EXTRA_DATA **ex_data, void *data, 264void *EC_GROUP_get_extra_data(const EC_GROUP *group, void *(*extra_data_dup_func)(void *),
550 void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *)) 265 void (*extra_data_free_func)(void *), void (*extra_data_clear_free_func)(void *))
551 { 266 {
552 EC_EXTRA_DATA *d; 267 if ((group->extra_data_dup_func != extra_data_dup_func)
553 268 || (group->extra_data_free_func != extra_data_free_func)
554 if (ex_data == NULL) 269 || (group->extra_data_clear_free_func != extra_data_clear_free_func))
555 return 0;
556
557 for (d = *ex_data; d != NULL; d = d->next)
558 { 270 {
559 if (d->dup_func == dup_func && d->free_func == free_func && d->clear_free_func == clear_free_func) 271#if 0 /* this was an error in 0.9.7, but that does not make a lot of sense */
560 { 272 ECerr(..._F_EC_GROUP_GET_EXTRA_DATA, ..._R_NO_SUCH_EXTRA_DATA);
561 ECerr(EC_F_EC_EX_DATA_SET_DATA, EC_R_SLOT_FULL); 273#endif
562 return 0; 274 return NULL;
563 }
564 } 275 }
565 276
566 if (data == NULL) 277 return group->extra_data;
567 /* no explicit entry needed */
568 return 1;
569
570 d = OPENSSL_malloc(sizeof *d);
571 if (d == NULL)
572 return 0;
573
574 d->data = data;
575 d->dup_func = dup_func;
576 d->free_func = free_func;
577 d->clear_free_func = clear_free_func;
578
579 d->next = *ex_data;
580 *ex_data = d;
581
582 return 1;
583 } 278 }
584 279
585/* this has 'package' visibility */
586void *EC_EX_DATA_get_data(const EC_EXTRA_DATA *ex_data,
587 void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *))
588 {
589 const EC_EXTRA_DATA *d;
590
591 for (d = ex_data; d != NULL; d = d->next)
592 {
593 if (d->dup_func == dup_func && d->free_func == free_func && d->clear_free_func == clear_free_func)
594 return d->data;
595 }
596
597 return NULL;
598 }
599 280
600/* this has 'package' visibility */ 281/* this has 'package' visibility */
601void EC_EX_DATA_free_data(EC_EXTRA_DATA **ex_data, 282void EC_GROUP_free_extra_data(EC_GROUP *group)
602 void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *))
603 { 283 {
604 EC_EXTRA_DATA **p; 284 if (group->extra_data_free_func)
605 285 group->extra_data_free_func(group->extra_data);
606 if (ex_data == NULL) 286 group->extra_data = NULL;
607 return; 287 group->extra_data_dup_func = 0;
608 288 group->extra_data_free_func = 0;
609 for (p = ex_data; *p != NULL; p = &((*p)->next)) 289 group->extra_data_clear_free_func = 0;
610 {
611 if ((*p)->dup_func == dup_func && (*p)->free_func == free_func && (*p)->clear_free_func == clear_free_func)
612 {
613 EC_EXTRA_DATA *next = (*p)->next;
614
615 (*p)->free_func((*p)->data);
616 OPENSSL_free(*p);
617
618 *p = next;
619 return;
620 }
621 }
622 } 290 }
623 291
624/* this has 'package' visibility */
625void EC_EX_DATA_clear_free_data(EC_EXTRA_DATA **ex_data,
626 void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *))
627 {
628 EC_EXTRA_DATA **p;
629
630 if (ex_data == NULL)
631 return;
632
633 for (p = ex_data; *p != NULL; p = &((*p)->next))
634 {
635 if ((*p)->dup_func == dup_func && (*p)->free_func == free_func && (*p)->clear_free_func == clear_free_func)
636 {
637 EC_EXTRA_DATA *next = (*p)->next;
638
639 (*p)->clear_free_func((*p)->data);
640 OPENSSL_free(*p);
641
642 *p = next;
643 return;
644 }
645 }
646 }
647 292
648/* this has 'package' visibility */ 293/* this has 'package' visibility */
649void EC_EX_DATA_free_all_data(EC_EXTRA_DATA **ex_data) 294void EC_GROUP_clear_free_extra_data(EC_GROUP *group)
650 { 295 {
651 EC_EXTRA_DATA *d; 296 if (group->extra_data_clear_free_func)
652 297 group->extra_data_clear_free_func(group->extra_data);
653 if (ex_data == NULL) 298 else if (group->extra_data_free_func)
654 return; 299 group->extra_data_free_func(group->extra_data);
655 300 group->extra_data = NULL;
656 d = *ex_data; 301 group->extra_data_dup_func = 0;
657 while (d) 302 group->extra_data_free_func = 0;
658 { 303 group->extra_data_clear_free_func = 0;
659 EC_EXTRA_DATA *next = d->next;
660
661 d->free_func(d->data);
662 OPENSSL_free(d);
663
664 d = next;
665 }
666 *ex_data = NULL;
667 } 304 }
668 305
669/* this has 'package' visibility */
670void EC_EX_DATA_clear_free_all_data(EC_EXTRA_DATA **ex_data)
671 {
672 EC_EXTRA_DATA *d;
673
674 if (ex_data == NULL)
675 return;
676
677 d = *ex_data;
678 while (d)
679 {
680 EC_EXTRA_DATA *next = d->next;
681
682 d->clear_free_func(d->data);
683 OPENSSL_free(d);
684
685 d = next;
686 }
687 *ex_data = NULL;
688 }
689 306
690 307
691/* functions for EC_POINT objects */ 308/* functions for EC_POINT objects */
@@ -765,25 +382,6 @@ int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src)
765 } 382 }
766 383
767 384
768EC_POINT *EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group)
769 {
770 EC_POINT *t;
771 int r;
772
773 if (a == NULL) return NULL;
774
775 t = EC_POINT_new(group);
776 if (t == NULL) return(NULL);
777 r = EC_POINT_copy(t, a);
778 if (!r)
779 {
780 EC_POINT_free(t);
781 return NULL;
782 }
783 else return t;
784 }
785
786
787const EC_METHOD *EC_POINT_method_of(const EC_POINT *point) 385const EC_METHOD *EC_POINT_method_of(const EC_POINT *point)
788 { 386 {
789 return point->meth; 387 return point->meth;
@@ -843,7 +441,7 @@ int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group, const EC_POI
843int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *point, 441int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
844 const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx) 442 const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx)
845 { 443 {
846 if (group->meth->point_set_affine_coordinates == 0) 444 if (group->meth->point_set_affine_coordinates_GFp == 0)
847 { 445 {
848 ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 446 ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
849 return 0; 447 return 0;
@@ -853,31 +451,14 @@ int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
853 ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS); 451 ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS);
854 return 0; 452 return 0;
855 } 453 }
856 return group->meth->point_set_affine_coordinates(group, point, x, y, ctx); 454 return group->meth->point_set_affine_coordinates_GFp(group, point, x, y, ctx);
857 }
858
859
860int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *group, EC_POINT *point,
861 const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx)
862 {
863 if (group->meth->point_set_affine_coordinates == 0)
864 {
865 ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
866 return 0;
867 }
868 if (group->meth != point->meth)
869 {
870 ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M, EC_R_INCOMPATIBLE_OBJECTS);
871 return 0;
872 }
873 return group->meth->point_set_affine_coordinates(group, point, x, y, ctx);
874 } 455 }
875 456
876 457
877int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group, const EC_POINT *point, 458int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group, const EC_POINT *point,
878 BIGNUM *x, BIGNUM *y, BN_CTX *ctx) 459 BIGNUM *x, BIGNUM *y, BN_CTX *ctx)
879 { 460 {
880 if (group->meth->point_get_affine_coordinates == 0) 461 if (group->meth->point_get_affine_coordinates_GFp == 0)
881 { 462 {
882 ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 463 ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
883 return 0; 464 return 0;
@@ -887,31 +468,14 @@ int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group, const EC_POINT *p
887 ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS); 468 ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS);
888 return 0; 469 return 0;
889 } 470 }
890 return group->meth->point_get_affine_coordinates(group, point, x, y, ctx); 471 return group->meth->point_get_affine_coordinates_GFp(group, point, x, y, ctx);
891 }
892
893
894int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *group, const EC_POINT *point,
895 BIGNUM *x, BIGNUM *y, BN_CTX *ctx)
896 {
897 if (group->meth->point_get_affine_coordinates == 0)
898 {
899 ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
900 return 0;
901 }
902 if (group->meth != point->meth)
903 {
904 ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M, EC_R_INCOMPATIBLE_OBJECTS);
905 return 0;
906 }
907 return group->meth->point_get_affine_coordinates(group, point, x, y, ctx);
908 } 472 }
909 473
910 474
911int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group, EC_POINT *point, 475int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
912 const BIGNUM *x, int y_bit, BN_CTX *ctx) 476 const BIGNUM *x, int y_bit, BN_CTX *ctx)
913 { 477 {
914 if (group->meth->point_set_compressed_coordinates == 0) 478 if (group->meth->point_set_compressed_coordinates_GFp == 0)
915 { 479 {
916 ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 480 ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
917 return 0; 481 return 0;
@@ -921,24 +485,7 @@ int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group, EC_POINT *poi
921 ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS); 485 ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP, EC_R_INCOMPATIBLE_OBJECTS);
922 return 0; 486 return 0;
923 } 487 }
924 return group->meth->point_set_compressed_coordinates(group, point, x, y_bit, ctx); 488 return group->meth->point_set_compressed_coordinates_GFp(group, point, x, y_bit, ctx);
925 }
926
927
928int EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP *group, EC_POINT *point,
929 const BIGNUM *x, int y_bit, BN_CTX *ctx)
930 {
931 if (group->meth->point_set_compressed_coordinates == 0)
932 {
933 ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
934 return 0;
935 }
936 if (group->meth != point->meth)
937 {
938 ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M, EC_R_INCOMPATIBLE_OBJECTS);
939 return 0;
940 }
941 return group->meth->point_set_compressed_coordinates(group, point, x, y_bit, ctx);
942 } 489 }
943 490
944 491
@@ -1012,12 +559,12 @@ int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx)
1012 { 559 {
1013 if (group->meth->dbl == 0) 560 if (group->meth->dbl == 0)
1014 { 561 {
1015 ECerr(EC_F_EC_POINT_INVERT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 562 ECerr(EC_F_EC_POINT_DBL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
1016 return 0; 563 return 0;
1017 } 564 }
1018 if (group->meth != a->meth) 565 if (group->meth != a->meth)
1019 { 566 {
1020 ECerr(EC_F_EC_POINT_INVERT, EC_R_INCOMPATIBLE_OBJECTS); 567 ECerr(EC_F_EC_POINT_DBL, EC_R_INCOMPATIBLE_OBJECTS);
1021 return 0; 568 return 0;
1022 } 569 }
1023 return group->meth->invert(group, a, ctx); 570 return group->meth->invert(group, a, ctx);
@@ -1107,58 +654,3 @@ int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[],
1107 } 654 }
1108 return group->meth->points_make_affine(group, num, points, ctx); 655 return group->meth->points_make_affine(group, num, points, ctx);
1109 } 656 }
1110
1111
1112/* Functions for point multiplication.
1113 *
1114 * If group->meth->mul is 0, we use the wNAF-based implementations in ec_mult.c;
1115 * otherwise we dispatch through methods.
1116 */
1117
1118int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
1119 size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx)
1120 {
1121 if (group->meth->mul == 0)
1122 /* use default */
1123 return ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx);
1124
1125 return group->meth->mul(group, r, scalar, num, points, scalars, ctx);
1126 }
1127
1128int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
1129 const EC_POINT *point, const BIGNUM *p_scalar, BN_CTX *ctx)
1130 {
1131 /* just a convenient interface to EC_POINTs_mul() */
1132
1133 const EC_POINT *points[1];
1134 const BIGNUM *scalars[1];
1135
1136 points[0] = point;
1137 scalars[0] = p_scalar;
1138
1139 return EC_POINTs_mul(group, r, g_scalar, (point != NULL && p_scalar != NULL), points, scalars, ctx);
1140 }
1141
1142int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
1143 {
1144 if (group->meth->mul == 0)
1145 /* use default */
1146 return ec_wNAF_precompute_mult(group, ctx);
1147
1148 if (group->meth->precompute_mult != 0)
1149 return group->meth->precompute_mult(group, ctx);
1150 else
1151 return 1; /* nothing to do, so report success */
1152 }
1153
1154int EC_GROUP_have_precompute_mult(const EC_GROUP *group)
1155 {
1156 if (group->meth->mul == 0)
1157 /* use default */
1158 return ec_wNAF_have_precompute_mult(group);
1159
1160 if (group->meth->have_precompute_mult != 0)
1161 return group->meth->have_precompute_mult(group);
1162 else
1163 return 0; /* cannot tell whether precomputation has been performed */
1164 }
diff --git a/src/lib/libcrypto/ec/ec_mult.c b/src/lib/libcrypto/ec/ec_mult.c
index 2ba173ef36..16822a73cf 100644
--- a/src/lib/libcrypto/ec/ec_mult.c
+++ b/src/lib/libcrypto/ec/ec_mult.c
@@ -1,9 +1,6 @@
1/* crypto/ec/ec_mult.c */ 1/* crypto/ec/ec_mult.c */
2/*
3 * Originally written by Bodo Moeller and Nils Larsch for the OpenSSL project.
4 */
5/* ==================================================================== 2/* ====================================================================
6 * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. 3 * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
7 * 4 *
8 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
@@ -55,161 +52,41 @@
55 * Hudson (tjh@cryptsoft.com). 52 * Hudson (tjh@cryptsoft.com).
56 * 53 *
57 */ 54 */
58/* ====================================================================
59 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
60 * Portions of this software developed by SUN MICROSYSTEMS, INC.,
61 * and contributed to the OpenSSL project.
62 */
63
64#include <string.h>
65 55
66#include <openssl/err.h> 56#include <openssl/err.h>
67 57
68#include "ec_lcl.h" 58#include "ec_lcl.h"
69 59
70 60
71/* 61/* TODO: optional precomputation of multiples of the generator */
72 * This file implements the wNAF-based interleaving multi-exponentation method
73 * (<URL:http://www.informatik.tu-darmstadt.de/TI/Mitarbeiter/moeller.html#multiexp>);
74 * for multiplication with precomputation, we use wNAF splitting
75 * (<URL:http://www.informatik.tu-darmstadt.de/TI/Mitarbeiter/moeller.html#fastexp>).
76 */
77
78
79
80
81/* structure for precomputed multiples of the generator */
82typedef struct ec_pre_comp_st {
83 const EC_GROUP *group; /* parent EC_GROUP object */
84 size_t blocksize; /* block size for wNAF splitting */
85 size_t numblocks; /* max. number of blocks for which we have precomputation */
86 size_t w; /* window size */
87 EC_POINT **points; /* array with pre-calculated multiples of generator:
88 * 'num' pointers to EC_POINT objects followed by a NULL */
89 size_t num; /* numblocks * 2^(w-1) */
90 int references;
91} EC_PRE_COMP;
92
93/* functions to manage EC_PRE_COMP within the EC_GROUP extra_data framework */
94static void *ec_pre_comp_dup(void *);
95static void ec_pre_comp_free(void *);
96static void ec_pre_comp_clear_free(void *);
97
98static EC_PRE_COMP *ec_pre_comp_new(const EC_GROUP *group)
99 {
100 EC_PRE_COMP *ret = NULL;
101
102 if (!group)
103 return NULL;
104
105 ret = (EC_PRE_COMP *)OPENSSL_malloc(sizeof(EC_PRE_COMP));
106 if (!ret)
107 {
108 ECerr(EC_F_EC_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
109 return ret;
110 }
111 ret->group = group;
112 ret->blocksize = 8; /* default */
113 ret->numblocks = 0;
114 ret->w = 4; /* default */
115 ret->points = NULL;
116 ret->num = 0;
117 ret->references = 1;
118 return ret;
119 }
120
121static void *ec_pre_comp_dup(void *src_)
122 {
123 EC_PRE_COMP *src = src_;
124
125 /* no need to actually copy, these objects never change! */
126
127 CRYPTO_add(&src->references, 1, CRYPTO_LOCK_EC_PRE_COMP);
128
129 return src_;
130 }
131
132static void ec_pre_comp_free(void *pre_)
133 {
134 int i;
135 EC_PRE_COMP *pre = pre_;
136
137 if (!pre)
138 return;
139
140 i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP);
141 if (i > 0)
142 return;
143
144 if (pre->points)
145 {
146 EC_POINT **p;
147
148 for (p = pre->points; *p != NULL; p++)
149 EC_POINT_free(*p);
150 OPENSSL_free(pre->points);
151 }
152 OPENSSL_free(pre);
153 }
154
155static void ec_pre_comp_clear_free(void *pre_)
156 {
157 int i;
158 EC_PRE_COMP *pre = pre_;
159
160 if (!pre)
161 return;
162
163 i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP);
164 if (i > 0)
165 return;
166
167 if (pre->points)
168 {
169 EC_POINT **p;
170 62
171 for (p = pre->points; *p != NULL; p++)
172 EC_POINT_clear_free(*p);
173 OPENSSL_cleanse(pre->points, sizeof pre->points);
174 OPENSSL_free(pre->points);
175 }
176 OPENSSL_cleanse(pre, sizeof pre);
177 OPENSSL_free(pre);
178 }
179 63
180 64
65/*
66 * wNAF-based interleaving multi-exponentation method
67 * (<URL:http://www.informatik.tu-darmstadt.de/TI/Mitarbeiter/moeller.html#multiexp>)
68 */
181 69
182 70
183/* Determine the modified width-(w+1) Non-Adjacent Form (wNAF) of 'scalar'. 71/* Determine the width-(w+1) Non-Adjacent Form (wNAF) of 'scalar'.
184 * This is an array r[] of values that are either zero or odd with an 72 * This is an array r[] of values that are either zero or odd with an
185 * absolute value less than 2^w satisfying 73 * absolute value less than 2^w satisfying
186 * scalar = \sum_j r[j]*2^j 74 * scalar = \sum_j r[j]*2^j
187 * where at most one of any w+1 consecutive digits is non-zero 75 * where at most one of any w+1 consecutive digits is non-zero.
188 * with the exception that the most significant digit may be only
189 * w-1 zeros away from that next non-zero digit.
190 */ 76 */
191static signed char *compute_wNAF(const BIGNUM *scalar, int w, size_t *ret_len) 77static signed char *compute_wNAF(const BIGNUM *scalar, int w, size_t *ret_len, BN_CTX *ctx)
192 { 78 {
193 int window_val; 79 BIGNUM *c;
194 int ok = 0; 80 int ok = 0;
195 signed char *r = NULL; 81 signed char *r = NULL;
196 int sign = 1; 82 int sign = 1;
197 int bit, next_bit, mask; 83 int bit, next_bit, mask;
198 size_t len = 0, j; 84 size_t len = 0, j;
199 85
200 if (BN_is_zero(scalar)) 86 BN_CTX_start(ctx);
201 { 87 c = BN_CTX_get(ctx);
202 r = OPENSSL_malloc(1); 88 if (c == NULL) goto err;
203 if (!r) 89
204 {
205 ECerr(EC_F_COMPUTE_WNAF, ERR_R_MALLOC_FAILURE);
206 goto err;
207 }
208 r[0] = 0;
209 *ret_len = 1;
210 return r;
211 }
212
213 if (w <= 0 || w > 7) /* 'signed char' can represent integers with absolute values less than 2^7 */ 90 if (w <= 0 || w > 7) /* 'signed char' can represent integers with absolute values less than 2^7 */
214 { 91 {
215 ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR); 92 ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
@@ -219,90 +96,60 @@ static signed char *compute_wNAF(const BIGNUM *scalar, int w, size_t *ret_len)
219 next_bit = bit << 1; /* at most 256 */ 96 next_bit = bit << 1; /* at most 256 */
220 mask = next_bit - 1; /* at most 255 */ 97 mask = next_bit - 1; /* at most 255 */
221 98
222 if (BN_is_negative(scalar)) 99 if (!BN_copy(c, scalar)) goto err;
100 if (c->neg)
223 { 101 {
224 sign = -1; 102 sign = -1;
103 c->neg = 0;
225 } 104 }
226 105
227 len = BN_num_bits(scalar); 106 len = BN_num_bits(c) + 1; /* wNAF may be one digit longer than binary representation */
228 r = OPENSSL_malloc(len + 1); /* modified wNAF may be one digit longer than binary representation 107 r = OPENSSL_malloc(len);
229 * (*ret_len will be set to the actual length, i.e. at most 108 if (r == NULL) goto err;
230 * BN_num_bits(scalar) + 1) */
231 if (r == NULL)
232 {
233 ECerr(EC_F_COMPUTE_WNAF, ERR_R_MALLOC_FAILURE);
234 goto err;
235 }
236 109
237 if (scalar->d == NULL || scalar->top == 0)
238 {
239 ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
240 goto err;
241 }
242 window_val = scalar->d[0] & mask;
243 j = 0; 110 j = 0;
244 while ((window_val != 0) || (j + w + 1 < len)) /* if j+w+1 >= len, window_val will not increase */ 111 while (!BN_is_zero(c))
245 { 112 {
246 int digit = 0; 113 int u = 0;
247 114
248 /* 0 <= window_val <= 2^(w+1) */ 115 if (BN_is_odd(c))
249
250 if (window_val & 1)
251 { 116 {
252 /* 0 < window_val < 2^(w+1) */ 117 if (c->d == NULL || c->top == 0)
253
254 if (window_val & bit)
255 { 118 {
256 digit = window_val - next_bit; /* -2^w < digit < 0 */ 119 ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
257 120 goto err;
258#if 1 /* modified wNAF */
259 if (j + w + 1 >= len)
260 {
261 /* special case for generating modified wNAFs:
262 * no new bits will be added into window_val,
263 * so using a positive digit here will decrease
264 * the total length of the representation */
265
266 digit = window_val & (mask >> 1); /* 0 < digit < 2^w */
267 }
268#endif
269 } 121 }
270 else 122 u = c->d[0] & mask;
123 if (u & bit)
271 { 124 {
272 digit = window_val; /* 0 < digit < 2^w */ 125 u -= next_bit;
126 /* u < 0 */
127 if (!BN_add_word(c, -u)) goto err;
273 } 128 }
274 129 else
275 if (digit <= -bit || digit >= bit || !(digit & 1))
276 { 130 {
277 ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR); 131 /* u > 0 */
278 goto err; 132 if (!BN_sub_word(c, u)) goto err;
279 } 133 }
280 134
281 window_val -= digit; 135 if (u <= -bit || u >= bit || !(u & 1) || c->neg)
282
283 /* now window_val is 0 or 2^(w+1) in standard wNAF generation;
284 * for modified window NAFs, it may also be 2^w
285 */
286 if (window_val != 0 && window_val != next_bit && window_val != bit)
287 { 136 {
288 ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR); 137 ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
289 goto err; 138 goto err;
290 } 139 }
291 } 140 }
292 141
293 r[j++] = sign * digit; 142 r[j++] = sign * u;
294 143
295 window_val >>= 1; 144 if (BN_is_odd(c))
296 window_val += bit * BN_is_bit_set(scalar, j + w);
297
298 if (window_val > next_bit)
299 { 145 {
300 ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR); 146 ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
301 goto err; 147 goto err;
302 } 148 }
149 if (!BN_rshift1(c, c)) goto err;
303 } 150 }
304 151
305 if (j > len + 1) 152 if (j > len)
306 { 153 {
307 ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR); 154 ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
308 goto err; 155 goto err;
@@ -311,6 +158,7 @@ static signed char *compute_wNAF(const BIGNUM *scalar, int w, size_t *ret_len)
311 ok = 1; 158 ok = 1;
312 159
313 err: 160 err:
161 BN_CTX_end(ctx);
314 if (!ok) 162 if (!ok)
315 { 163 {
316 OPENSSL_free(r); 164 OPENSSL_free(r);
@@ -333,7 +181,7 @@ static signed char *compute_wNAF(const BIGNUM *scalar, int w, size_t *ret_len)
333 (b) >= 300 ? 4 : \ 181 (b) >= 300 ? 4 : \
334 (b) >= 70 ? 3 : \ 182 (b) >= 70 ? 3 : \
335 (b) >= 20 ? 2 : \ 183 (b) >= 20 ? 2 : \
336 1)) 184 1))
337 185
338/* Compute 186/* Compute
339 * \sum scalars[i]*points[i], 187 * \sum scalars[i]*points[i],
@@ -341,15 +189,13 @@ static signed char *compute_wNAF(const BIGNUM *scalar, int w, size_t *ret_len)
341 * scalar*generator 189 * scalar*generator
342 * in the addition if scalar != NULL 190 * in the addition if scalar != NULL
343 */ 191 */
344int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, 192int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
345 size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx) 193 size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx)
346 { 194 {
347 BN_CTX *new_ctx = NULL; 195 BN_CTX *new_ctx = NULL;
348 const EC_POINT *generator = NULL; 196 EC_POINT *generator = NULL;
349 EC_POINT *tmp = NULL; 197 EC_POINT *tmp = NULL;
350 size_t totalnum; 198 size_t totalnum;
351 size_t blocksize = 0, numblocks = 0; /* for wNAF splitting */
352 size_t pre_points_per_block = 0;
353 size_t i, j; 199 size_t i, j;
354 int k; 200 int k;
355 int r_is_inverted = 0; 201 int r_is_inverted = 0;
@@ -361,15 +207,12 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
361 size_t num_val; 207 size_t num_val;
362 EC_POINT **val = NULL; /* precomputation */ 208 EC_POINT **val = NULL; /* precomputation */
363 EC_POINT **v; 209 EC_POINT **v;
364 EC_POINT ***val_sub = NULL; /* pointers to sub-arrays of 'val' or 'pre_comp->points' */ 210 EC_POINT ***val_sub = NULL; /* pointers to sub-arrays of 'val' */
365 const EC_PRE_COMP *pre_comp = NULL;
366 int num_scalar = 0; /* flag: will be set to 1 if 'scalar' must be treated like other scalars,
367 * i.e. precomputation is not available */
368 int ret = 0; 211 int ret = 0;
369 212
370 if (group->meth != r->meth) 213 if (group->meth != r->meth)
371 { 214 {
372 ECerr(EC_F_EC_WNAF_MUL, EC_R_INCOMPATIBLE_OBJECTS); 215 ECerr(EC_F_EC_POINTS_MUL, EC_R_INCOMPATIBLE_OBJECTS);
373 return 0; 216 return 0;
374 } 217 }
375 218
@@ -378,226 +221,59 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
378 return EC_POINT_set_to_infinity(group, r); 221 return EC_POINT_set_to_infinity(group, r);
379 } 222 }
380 223
381 for (i = 0; i < num; i++)
382 {
383 if (group->meth != points[i]->meth)
384 {
385 ECerr(EC_F_EC_WNAF_MUL, EC_R_INCOMPATIBLE_OBJECTS);
386 return 0;
387 }
388 }
389
390 if (ctx == NULL)
391 {
392 ctx = new_ctx = BN_CTX_new();
393 if (ctx == NULL)
394 goto err;
395 }
396
397 if (scalar != NULL) 224 if (scalar != NULL)
398 { 225 {
399 generator = EC_GROUP_get0_generator(group); 226 generator = EC_GROUP_get0_generator(group);
400 if (generator == NULL) 227 if (generator == NULL)
401 { 228 {
402 ECerr(EC_F_EC_WNAF_MUL, EC_R_UNDEFINED_GENERATOR); 229 ECerr(EC_F_EC_POINTS_MUL, EC_R_UNDEFINED_GENERATOR);
403 goto err; 230 return 0;
404 }
405
406 /* look if we can use precomputed multiples of generator */
407
408 pre_comp = EC_EX_DATA_get_data(group->extra_data, ec_pre_comp_dup, ec_pre_comp_free, ec_pre_comp_clear_free);
409
410 if (pre_comp && pre_comp->numblocks && (EC_POINT_cmp(group, generator, pre_comp->points[0], ctx) == 0))
411 {
412 blocksize = pre_comp->blocksize;
413
414 /* determine maximum number of blocks that wNAF splitting may yield
415 * (NB: maximum wNAF length is bit length plus one) */
416 numblocks = (BN_num_bits(scalar) / blocksize) + 1;
417
418 /* we cannot use more blocks than we have precomputation for */
419 if (numblocks > pre_comp->numblocks)
420 numblocks = pre_comp->numblocks;
421
422 pre_points_per_block = 1u << (pre_comp->w - 1);
423
424 /* check that pre_comp looks sane */
425 if (pre_comp->num != (pre_comp->numblocks * pre_points_per_block))
426 {
427 ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
428 goto err;
429 }
430 } 231 }
431 else 232 }
233
234 for (i = 0; i < num; i++)
235 {
236 if (group->meth != points[i]->meth)
432 { 237 {
433 /* can't use precomputation */ 238 ECerr(EC_F_EC_POINTS_MUL, EC_R_INCOMPATIBLE_OBJECTS);
434 pre_comp = NULL; 239 return 0;
435 numblocks = 1;
436 num_scalar = 1; /* treat 'scalar' like 'num'-th element of 'scalars' */
437 } 240 }
438 } 241 }
439
440 totalnum = num + numblocks;
441 242
442 wsize = OPENSSL_malloc(totalnum * sizeof wsize[0]); 243 totalnum = num + (scalar != NULL);
244
245 wsize = OPENSSL_malloc(totalnum * sizeof wsize[0]);
443 wNAF_len = OPENSSL_malloc(totalnum * sizeof wNAF_len[0]); 246 wNAF_len = OPENSSL_malloc(totalnum * sizeof wNAF_len[0]);
444 wNAF = OPENSSL_malloc((totalnum + 1) * sizeof wNAF[0]); /* includes space for pivot */ 247 wNAF = OPENSSL_malloc((totalnum + 1) * sizeof wNAF[0]);
445 val_sub = OPENSSL_malloc(totalnum * sizeof val_sub[0]); 248 if (wNAF != NULL)
446
447 if (!wsize || !wNAF_len || !wNAF || !val_sub)
448 { 249 {
449 ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE); 250 wNAF[0] = NULL; /* preliminary pivot */
450 goto err;
451 } 251 }
252 if (wsize == NULL || wNAF_len == NULL || wNAF == NULL) goto err;
452 253
453 wNAF[0] = NULL; /* preliminary pivot */ 254 /* num_val := total number of points to precompute */
454
455 /* num_val will be the total number of temporarily precomputed points */
456 num_val = 0; 255 num_val = 0;
457 256 for (i = 0; i < totalnum; i++)
458 for (i = 0; i < num + num_scalar; i++)
459 { 257 {
460 size_t bits; 258 size_t bits;
461 259
462 bits = i < num ? BN_num_bits(scalars[i]) : BN_num_bits(scalar); 260 bits = i < num ? BN_num_bits(scalars[i]) : BN_num_bits(scalar);
463 wsize[i] = EC_window_bits_for_scalar_size(bits); 261 wsize[i] = EC_window_bits_for_scalar_size(bits);
464 num_val += 1u << (wsize[i] - 1); 262 num_val += 1u << (wsize[i] - 1);
465 wNAF[i + 1] = NULL; /* make sure we always have a pivot */
466 wNAF[i] = compute_wNAF((i < num ? scalars[i] : scalar), wsize[i], &wNAF_len[i]);
467 if (wNAF[i] == NULL)
468 goto err;
469 if (wNAF_len[i] > max_len)
470 max_len = wNAF_len[i];
471 }
472
473 if (numblocks)
474 {
475 /* we go here iff scalar != NULL */
476
477 if (pre_comp == NULL)
478 {
479 if (num_scalar != 1)
480 {
481 ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
482 goto err;
483 }
484 /* we have already generated a wNAF for 'scalar' */
485 }
486 else
487 {
488 signed char *tmp_wNAF = NULL;
489 size_t tmp_len = 0;
490
491 if (num_scalar != 0)
492 {
493 ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
494 goto err;
495 }
496
497 /* use the window size for which we have precomputation */
498 wsize[num] = pre_comp->w;
499 tmp_wNAF = compute_wNAF(scalar, wsize[num], &tmp_len);
500 if (!tmp_wNAF)
501 goto err;
502
503 if (tmp_len <= max_len)
504 {
505 /* One of the other wNAFs is at least as long
506 * as the wNAF belonging to the generator,
507 * so wNAF splitting will not buy us anything. */
508
509 numblocks = 1;
510 totalnum = num + 1; /* don't use wNAF splitting */
511 wNAF[num] = tmp_wNAF;
512 wNAF[num + 1] = NULL;
513 wNAF_len[num] = tmp_len;
514 if (tmp_len > max_len)
515 max_len = tmp_len;
516 /* pre_comp->points starts with the points that we need here: */
517 val_sub[num] = pre_comp->points;
518 }
519 else
520 {
521 /* don't include tmp_wNAF directly into wNAF array
522 * - use wNAF splitting and include the blocks */
523
524 signed char *pp;
525 EC_POINT **tmp_points;
526
527 if (tmp_len < numblocks * blocksize)
528 {
529 /* possibly we can do with fewer blocks than estimated */
530 numblocks = (tmp_len + blocksize - 1) / blocksize;
531 if (numblocks > pre_comp->numblocks)
532 {
533 ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
534 goto err;
535 }
536 totalnum = num + numblocks;
537 }
538
539 /* split wNAF in 'numblocks' parts */
540 pp = tmp_wNAF;
541 tmp_points = pre_comp->points;
542
543 for (i = num; i < totalnum; i++)
544 {
545 if (i < totalnum - 1)
546 {
547 wNAF_len[i] = blocksize;
548 if (tmp_len < blocksize)
549 {
550 ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
551 goto err;
552 }
553 tmp_len -= blocksize;
554 }
555 else
556 /* last block gets whatever is left
557 * (this could be more or less than 'blocksize'!) */
558 wNAF_len[i] = tmp_len;
559
560 wNAF[i + 1] = NULL;
561 wNAF[i] = OPENSSL_malloc(wNAF_len[i]);
562 if (wNAF[i] == NULL)
563 {
564 ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE);
565 OPENSSL_free(tmp_wNAF);
566 goto err;
567 }
568 memcpy(wNAF[i], pp, wNAF_len[i]);
569 if (wNAF_len[i] > max_len)
570 max_len = wNAF_len[i];
571
572 if (*tmp_points == NULL)
573 {
574 ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
575 OPENSSL_free(tmp_wNAF);
576 goto err;
577 }
578 val_sub[i] = tmp_points;
579 tmp_points += pre_points_per_block;
580 pp += blocksize;
581 }
582 OPENSSL_free(tmp_wNAF);
583 }
584 }
585 } 263 }
586 264
587 /* All points we precompute now go into a single array 'val'. 265 /* all precomputed points go into a single array 'val',
588 * 'val_sub[i]' is a pointer to the subarray for the i-th point, 266 * 'val_sub[i]' is a pointer to the subarray for the i-th point */
589 * or to a subarray of 'pre_comp->points' if we already have precomputation. */
590 val = OPENSSL_malloc((num_val + 1) * sizeof val[0]); 267 val = OPENSSL_malloc((num_val + 1) * sizeof val[0]);
591 if (val == NULL) 268 if (val == NULL) goto err;
592 {
593 ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE);
594 goto err;
595 }
596 val[num_val] = NULL; /* pivot element */ 269 val[num_val] = NULL; /* pivot element */
597 270
271 val_sub = OPENSSL_malloc(totalnum * sizeof val_sub[0]);
272 if (val_sub == NULL) goto err;
273
598 /* allocate points for precomputation */ 274 /* allocate points for precomputation */
599 v = val; 275 v = val;
600 for (i = 0; i < num + num_scalar; i++) 276 for (i = 0; i < totalnum; i++)
601 { 277 {
602 val_sub[i] = v; 278 val_sub[i] = v;
603 for (j = 0; j < (1u << (wsize[i] - 1)); j++) 279 for (j = 0; j < (1u << (wsize[i] - 1)); j++)
@@ -609,12 +285,19 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
609 } 285 }
610 if (!(v == val + num_val)) 286 if (!(v == val + num_val))
611 { 287 {
612 ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR); 288 ECerr(EC_F_EC_POINTS_MUL, ERR_R_INTERNAL_ERROR);
613 goto err; 289 goto err;
614 } 290 }
615 291
616 if (!(tmp = EC_POINT_new(group))) 292 if (ctx == NULL)
617 goto err; 293 {
294 ctx = new_ctx = BN_CTX_new();
295 if (ctx == NULL)
296 goto err;
297 }
298
299 tmp = EC_POINT_new(group);
300 if (tmp == NULL) goto err;
618 301
619 /* prepare precomputed values: 302 /* prepare precomputed values:
620 * val_sub[i][0] := points[i] 303 * val_sub[i][0] := points[i]
@@ -622,7 +305,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
622 * val_sub[i][2] := 5 * points[i] 305 * val_sub[i][2] := 5 * points[i]
623 * ... 306 * ...
624 */ 307 */
625 for (i = 0; i < num + num_scalar; i++) 308 for (i = 0; i < totalnum; i++)
626 { 309 {
627 if (i < num) 310 if (i < num)
628 { 311 {
@@ -641,11 +324,16 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
641 if (!EC_POINT_add(group, val_sub[i][j], val_sub[i][j - 1], tmp, ctx)) goto err; 324 if (!EC_POINT_add(group, val_sub[i][j], val_sub[i][j - 1], tmp, ctx)) goto err;
642 } 325 }
643 } 326 }
327
328 wNAF[i + 1] = NULL; /* make sure we always have a pivot */
329 wNAF[i] = compute_wNAF((i < num ? scalars[i] : scalar), wsize[i], &wNAF_len[i], ctx);
330 if (wNAF[i] == NULL) goto err;
331 if (wNAF_len[i] > max_len)
332 max_len = wNAF_len[i];
644 } 333 }
645 334
646#if 1 /* optional; EC_window_bits_for_scalar_size assumes we do this step */ 335#if 1 /* optional; EC_window_bits_for_scalar_size assumes we do this step */
647 if (!EC_POINTs_make_affine(group, num_val, val, ctx)) 336 if (!EC_POINTs_make_affine(group, num_val, val, ctx)) goto err;
648 goto err;
649#endif 337#endif
650 338
651 r_is_at_infinity = 1; 339 r_is_at_infinity = 1;
@@ -741,198 +429,57 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
741 } 429 }
742 430
743 431
744/* ec_wNAF_precompute_mult() 432int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar, const EC_POINT *point, const BIGNUM *p_scalar, BN_CTX *ctx)
745 * creates an EC_PRE_COMP object with preprecomputed multiples of the generator 433 {
746 * for use with wNAF splitting as implemented in ec_wNAF_mul(). 434 const EC_POINT *points[1];
747 * 435 const BIGNUM *scalars[1];
748 * 'pre_comp->points' is an array of multiples of the generator 436
749 * of the following form: 437 points[0] = point;
750 * points[0] = generator; 438 scalars[0] = p_scalar;
751 * points[1] = 3 * generator; 439
752 * ... 440 return EC_POINTs_mul(group, r, g_scalar, (point != NULL && p_scalar != NULL), points, scalars, ctx);
753 * points[2^(w-1)-1] = (2^(w-1)-1) * generator; 441 }
754 * points[2^(w-1)] = 2^blocksize * generator; 442
755 * points[2^(w-1)+1] = 3 * 2^blocksize * generator; 443
756 * ... 444int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
757 * points[2^(w-1)*(numblocks-1)-1] = (2^(w-1)) * 2^(blocksize*(numblocks-2)) * generator
758 * points[2^(w-1)*(numblocks-1)] = 2^(blocksize*(numblocks-1)) * generator
759 * ...
760 * points[2^(w-1)*numblocks-1] = (2^(w-1)) * 2^(blocksize*(numblocks-1)) * generator
761 * points[2^(w-1)*numblocks] = NULL
762 */
763int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
764 { 445 {
765 const EC_POINT *generator; 446 const EC_POINT *generator;
766 EC_POINT *tmp_point = NULL, *base = NULL, **var;
767 BN_CTX *new_ctx = NULL; 447 BN_CTX *new_ctx = NULL;
768 BIGNUM *order; 448 BIGNUM *order;
769 size_t i, bits, w, pre_points_per_block, blocksize, numblocks, num;
770 EC_POINT **points = NULL;
771 EC_PRE_COMP *pre_comp;
772 int ret = 0; 449 int ret = 0;
773 450
774 /* if there is an old EC_PRE_COMP object, throw it away */
775 EC_EX_DATA_free_data(&group->extra_data, ec_pre_comp_dup, ec_pre_comp_free, ec_pre_comp_clear_free);
776
777 if ((pre_comp = ec_pre_comp_new(group)) == NULL)
778 return 0;
779
780 generator = EC_GROUP_get0_generator(group); 451 generator = EC_GROUP_get0_generator(group);
781 if (generator == NULL) 452 if (generator == NULL)
782 { 453 {
783 ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, EC_R_UNDEFINED_GENERATOR); 454 ECerr(EC_F_EC_GROUP_PRECOMPUTE_MULT, EC_R_UNDEFINED_GENERATOR);
784 goto err; 455 return 0;
785 } 456 }
786 457
787 if (ctx == NULL) 458 if (ctx == NULL)
788 { 459 {
789 ctx = new_ctx = BN_CTX_new(); 460 ctx = new_ctx = BN_CTX_new();
790 if (ctx == NULL) 461 if (ctx == NULL)
791 goto err; 462 return 0;
792 } 463 }
793 464
794 BN_CTX_start(ctx); 465 BN_CTX_start(ctx);
795 order = BN_CTX_get(ctx); 466 order = BN_CTX_get(ctx);
796 if (order == NULL) goto err; 467 if (order == NULL) goto err;
797 468
798 if (!EC_GROUP_get_order(group, order, ctx)) goto err; 469 if (!EC_GROUP_get_order(group, order, ctx)) return 0;
799 if (BN_is_zero(order)) 470 if (BN_is_zero(order))
800 { 471 {
801 ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, EC_R_UNKNOWN_ORDER); 472 ECerr(EC_F_EC_GROUP_PRECOMPUTE_MULT, EC_R_UNKNOWN_ORDER);
802 goto err; 473 goto err;
803 } 474 }
804 475
805 bits = BN_num_bits(order); 476 /* TODO */
806 /* The following parameters mean we precompute (approximately)
807 * one point per bit.
808 *
809 * TBD: The combination 8, 4 is perfect for 160 bits; for other
810 * bit lengths, other parameter combinations might provide better
811 * efficiency.
812 */
813 blocksize = 8;
814 w = 4;
815 if (EC_window_bits_for_scalar_size(bits) > w)
816 {
817 /* let's not make the window too small ... */
818 w = EC_window_bits_for_scalar_size(bits);
819 }
820
821 numblocks = (bits + blocksize - 1) / blocksize; /* max. number of blocks to use for wNAF splitting */
822
823 pre_points_per_block = 1u << (w - 1);
824 num = pre_points_per_block * numblocks; /* number of points to compute and store */
825
826 points = OPENSSL_malloc(sizeof (EC_POINT*)*(num + 1));
827 if (!points)
828 {
829 ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_MALLOC_FAILURE);
830 goto err;
831 }
832
833 var = points;
834 var[num] = NULL; /* pivot */
835 for (i = 0; i < num; i++)
836 {
837 if ((var[i] = EC_POINT_new(group)) == NULL)
838 {
839 ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_MALLOC_FAILURE);
840 goto err;
841 }
842 }
843
844 if (!(tmp_point = EC_POINT_new(group)) || !(base = EC_POINT_new(group)))
845 {
846 ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_MALLOC_FAILURE);
847 goto err;
848 }
849
850 if (!EC_POINT_copy(base, generator))
851 goto err;
852
853 /* do the precomputation */
854 for (i = 0; i < numblocks; i++)
855 {
856 size_t j;
857
858 if (!EC_POINT_dbl(group, tmp_point, base, ctx))
859 goto err;
860
861 if (!EC_POINT_copy(*var++, base))
862 goto err;
863
864 for (j = 1; j < pre_points_per_block; j++, var++)
865 {
866 /* calculate odd multiples of the current base point */
867 if (!EC_POINT_add(group, *var, tmp_point, *(var - 1), ctx))
868 goto err;
869 }
870
871 if (i < numblocks - 1)
872 {
873 /* get the next base (multiply current one by 2^blocksize) */
874 size_t k;
875
876 if (blocksize <= 2)
877 {
878 ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_INTERNAL_ERROR);
879 goto err;
880 }
881
882 if (!EC_POINT_dbl(group, base, tmp_point, ctx))
883 goto err;
884 for (k = 2; k < blocksize; k++)
885 {
886 if (!EC_POINT_dbl(group,base,base,ctx))
887 goto err;
888 }
889 }
890 }
891
892 if (!EC_POINTs_make_affine(group, num, points, ctx))
893 goto err;
894
895 pre_comp->group = group;
896 pre_comp->blocksize = blocksize;
897 pre_comp->numblocks = numblocks;
898 pre_comp->w = w;
899 pre_comp->points = points;
900 points = NULL;
901 pre_comp->num = num;
902
903 if (!EC_EX_DATA_set_data(&group->extra_data, pre_comp,
904 ec_pre_comp_dup, ec_pre_comp_free, ec_pre_comp_clear_free))
905 goto err;
906 pre_comp = NULL;
907 477
908 ret = 1; 478 ret = 1;
479
909 err: 480 err:
910 if (ctx != NULL) 481 BN_CTX_end(ctx);
911 BN_CTX_end(ctx);
912 if (new_ctx != NULL) 482 if (new_ctx != NULL)
913 BN_CTX_free(new_ctx); 483 BN_CTX_free(new_ctx);
914 if (pre_comp)
915 ec_pre_comp_free(pre_comp);
916 if (points)
917 {
918 EC_POINT **p;
919
920 for (p = points; *p != NULL; p++)
921 EC_POINT_free(*p);
922 OPENSSL_free(points);
923 }
924 if (tmp_point)
925 EC_POINT_free(tmp_point);
926 if (base)
927 EC_POINT_free(base);
928 return ret; 484 return ret;
929 } 485 }
930
931
932int ec_wNAF_have_precompute_mult(const EC_GROUP *group)
933 {
934 if (EC_EX_DATA_get_data(group->extra_data, ec_pre_comp_dup, ec_pre_comp_free, ec_pre_comp_clear_free) != NULL)
935 return 1;
936 else
937 return 0;
938 }
diff --git a/src/lib/libcrypto/ec/ecp_mont.c b/src/lib/libcrypto/ec/ecp_mont.c
index 9fc4a466a5..7b30d4c38a 100644
--- a/src/lib/libcrypto/ec/ecp_mont.c
+++ b/src/lib/libcrypto/ec/ecp_mont.c
@@ -1,7 +1,4 @@
1/* crypto/ec/ecp_mont.c */ 1/* crypto/ec/ecp_mont.c */
2/*
3 * Originally written by Bodo Moeller for the OpenSSL project.
4 */
5/* ==================================================================== 2/* ====================================================================
6 * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. 3 * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
7 * 4 *
@@ -55,11 +52,6 @@
55 * Hudson (tjh@cryptsoft.com). 52 * Hudson (tjh@cryptsoft.com).
56 * 53 *
57 */ 54 */
58/* ====================================================================
59 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
60 * Portions of this software developed by SUN MICROSYSTEMS, INC.,
61 * and contributed to the OpenSSL project.
62 */
63 55
64#include <openssl/err.h> 56#include <openssl/err.h>
65 57
@@ -69,15 +61,16 @@
69const EC_METHOD *EC_GFp_mont_method(void) 61const EC_METHOD *EC_GFp_mont_method(void)
70 { 62 {
71 static const EC_METHOD ret = { 63 static const EC_METHOD ret = {
72 NID_X9_62_prime_field,
73 ec_GFp_mont_group_init, 64 ec_GFp_mont_group_init,
74 ec_GFp_mont_group_finish, 65 ec_GFp_mont_group_finish,
75 ec_GFp_mont_group_clear_finish, 66 ec_GFp_mont_group_clear_finish,
76 ec_GFp_mont_group_copy, 67 ec_GFp_mont_group_copy,
77 ec_GFp_mont_group_set_curve, 68 ec_GFp_mont_group_set_curve_GFp,
78 ec_GFp_simple_group_get_curve, 69 ec_GFp_simple_group_get_curve_GFp,
79 ec_GFp_simple_group_get_degree, 70 ec_GFp_simple_group_set_generator,
80 ec_GFp_simple_group_check_discriminant, 71 ec_GFp_simple_group_get0_generator,
72 ec_GFp_simple_group_get_order,
73 ec_GFp_simple_group_get_cofactor,
81 ec_GFp_simple_point_init, 74 ec_GFp_simple_point_init,
82 ec_GFp_simple_point_finish, 75 ec_GFp_simple_point_finish,
83 ec_GFp_simple_point_clear_finish, 76 ec_GFp_simple_point_clear_finish,
@@ -85,9 +78,9 @@ const EC_METHOD *EC_GFp_mont_method(void)
85 ec_GFp_simple_point_set_to_infinity, 78 ec_GFp_simple_point_set_to_infinity,
86 ec_GFp_simple_set_Jprojective_coordinates_GFp, 79 ec_GFp_simple_set_Jprojective_coordinates_GFp,
87 ec_GFp_simple_get_Jprojective_coordinates_GFp, 80 ec_GFp_simple_get_Jprojective_coordinates_GFp,
88 ec_GFp_simple_point_set_affine_coordinates, 81 ec_GFp_simple_point_set_affine_coordinates_GFp,
89 ec_GFp_simple_point_get_affine_coordinates, 82 ec_GFp_simple_point_get_affine_coordinates_GFp,
90 ec_GFp_simple_set_compressed_coordinates, 83 ec_GFp_simple_set_compressed_coordinates_GFp,
91 ec_GFp_simple_point2oct, 84 ec_GFp_simple_point2oct,
92 ec_GFp_simple_oct2point, 85 ec_GFp_simple_oct2point,
93 ec_GFp_simple_add, 86 ec_GFp_simple_add,
@@ -98,12 +91,8 @@ const EC_METHOD *EC_GFp_mont_method(void)
98 ec_GFp_simple_cmp, 91 ec_GFp_simple_cmp,
99 ec_GFp_simple_make_affine, 92 ec_GFp_simple_make_affine,
100 ec_GFp_simple_points_make_affine, 93 ec_GFp_simple_points_make_affine,
101 0 /* mul */,
102 0 /* precompute_mult */,
103 0 /* have_precompute_mult */,
104 ec_GFp_mont_field_mul, 94 ec_GFp_mont_field_mul,
105 ec_GFp_mont_field_sqr, 95 ec_GFp_mont_field_sqr,
106 0 /* field_div */,
107 ec_GFp_mont_field_encode, 96 ec_GFp_mont_field_encode,
108 ec_GFp_mont_field_decode, 97 ec_GFp_mont_field_decode,
109 ec_GFp_mont_field_set_to_one }; 98 ec_GFp_mont_field_set_to_one };
@@ -123,6 +112,66 @@ int ec_GFp_mont_group_init(EC_GROUP *group)
123 } 112 }
124 113
125 114
115int ec_GFp_mont_group_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
116 {
117 BN_CTX *new_ctx = NULL;
118 BN_MONT_CTX *mont = NULL;
119 BIGNUM *one = NULL;
120 int ret = 0;
121
122 if (group->field_data1 != NULL)
123 {
124 BN_MONT_CTX_free(group->field_data1);
125 group->field_data1 = NULL;
126 }
127 if (group->field_data2 != NULL)
128 {
129 BN_free(group->field_data2);
130 group->field_data2 = NULL;
131 }
132
133 if (ctx == NULL)
134 {
135 ctx = new_ctx = BN_CTX_new();
136 if (ctx == NULL)
137 return 0;
138 }
139
140 mont = BN_MONT_CTX_new();
141 if (mont == NULL) goto err;
142 if (!BN_MONT_CTX_set(mont, p, ctx))
143 {
144 ECerr(EC_F_GFP_MONT_GROUP_SET_CURVE_GFP, ERR_R_BN_LIB);
145 goto err;
146 }
147 one = BN_new();
148 if (one == NULL) goto err;
149 if (!BN_to_montgomery(one, BN_value_one(), mont, ctx)) goto err;
150
151 group->field_data1 = mont;
152 mont = NULL;
153 group->field_data2 = one;
154 one = NULL;
155
156 ret = ec_GFp_simple_group_set_curve_GFp(group, p, a, b, ctx);
157
158 if (!ret)
159 {
160 BN_MONT_CTX_free(group->field_data1);
161 group->field_data1 = NULL;
162 BN_free(group->field_data2);
163 group->field_data2 = NULL;
164 }
165
166 err:
167 if (new_ctx != NULL)
168 BN_CTX_free(new_ctx);
169 if (mont != NULL)
170 BN_MONT_CTX_free(mont);
171 return ret;
172 }
173
174
126void ec_GFp_mont_group_finish(EC_GROUP *group) 175void ec_GFp_mont_group_finish(EC_GROUP *group)
127 { 176 {
128 if (group->field_data1 != NULL) 177 if (group->field_data1 != NULL)
@@ -194,66 +243,6 @@ int ec_GFp_mont_group_copy(EC_GROUP *dest, const EC_GROUP *src)
194 } 243 }
195 244
196 245
197int ec_GFp_mont_group_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
198 {
199 BN_CTX *new_ctx = NULL;
200 BN_MONT_CTX *mont = NULL;
201 BIGNUM *one = NULL;
202 int ret = 0;
203
204 if (group->field_data1 != NULL)
205 {
206 BN_MONT_CTX_free(group->field_data1);
207 group->field_data1 = NULL;
208 }
209 if (group->field_data2 != NULL)
210 {
211 BN_free(group->field_data2);
212 group->field_data2 = NULL;
213 }
214
215 if (ctx == NULL)
216 {
217 ctx = new_ctx = BN_CTX_new();
218 if (ctx == NULL)
219 return 0;
220 }
221
222 mont = BN_MONT_CTX_new();
223 if (mont == NULL) goto err;
224 if (!BN_MONT_CTX_set(mont, p, ctx))
225 {
226 ECerr(EC_F_EC_GFP_MONT_GROUP_SET_CURVE, ERR_R_BN_LIB);
227 goto err;
228 }
229 one = BN_new();
230 if (one == NULL) goto err;
231 if (!BN_to_montgomery(one, BN_value_one(), mont, ctx)) goto err;
232
233 group->field_data1 = mont;
234 mont = NULL;
235 group->field_data2 = one;
236 one = NULL;
237
238 ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
239
240 if (!ret)
241 {
242 BN_MONT_CTX_free(group->field_data1);
243 group->field_data1 = NULL;
244 BN_free(group->field_data2);
245 group->field_data2 = NULL;
246 }
247
248 err:
249 if (new_ctx != NULL)
250 BN_CTX_free(new_ctx);
251 if (mont != NULL)
252 BN_MONT_CTX_free(mont);
253 return ret;
254 }
255
256
257int ec_GFp_mont_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) 246int ec_GFp_mont_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
258 { 247 {
259 if (group->field_data1 == NULL) 248 if (group->field_data1 == NULL)
@@ -306,7 +295,7 @@ int ec_GFp_mont_field_set_to_one(const EC_GROUP *group, BIGNUM *r, BN_CTX *ctx)
306 { 295 {
307 if (group->field_data2 == NULL) 296 if (group->field_data2 == NULL)
308 { 297 {
309 ECerr(EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE, EC_R_NOT_INITIALIZED); 298 ECerr(EC_F_EC_GFP_MONT_FIELD_DECODE, EC_R_NOT_INITIALIZED);
310 return 0; 299 return 0;
311 } 300 }
312 301
diff --git a/src/lib/libcrypto/ec/ecp_nist.c b/src/lib/libcrypto/ec/ecp_nist.c
index 71893d5eab..ed07748675 100644
--- a/src/lib/libcrypto/ec/ecp_nist.c
+++ b/src/lib/libcrypto/ec/ecp_nist.c
@@ -1,9 +1,6 @@
1/* crypto/ec/ecp_nist.c */ 1/* crypto/ec/ecp_nist.c */
2/*
3 * Written by Nils Larsch for the OpenSSL project.
4 */
5/* ==================================================================== 2/* ====================================================================
6 * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. 3 * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
7 * 4 *
8 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
@@ -55,30 +52,23 @@
55 * Hudson (tjh@cryptsoft.com). 52 * Hudson (tjh@cryptsoft.com).
56 * 53 *
57 */ 54 */
58/* ====================================================================
59 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
60 * Portions of this software developed by SUN MICROSYSTEMS, INC.,
61 * and contributed to the OpenSSL project.
62 */
63 55
64#include <limits.h>
65
66#include <openssl/err.h>
67#include <openssl/obj_mac.h>
68#include "ec_lcl.h" 56#include "ec_lcl.h"
69 57
58#if 0
70const EC_METHOD *EC_GFp_nist_method(void) 59const EC_METHOD *EC_GFp_nist_method(void)
71 { 60 {
72 static const EC_METHOD ret = { 61 static const EC_METHOD ret = {
73 NID_X9_62_prime_field, 62 ec_GFp_nist_group_init,
74 ec_GFp_simple_group_init, 63 ec_GFp_nist_group_finish,
75 ec_GFp_simple_group_finish, 64 ec_GFp_nist_group_clear_finish,
76 ec_GFp_simple_group_clear_finish,
77 ec_GFp_nist_group_copy, 65 ec_GFp_nist_group_copy,
78 ec_GFp_nist_group_set_curve, 66 ec_GFp_nist_group_set_curve_GFp,
79 ec_GFp_simple_group_get_curve, 67 ec_GFp_simple_group_get_curve_GFp,
80 ec_GFp_simple_group_get_degree, 68 ec_GFp_simple_group_set_generator,
81 ec_GFp_simple_group_check_discriminant, 69 ec_GFp_simple_group_get0_generator,
70 ec_GFp_simple_group_get_order,
71 ec_GFp_simple_group_get_cofactor,
82 ec_GFp_simple_point_init, 72 ec_GFp_simple_point_init,
83 ec_GFp_simple_point_finish, 73 ec_GFp_simple_point_finish,
84 ec_GFp_simple_point_clear_finish, 74 ec_GFp_simple_point_clear_finish,
@@ -86,9 +76,9 @@ const EC_METHOD *EC_GFp_nist_method(void)
86 ec_GFp_simple_point_set_to_infinity, 76 ec_GFp_simple_point_set_to_infinity,
87 ec_GFp_simple_set_Jprojective_coordinates_GFp, 77 ec_GFp_simple_set_Jprojective_coordinates_GFp,
88 ec_GFp_simple_get_Jprojective_coordinates_GFp, 78 ec_GFp_simple_get_Jprojective_coordinates_GFp,
89 ec_GFp_simple_point_set_affine_coordinates, 79 ec_GFp_simple_point_set_affine_coordinates_GFp,
90 ec_GFp_simple_point_get_affine_coordinates, 80 ec_GFp_simple_point_get_affine_coordinates_GFp,
91 ec_GFp_simple_set_compressed_coordinates, 81 ec_GFp_simple_set_compressed_coordinates_GFp,
92 ec_GFp_simple_point2oct, 82 ec_GFp_simple_point2oct,
93 ec_GFp_simple_oct2point, 83 ec_GFp_simple_oct2point,
94 ec_GFp_simple_add, 84 ec_GFp_simple_add,
@@ -99,138 +89,46 @@ const EC_METHOD *EC_GFp_nist_method(void)
99 ec_GFp_simple_cmp, 89 ec_GFp_simple_cmp,
100 ec_GFp_simple_make_affine, 90 ec_GFp_simple_make_affine,
101 ec_GFp_simple_points_make_affine, 91 ec_GFp_simple_points_make_affine,
102 0 /* mul */,
103 0 /* precompute_mult */,
104 0 /* have_precompute_mult */,
105 ec_GFp_nist_field_mul, 92 ec_GFp_nist_field_mul,
106 ec_GFp_nist_field_sqr, 93 ec_GFp_nist_field_sqr,
107 0 /* field_div */,
108 0 /* field_encode */, 94 0 /* field_encode */,
109 0 /* field_decode */, 95 0 /* field_decode */,
110 0 /* field_set_to_one */ }; 96 0 /* field_set_to_one */ };
111 97
112 return &ret; 98 return &ret;
113 } 99 }
114
115#if BN_BITS2 == 64
116#define NO_32_BIT_TYPE
117#endif 100#endif
118 101
119int ec_GFp_nist_group_copy(EC_GROUP *dest, const EC_GROUP *src) 102
103int ec_GFp_nist_group_init(EC_GROUP *group)
120 { 104 {
121 dest->field_mod_func = src->field_mod_func; 105 int ok;
122 106
123 return ec_GFp_simple_group_copy(dest, src); 107 ok = ec_GFp_simple_group_init(group);
108 group->field_data1 = NULL;
109 return ok;
124 } 110 }
125 111
126int ec_GFp_nist_group_set_curve(EC_GROUP *group, const BIGNUM *p,
127 const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
128 {
129 int ret = 0;
130 BN_CTX *new_ctx = NULL;
131 BIGNUM *tmp_bn;
132
133 if (ctx == NULL)
134 if ((ctx = new_ctx = BN_CTX_new()) == NULL) return 0;
135
136 BN_CTX_start(ctx);
137 if ((tmp_bn = BN_CTX_get(ctx)) == NULL) goto err;
138
139 if (BN_ucmp(BN_get0_nist_prime_192(), p) == 0)
140 group->field_mod_func = BN_nist_mod_192;
141 else if (BN_ucmp(BN_get0_nist_prime_224(), p) == 0)
142 {
143#ifndef NO_32_BIT_TYPE
144 group->field_mod_func = BN_nist_mod_224;
145#else
146 ECerr(EC_F_EC_GFP_NIST_GROUP_SET_CURVE, EC_R_NOT_A_SUPPORTED_NIST_PRIME);
147 goto err;
148#endif
149 }
150 else if (BN_ucmp(BN_get0_nist_prime_256(), p) == 0)
151 {
152#ifndef NO_32_BIT_TYPE
153 group->field_mod_func = BN_nist_mod_256;
154#else
155 ECerr(EC_F_EC_GFP_NIST_GROUP_SET_CURVE, EC_R_NOT_A_SUPPORTED_NIST_PRIME);
156 goto err;
157#endif
158 }
159 else if (BN_ucmp(BN_get0_nist_prime_384(), p) == 0)
160 {
161#ifndef NO_32_BIT_TYPE
162 group->field_mod_func = BN_nist_mod_384;
163#else
164 ECerr(EC_F_EC_GFP_NIST_GROUP_SET_CURVE, EC_R_NOT_A_SUPPORTED_NIST_PRIME);
165 goto err;
166#endif
167 }
168 else if (BN_ucmp(BN_get0_nist_prime_521(), p) == 0)
169 /* this one works in the NO_32_BIT_TYPE case */
170 group->field_mod_func = BN_nist_mod_521;
171 else
172 {
173 ECerr(EC_F_EC_GFP_NIST_GROUP_SET_CURVE, EC_R_NOT_A_NIST_PRIME);
174 goto err;
175 }
176
177 ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
178
179 err:
180 BN_CTX_end(ctx);
181 if (new_ctx != NULL)
182 BN_CTX_free(new_ctx);
183 return ret;
184 }
185 112
113int ec_GFp_nist_group_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
114/* TODO */
186 115
187int ec_GFp_nist_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
188 const BIGNUM *b, BN_CTX *ctx)
189 {
190 int ret=0;
191 BN_CTX *ctx_new=NULL;
192
193 if (!group || !r || !a || !b)
194 {
195 ECerr(EC_F_EC_GFP_NIST_FIELD_MUL, ERR_R_PASSED_NULL_PARAMETER);
196 goto err;
197 }
198 if (!ctx)
199 if ((ctx_new = ctx = BN_CTX_new()) == NULL) goto err;
200
201 if (!BN_mul(r, a, b, ctx)) goto err;
202 if (!group->field_mod_func(r, r, &group->field, ctx))
203 goto err;
204
205 ret=1;
206err:
207 if (ctx_new)
208 BN_CTX_free(ctx_new);
209 return ret;
210 }
211 116
117void ec_GFp_nist_group_finish(EC_GROUP *group);
118/* TODO */
212 119
213int ec_GFp_nist_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, 120
214 BN_CTX *ctx) 121void ec_GFp_nist_group_clear_finish(EC_GROUP *group);
215 { 122/* TODO */
216 int ret=0; 123
217 BN_CTX *ctx_new=NULL; 124
218 125int ec_GFp_nist_group_copy(EC_GROUP *dest, const EC_GROUP *src);
219 if (!group || !r || !a) 126/* TODO */
220 { 127
221 ECerr(EC_F_EC_GFP_NIST_FIELD_SQR, EC_R_PASSED_NULL_PARAMETER); 128
222 goto err; 129int ec_GFp_nist_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
223 } 130/* TODO */
224 if (!ctx) 131
225 if ((ctx_new = ctx = BN_CTX_new()) == NULL) goto err; 132
226 133int ec_GFp_nist_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *ctx);
227 if (!BN_sqr(r, a, ctx)) goto err; 134/* TODO */
228 if (!group->field_mod_func(r, r, &group->field, ctx))
229 goto err;
230
231 ret=1;
232err:
233 if (ctx_new)
234 BN_CTX_free(ctx_new);
235 return ret;
236 }
diff --git a/src/lib/libcrypto/ec/ecp_recp.c b/src/lib/libcrypto/ec/ecp_recp.c
new file mode 100644
index 0000000000..fec843b5c8
--- /dev/null
+++ b/src/lib/libcrypto/ec/ecp_recp.c
@@ -0,0 +1,133 @@
1/* crypto/ec/ecp_recp.c */
2/* ====================================================================
3 * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 *
17 * 3. All advertising materials mentioning features or use of this
18 * software must display the following acknowledgment:
19 * "This product includes software developed by the OpenSSL Project
20 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
21 *
22 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
23 * endorse or promote products derived from this software without
24 * prior written permission. For written permission, please contact
25 * openssl-core@openssl.org.
26 *
27 * 5. Products derived from this software may not be called "OpenSSL"
28 * nor may "OpenSSL" appear in their names without prior written
29 * permission of the OpenSSL Project.
30 *
31 * 6. Redistributions of any form whatsoever must retain the following
32 * acknowledgment:
33 * "This product includes software developed by the OpenSSL Project
34 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
35 *
36 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
37 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
40 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
45 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
47 * OF THE POSSIBILITY OF SUCH DAMAGE.
48 * ====================================================================
49 *
50 * This product includes cryptographic software written by Eric Young
51 * (eay@cryptsoft.com). This product includes software written by Tim
52 * Hudson (tjh@cryptsoft.com).
53 *
54 */
55
56#include "ec_lcl.h"
57
58#if 0
59const EC_METHOD *EC_GFp_recp_method(void)
60 {
61 static const EC_METHOD ret = {
62 ec_GFp_recp_group_init,
63 ec_GFp_recp_group_finish,
64 ec_GFp_recp_group_clear_finish,
65 ec_GFp_recp_group_copy,
66 ec_GFp_recp_group_set_curve_GFp,
67 ec_GFp_simple_group_get_curve_GFp,
68 ec_GFp_simple_group_set_generator,
69 ec_GFp_simple_group_get0_generator,
70 ec_GFp_simple_group_get_order,
71 ec_GFp_simple_group_get_cofactor,
72 ec_GFp_simple_point_init,
73 ec_GFp_simple_point_finish,
74 ec_GFp_simple_point_clear_finish,
75 ec_GFp_simple_point_copy,
76 ec_GFp_simple_point_set_to_infinity,
77 ec_GFp_simple_set_Jprojective_coordinates_GFp,
78 ec_GFp_simple_get_Jprojective_coordinates_GFp,
79 ec_GFp_simple_point_set_affine_coordinates_GFp,
80 ec_GFp_simple_point_get_affine_coordinates_GFp,
81 ec_GFp_simple_set_compressed_coordinates_GFp,
82 ec_GFp_simple_point2oct,
83 ec_GFp_simple_oct2point,
84 ec_GFp_simple_add,
85 ec_GFp_simple_dbl,
86 ec_GFp_simple_invert,
87 ec_GFp_simple_is_at_infinity,
88 ec_GFp_simple_is_on_curve,
89 ec_GFp_simple_cmp,
90 ec_GFp_simple_make_affine,
91 ec_GFp_simple_points_make_affine,
92 ec_GFp_recp_field_mul,
93 ec_GFp_recp_field_sqr,
94 0 /* field_encode */,
95 0 /* field_decode */,
96 0 /* field_set_to_one */ };
97
98 return &ret;
99 }
100#endif
101
102int ec_GFp_recp_group_init(EC_GROUP *group)
103 {
104 int ok;
105
106 ok = ec_GFp_simple_group_init(group);
107 group->field_data1 = NULL;
108 return ok;
109 }
110
111
112int ec_GFp_recp_group_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
113/* TODO */
114
115
116void ec_GFp_recp_group_finish(EC_GROUP *group);
117/* TODO */
118
119
120void ec_GFp_recp_group_clear_finish(EC_GROUP *group);
121/* TODO */
122
123
124int ec_GFp_recp_group_copy(EC_GROUP *dest, const EC_GROUP *src);
125/* TODO */
126
127
128int ec_GFp_recp_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
129/* TODO */
130
131
132int ec_GFp_recp_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *ctx);
133/* TODO */
diff --git a/src/lib/libcrypto/ec/ecp_smpl.c b/src/lib/libcrypto/ec/ecp_smpl.c
index 4d26f8bdf6..e9a51fb87a 100644
--- a/src/lib/libcrypto/ec/ecp_smpl.c
+++ b/src/lib/libcrypto/ec/ecp_smpl.c
@@ -1,10 +1,8 @@
1/* crypto/ec/ecp_smpl.c */ 1/* crypto/ec/ecp_smpl.c */
2/* Includes code written by Lenka Fibikova <fibikova@exp-math.uni-essen.de> 2/* Includes code written by Lenka Fibikova <fibikova@exp-math.uni-essen.de>
3 * for the OpenSSL project. 3 * for the OpenSSL project. */
4 * Includes code written by Bodo Moeller for the OpenSSL project.
5*/
6/* ==================================================================== 4/* ====================================================================
7 * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. 5 * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
8 * 6 *
9 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
@@ -56,29 +54,25 @@
56 * Hudson (tjh@cryptsoft.com). 54 * Hudson (tjh@cryptsoft.com).
57 * 55 *
58 */ 56 */
59/* ====================================================================
60 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
61 * Portions of this software developed by SUN MICROSYSTEMS, INC.,
62 * and contributed to the OpenSSL project.
63 */
64 57
65#include <openssl/err.h> 58#include <openssl/err.h>
66#include <openssl/symhacks.h>
67 59
68#include "ec_lcl.h" 60#include "ec_lcl.h"
69 61
62
70const EC_METHOD *EC_GFp_simple_method(void) 63const EC_METHOD *EC_GFp_simple_method(void)
71 { 64 {
72 static const EC_METHOD ret = { 65 static const EC_METHOD ret = {
73 NID_X9_62_prime_field,
74 ec_GFp_simple_group_init, 66 ec_GFp_simple_group_init,
75 ec_GFp_simple_group_finish, 67 ec_GFp_simple_group_finish,
76 ec_GFp_simple_group_clear_finish, 68 ec_GFp_simple_group_clear_finish,
77 ec_GFp_simple_group_copy, 69 ec_GFp_simple_group_copy,
78 ec_GFp_simple_group_set_curve, 70 ec_GFp_simple_group_set_curve_GFp,
79 ec_GFp_simple_group_get_curve, 71 ec_GFp_simple_group_get_curve_GFp,
80 ec_GFp_simple_group_get_degree, 72 ec_GFp_simple_group_set_generator,
81 ec_GFp_simple_group_check_discriminant, 73 ec_GFp_simple_group_get0_generator,
74 ec_GFp_simple_group_get_order,
75 ec_GFp_simple_group_get_cofactor,
82 ec_GFp_simple_point_init, 76 ec_GFp_simple_point_init,
83 ec_GFp_simple_point_finish, 77 ec_GFp_simple_point_finish,
84 ec_GFp_simple_point_clear_finish, 78 ec_GFp_simple_point_clear_finish,
@@ -86,9 +80,9 @@ const EC_METHOD *EC_GFp_simple_method(void)
86 ec_GFp_simple_point_set_to_infinity, 80 ec_GFp_simple_point_set_to_infinity,
87 ec_GFp_simple_set_Jprojective_coordinates_GFp, 81 ec_GFp_simple_set_Jprojective_coordinates_GFp,
88 ec_GFp_simple_get_Jprojective_coordinates_GFp, 82 ec_GFp_simple_get_Jprojective_coordinates_GFp,
89 ec_GFp_simple_point_set_affine_coordinates, 83 ec_GFp_simple_point_set_affine_coordinates_GFp,
90 ec_GFp_simple_point_get_affine_coordinates, 84 ec_GFp_simple_point_get_affine_coordinates_GFp,
91 ec_GFp_simple_set_compressed_coordinates, 85 ec_GFp_simple_set_compressed_coordinates_GFp,
92 ec_GFp_simple_point2oct, 86 ec_GFp_simple_point2oct,
93 ec_GFp_simple_oct2point, 87 ec_GFp_simple_oct2point,
94 ec_GFp_simple_add, 88 ec_GFp_simple_add,
@@ -99,12 +93,8 @@ const EC_METHOD *EC_GFp_simple_method(void)
99 ec_GFp_simple_cmp, 93 ec_GFp_simple_cmp,
100 ec_GFp_simple_make_affine, 94 ec_GFp_simple_make_affine,
101 ec_GFp_simple_points_make_affine, 95 ec_GFp_simple_points_make_affine,
102 0 /* mul */,
103 0 /* precompute_mult */,
104 0 /* have_precompute_mult */,
105 ec_GFp_simple_field_mul, 96 ec_GFp_simple_field_mul,
106 ec_GFp_simple_field_sqr, 97 ec_GFp_simple_field_sqr,
107 0 /* field_div */,
108 0 /* field_encode */, 98 0 /* field_encode */,
109 0 /* field_decode */, 99 0 /* field_decode */,
110 0 /* field_set_to_one */ }; 100 0 /* field_set_to_one */ };
@@ -113,26 +103,15 @@ const EC_METHOD *EC_GFp_simple_method(void)
113 } 103 }
114 104
115 105
116/* Most method functions in this file are designed to work with
117 * non-trivial representations of field elements if necessary
118 * (see ecp_mont.c): while standard modular addition and subtraction
119 * are used, the field_mul and field_sqr methods will be used for
120 * multiplication, and field_encode and field_decode (if defined)
121 * will be used for converting between representations.
122
123 * Functions ec_GFp_simple_points_make_affine() and
124 * ec_GFp_simple_point_get_affine_coordinates() specifically assume
125 * that if a non-trivial representation is used, it is a Montgomery
126 * representation (i.e. 'encoding' means multiplying by some factor R).
127 */
128
129
130int ec_GFp_simple_group_init(EC_GROUP *group) 106int ec_GFp_simple_group_init(EC_GROUP *group)
131 { 107 {
132 BN_init(&group->field); 108 BN_init(&group->field);
133 BN_init(&group->a); 109 BN_init(&group->a);
134 BN_init(&group->b); 110 BN_init(&group->b);
135 group->a_is_minus3 = 0; 111 group->a_is_minus3 = 0;
112 group->generator = NULL;
113 BN_init(&group->order);
114 BN_init(&group->cofactor);
136 return 1; 115 return 1;
137 } 116 }
138 117
@@ -142,6 +121,10 @@ void ec_GFp_simple_group_finish(EC_GROUP *group)
142 BN_free(&group->field); 121 BN_free(&group->field);
143 BN_free(&group->a); 122 BN_free(&group->a);
144 BN_free(&group->b); 123 BN_free(&group->b);
124 if (group->generator != NULL)
125 EC_POINT_free(group->generator);
126 BN_free(&group->order);
127 BN_free(&group->cofactor);
145 } 128 }
146 129
147 130
@@ -150,6 +133,13 @@ void ec_GFp_simple_group_clear_finish(EC_GROUP *group)
150 BN_clear_free(&group->field); 133 BN_clear_free(&group->field);
151 BN_clear_free(&group->a); 134 BN_clear_free(&group->a);
152 BN_clear_free(&group->b); 135 BN_clear_free(&group->b);
136 if (group->generator != NULL)
137 {
138 EC_POINT_clear_free(group->generator);
139 group->generator = NULL;
140 }
141 BN_clear_free(&group->order);
142 BN_clear_free(&group->cofactor);
153 } 143 }
154 144
155 145
@@ -161,11 +151,33 @@ int ec_GFp_simple_group_copy(EC_GROUP *dest, const EC_GROUP *src)
161 151
162 dest->a_is_minus3 = src->a_is_minus3; 152 dest->a_is_minus3 = src->a_is_minus3;
163 153
154 if (src->generator != NULL)
155 {
156 if (dest->generator == NULL)
157 {
158 dest->generator = EC_POINT_new(dest);
159 if (dest->generator == NULL) return 0;
160 }
161 if (!EC_POINT_copy(dest->generator, src->generator)) return 0;
162 }
163 else
164 {
165 /* src->generator == NULL */
166 if (dest->generator != NULL)
167 {
168 EC_POINT_clear_free(dest->generator);
169 dest->generator = NULL;
170 }
171 }
172
173 if (!BN_copy(&dest->order, &src->order)) return 0;
174 if (!BN_copy(&dest->cofactor, &src->cofactor)) return 0;
175
164 return 1; 176 return 1;
165 } 177 }
166 178
167 179
168int ec_GFp_simple_group_set_curve(EC_GROUP *group, 180int ec_GFp_simple_group_set_curve_GFp(EC_GROUP *group,
169 const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) 181 const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
170 { 182 {
171 int ret = 0; 183 int ret = 0;
@@ -175,7 +187,7 @@ int ec_GFp_simple_group_set_curve(EC_GROUP *group,
175 /* p must be a prime > 3 */ 187 /* p must be a prime > 3 */
176 if (BN_num_bits(p) <= 2 || !BN_is_odd(p)) 188 if (BN_num_bits(p) <= 2 || !BN_is_odd(p))
177 { 189 {
178 ECerr(EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE, EC_R_INVALID_FIELD); 190 ECerr(EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP, EC_R_INVALID_FIELD);
179 return 0; 191 return 0;
180 } 192 }
181 193
@@ -192,7 +204,7 @@ int ec_GFp_simple_group_set_curve(EC_GROUP *group,
192 204
193 /* group->field */ 205 /* group->field */
194 if (!BN_copy(&group->field, p)) goto err; 206 if (!BN_copy(&group->field, p)) goto err;
195 BN_set_negative(&group->field, 0); 207 group->field.neg = 0;
196 208
197 /* group->a */ 209 /* group->a */
198 if (!BN_nnmod(tmp_a, a, p, ctx)) goto err; 210 if (!BN_nnmod(tmp_a, a, p, ctx)) goto err;
@@ -220,7 +232,7 @@ int ec_GFp_simple_group_set_curve(EC_GROUP *group,
220 } 232 }
221 233
222 234
223int ec_GFp_simple_group_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx) 235int ec_GFp_simple_group_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx)
224 { 236 {
225 int ret = 0; 237 int ret = 0;
226 BN_CTX *new_ctx = NULL; 238 BN_CTX *new_ctx = NULL;
@@ -271,76 +283,58 @@ int ec_GFp_simple_group_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, B
271 } 283 }
272 284
273 285
274int ec_GFp_simple_group_get_degree(const EC_GROUP *group)
275 {
276 return BN_num_bits(&group->field);
277 }
278
279 286
280int ec_GFp_simple_group_check_discriminant(const EC_GROUP *group, BN_CTX *ctx) 287int ec_GFp_simple_group_set_generator(EC_GROUP *group, const EC_POINT *generator,
288 const BIGNUM *order, const BIGNUM *cofactor)
281 { 289 {
282 int ret = 0; 290 if (generator == NULL)
283 BIGNUM *a,*b,*order,*tmp_1,*tmp_2;
284 const BIGNUM *p = &group->field;
285 BN_CTX *new_ctx = NULL;
286
287 if (ctx == NULL)
288 { 291 {
289 ctx = new_ctx = BN_CTX_new(); 292 ECerr(EC_F_EC_GFP_SIMPLE_GROUP_SET_GENERATOR, ERR_R_PASSED_NULL_PARAMETER);
290 if (ctx == NULL) 293 return 0 ;
291 {
292 ECerr(EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT, ERR_R_MALLOC_FAILURE);
293 goto err;
294 }
295 } 294 }
296 BN_CTX_start(ctx);
297 a = BN_CTX_get(ctx);
298 b = BN_CTX_get(ctx);
299 tmp_1 = BN_CTX_get(ctx);
300 tmp_2 = BN_CTX_get(ctx);
301 order = BN_CTX_get(ctx);
302 if (order == NULL) goto err;
303 295
304 if (group->meth->field_decode) 296 if (group->generator == NULL)
305 { 297 {
306 if (!group->meth->field_decode(group, a, &group->a, ctx)) goto err; 298 group->generator = EC_POINT_new(group);
307 if (!group->meth->field_decode(group, b, &group->b, ctx)) goto err; 299 if (group->generator == NULL) return 0;
308 } 300 }
301 if (!EC_POINT_copy(group->generator, generator)) return 0;
302
303 if (order != NULL)
304 { if (!BN_copy(&group->order, order)) return 0; }
309 else 305 else
310 { 306 { if (!BN_zero(&group->order)) return 0; }
311 if (!BN_copy(a, &group->a)) goto err;
312 if (!BN_copy(b, &group->b)) goto err;
313 }
314
315 /* check the discriminant:
316 * y^2 = x^3 + a*x + b is an elliptic curve <=> 4*a^3 + 27*b^2 != 0 (mod p)
317 * 0 =< a, b < p */
318 if (BN_is_zero(a))
319 {
320 if (BN_is_zero(b)) goto err;
321 }
322 else if (!BN_is_zero(b))
323 {
324 if (!BN_mod_sqr(tmp_1, a, p, ctx)) goto err;
325 if (!BN_mod_mul(tmp_2, tmp_1, a, p, ctx)) goto err;
326 if (!BN_lshift(tmp_1, tmp_2, 2)) goto err;
327 /* tmp_1 = 4*a^3 */
328 307
329 if (!BN_mod_sqr(tmp_2, b, p, ctx)) goto err; 308 if (cofactor != NULL)
330 if (!BN_mul_word(tmp_2, 27)) goto err; 309 { if (!BN_copy(&group->cofactor, cofactor)) return 0; }
331 /* tmp_2 = 27*b^2 */ 310 else
311 { if (!BN_zero(&group->cofactor)) return 0; }
332 312
333 if (!BN_mod_add(a, tmp_1, tmp_2, p, ctx)) goto err; 313 return 1;
334 if (BN_is_zero(a)) goto err; 314 }
335 }
336 ret = 1;
337 315
338err: 316
339 if (ctx != NULL) 317EC_POINT *ec_GFp_simple_group_get0_generator(const EC_GROUP *group)
340 BN_CTX_end(ctx); 318 {
341 if (new_ctx != NULL) 319 return group->generator;
342 BN_CTX_free(new_ctx); 320 }
343 return ret; 321
322
323int ec_GFp_simple_group_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx)
324 {
325 if (!BN_copy(order, &group->order))
326 return 0;
327
328 return !BN_is_zero(&group->order);
329 }
330
331
332int ec_GFp_simple_group_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, BN_CTX *ctx)
333 {
334 if (!BN_copy(cofactor, &group->cofactor))
335 return 0;
336
337 return !BN_is_zero(&group->cofactor);
344 } 338 }
345 339
346 340
@@ -386,8 +380,7 @@ int ec_GFp_simple_point_copy(EC_POINT *dest, const EC_POINT *src)
386int ec_GFp_simple_point_set_to_infinity(const EC_GROUP *group, EC_POINT *point) 380int ec_GFp_simple_point_set_to_infinity(const EC_GROUP *group, EC_POINT *point)
387 { 381 {
388 point->Z_is_one = 0; 382 point->Z_is_one = 0;
389 BN_zero(&point->Z); 383 return (BN_zero(&point->Z));
390 return 1;
391 } 384 }
392 385
393 386
@@ -504,13 +497,13 @@ int ec_GFp_simple_get_Jprojective_coordinates_GFp(const EC_GROUP *group, const E
504 } 497 }
505 498
506 499
507int ec_GFp_simple_point_set_affine_coordinates(const EC_GROUP *group, EC_POINT *point, 500int ec_GFp_simple_point_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
508 const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx) 501 const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx)
509 { 502 {
510 if (x == NULL || y == NULL) 503 if (x == NULL || y == NULL)
511 { 504 {
512 /* unlike for projective coordinates, we do not tolerate this */ 505 /* unlike for projective coordinates, we do not tolerate this */
513 ECerr(EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES, ERR_R_PASSED_NULL_PARAMETER); 506 ECerr(EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES_GFP, ERR_R_PASSED_NULL_PARAMETER);
514 return 0; 507 return 0;
515 } 508 }
516 509
@@ -518,17 +511,17 @@ int ec_GFp_simple_point_set_affine_coordinates(const EC_GROUP *group, EC_POINT *
518 } 511 }
519 512
520 513
521int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *group, const EC_POINT *point, 514int ec_GFp_simple_point_get_affine_coordinates_GFp(const EC_GROUP *group, const EC_POINT *point,
522 BIGNUM *x, BIGNUM *y, BN_CTX *ctx) 515 BIGNUM *x, BIGNUM *y, BN_CTX *ctx)
523 { 516 {
524 BN_CTX *new_ctx = NULL; 517 BN_CTX *new_ctx = NULL;
525 BIGNUM *Z, *Z_1, *Z_2, *Z_3; 518 BIGNUM *X, *Y, *Z, *Z_1, *Z_2, *Z_3;
526 const BIGNUM *Z_; 519 const BIGNUM *X_, *Y_, *Z_;
527 int ret = 0; 520 int ret = 0;
528 521
529 if (EC_POINT_is_at_infinity(group, point)) 522 if (EC_POINT_is_at_infinity(group, point))
530 { 523 {
531 ECerr(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES, EC_R_POINT_AT_INFINITY); 524 ECerr(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES_GFP, EC_R_POINT_AT_INFINITY);
532 return 0; 525 return 0;
533 } 526 }
534 527
@@ -540,6 +533,8 @@ int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *group, const EC_P
540 } 533 }
541 534
542 BN_CTX_start(ctx); 535 BN_CTX_start(ctx);
536 X = BN_CTX_get(ctx);
537 Y = BN_CTX_get(ctx);
543 Z = BN_CTX_get(ctx); 538 Z = BN_CTX_get(ctx);
544 Z_1 = BN_CTX_get(ctx); 539 Z_1 = BN_CTX_get(ctx);
545 Z_2 = BN_CTX_get(ctx); 540 Z_2 = BN_CTX_get(ctx);
@@ -550,44 +545,34 @@ int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *group, const EC_P
550 545
551 if (group->meth->field_decode) 546 if (group->meth->field_decode)
552 { 547 {
548 if (!group->meth->field_decode(group, X, &point->X, ctx)) goto err;
549 if (!group->meth->field_decode(group, Y, &point->Y, ctx)) goto err;
553 if (!group->meth->field_decode(group, Z, &point->Z, ctx)) goto err; 550 if (!group->meth->field_decode(group, Z, &point->Z, ctx)) goto err;
554 Z_ = Z; 551 X_ = X; Y_ = Y; Z_ = Z;
555 } 552 }
556 else 553 else
557 { 554 {
555 X_ = &point->X;
556 Y_ = &point->Y;
558 Z_ = &point->Z; 557 Z_ = &point->Z;
559 } 558 }
560 559
561 if (BN_is_one(Z_)) 560 if (BN_is_one(Z_))
562 { 561 {
563 if (group->meth->field_decode) 562 if (x != NULL)
564 { 563 {
565 if (x != NULL) 564 if (!BN_copy(x, X_)) goto err;
566 {
567 if (!group->meth->field_decode(group, x, &point->X, ctx)) goto err;
568 }
569 if (y != NULL)
570 {
571 if (!group->meth->field_decode(group, y, &point->Y, ctx)) goto err;
572 }
573 } 565 }
574 else 566 if (y != NULL)
575 { 567 {
576 if (x != NULL) 568 if (!BN_copy(y, Y_)) goto err;
577 {
578 if (!BN_copy(x, &point->X)) goto err;
579 }
580 if (y != NULL)
581 {
582 if (!BN_copy(y, &point->Y)) goto err;
583 }
584 } 569 }
585 } 570 }
586 else 571 else
587 { 572 {
588 if (!BN_mod_inverse(Z_1, Z_, &group->field, ctx)) 573 if (!BN_mod_inverse(Z_1, Z_, &group->field, ctx))
589 { 574 {
590 ECerr(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES, ERR_R_BN_LIB); 575 ECerr(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES_GFP, ERR_R_BN_LIB);
591 goto err; 576 goto err;
592 } 577 }
593 578
@@ -603,8 +588,15 @@ int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *group, const EC_P
603 588
604 if (x != NULL) 589 if (x != NULL)
605 { 590 {
606 /* in the Montgomery case, field_mul will cancel out Montgomery factor in X: */ 591 if (group->meth->field_encode == 0)
607 if (!group->meth->field_mul(group, x, &point->X, Z_2, ctx)) goto err; 592 {
593 /* field_mul works on standard representation */
594 if (!group->meth->field_mul(group, x, X_, Z_2, ctx)) goto err;
595 }
596 else
597 {
598 if (!BN_mod_mul(x, X_, Z_2, &group->field, ctx)) goto err;
599 }
608 } 600 }
609 601
610 if (y != NULL) 602 if (y != NULL)
@@ -613,14 +605,14 @@ int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *group, const EC_P
613 { 605 {
614 /* field_mul works on standard representation */ 606 /* field_mul works on standard representation */
615 if (!group->meth->field_mul(group, Z_3, Z_2, Z_1, ctx)) goto err; 607 if (!group->meth->field_mul(group, Z_3, Z_2, Z_1, ctx)) goto err;
608 if (!group->meth->field_mul(group, y, Y_, Z_3, ctx)) goto err;
609
616 } 610 }
617 else 611 else
618 { 612 {
619 if (!BN_mod_mul(Z_3, Z_2, Z_1, &group->field, ctx)) goto err; 613 if (!BN_mod_mul(Z_3, Z_2, Z_1, &group->field, ctx)) goto err;
614 if (!BN_mod_mul(y, Y_, Z_3, &group->field, ctx)) goto err;
620 } 615 }
621
622 /* in the Montgomery case, field_mul will cancel out Montgomery factor in Y: */
623 if (!group->meth->field_mul(group, y, &point->Y, Z_3, ctx)) goto err;
624 } 616 }
625 } 617 }
626 618
@@ -634,16 +626,13 @@ int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *group, const EC_P
634 } 626 }
635 627
636 628
637int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *point, 629int ec_GFp_simple_set_compressed_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
638 const BIGNUM *x_, int y_bit, BN_CTX *ctx) 630 const BIGNUM *x_, int y_bit, BN_CTX *ctx)
639 { 631 {
640 BN_CTX *new_ctx = NULL; 632 BN_CTX *new_ctx = NULL;
641 BIGNUM *tmp1, *tmp2, *x, *y; 633 BIGNUM *tmp1, *tmp2, *x, *y;
642 int ret = 0; 634 int ret = 0;
643 635
644 /* clear error queue*/
645 ERR_clear_error();
646
647 if (ctx == NULL) 636 if (ctx == NULL)
648 { 637 {
649 ctx = new_ctx = BN_CTX_new(); 638 ctx = new_ctx = BN_CTX_new();
@@ -715,17 +704,19 @@ int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *po
715 704
716 if (!BN_mod_sqrt(y, tmp1, &group->field, ctx)) 705 if (!BN_mod_sqrt(y, tmp1, &group->field, ctx))
717 { 706 {
718 unsigned long err = ERR_peek_last_error(); 707 unsigned long err = ERR_peek_error();
719 708
720 if (ERR_GET_LIB(err) == ERR_LIB_BN && ERR_GET_REASON(err) == BN_R_NOT_A_SQUARE) 709 if (ERR_GET_LIB(err) == ERR_LIB_BN && ERR_GET_REASON(err) == BN_R_NOT_A_SQUARE)
721 { 710 {
722 ERR_clear_error(); 711 (void)ERR_get_error();
723 ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSED_POINT); 712 ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES_GFP, EC_R_INVALID_COMPRESSED_POINT);
724 } 713 }
725 else 714 else
726 ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, ERR_R_BN_LIB); 715 ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES_GFP, ERR_R_BN_LIB);
727 goto err; 716 goto err;
728 } 717 }
718 /* If tmp1 is not a square (i.e. there is no point on the curve with
719 * our x), then y now is a nonsense value too */
729 720
730 if (y_bit != BN_is_odd(y)) 721 if (y_bit != BN_is_odd(y))
731 { 722 {
@@ -737,17 +728,16 @@ int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *po
737 if (kron == -2) goto err; 728 if (kron == -2) goto err;
738 729
739 if (kron == 1) 730 if (kron == 1)
740 ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSION_BIT); 731 ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES_GFP, EC_R_INVALID_COMPRESSION_BIT);
741 else 732 else
742 /* BN_mod_sqrt() should have cought this error (not a square) */ 733 ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES_GFP, EC_R_INVALID_COMPRESSED_POINT);
743 ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSED_POINT);
744 goto err; 734 goto err;
745 } 735 }
746 if (!BN_usub(y, &group->field, y)) goto err; 736 if (!BN_usub(y, &group->field, y)) goto err;
747 } 737 }
748 if (y_bit != BN_is_odd(y)) 738 if (y_bit != BN_is_odd(y))
749 { 739 {
750 ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, ERR_R_INTERNAL_ERROR); 740 ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES_GFP, ERR_R_INTERNAL_ERROR);
751 goto err; 741 goto err;
752 } 742 }
753 743
@@ -1098,7 +1088,7 @@ int ec_GFp_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, con
1098 else 1088 else
1099 { 1089 {
1100 /* a is the inverse of b */ 1090 /* a is the inverse of b */
1101 BN_zero(&r->Z); 1091 if (!BN_zero(&r->Z)) goto end;
1102 r->Z_is_one = 0; 1092 r->Z_is_one = 0;
1103 ret = 1; 1093 ret = 1;
1104 goto end; 1094 goto end;
@@ -1174,7 +1164,7 @@ int ec_GFp_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_
1174 1164
1175 if (EC_POINT_is_at_infinity(group, a)) 1165 if (EC_POINT_is_at_infinity(group, a))
1176 { 1166 {
1177 BN_zero(&r->Z); 1167 if (!BN_zero(&r->Z)) return 0;
1178 r->Z_is_one = 0; 1168 r->Z_is_one = 0;
1179 return 1; 1169 return 1;
1180 } 1170 }
@@ -1302,7 +1292,7 @@ int ec_GFp_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_C
1302 int (*field_sqr)(const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *); 1292 int (*field_sqr)(const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
1303 const BIGNUM *p; 1293 const BIGNUM *p;
1304 BN_CTX *new_ctx = NULL; 1294 BN_CTX *new_ctx = NULL;
1305 BIGNUM *rh, *tmp, *Z4, *Z6; 1295 BIGNUM *rh, *tmp1, *tmp2, *Z4, *Z6;
1306 int ret = -1; 1296 int ret = -1;
1307 1297
1308 if (EC_POINT_is_at_infinity(group, point)) 1298 if (EC_POINT_is_at_infinity(group, point))
@@ -1321,7 +1311,8 @@ int ec_GFp_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_C
1321 1311
1322 BN_CTX_start(ctx); 1312 BN_CTX_start(ctx);
1323 rh = BN_CTX_get(ctx); 1313 rh = BN_CTX_get(ctx);
1324 tmp = BN_CTX_get(ctx); 1314 tmp1 = BN_CTX_get(ctx);
1315 tmp2 = BN_CTX_get(ctx);
1325 Z4 = BN_CTX_get(ctx); 1316 Z4 = BN_CTX_get(ctx);
1326 Z6 = BN_CTX_get(ctx); 1317 Z6 = BN_CTX_get(ctx);
1327 if (Z6 == NULL) goto err; 1318 if (Z6 == NULL) goto err;
@@ -1335,49 +1326,59 @@ int ec_GFp_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_C
1335 * To test this, we add up the right-hand side in 'rh'. 1326 * To test this, we add up the right-hand side in 'rh'.
1336 */ 1327 */
1337 1328
1338 /* rh := X^2 */ 1329 /* rh := X^3 */
1339 if (!field_sqr(group, rh, &point->X, ctx)) goto err; 1330 if (!field_sqr(group, rh, &point->X, ctx)) goto err;
1331 if (!field_mul(group, rh, rh, &point->X, ctx)) goto err;
1340 1332
1341 if (!point->Z_is_one) 1333 if (!point->Z_is_one)
1342 { 1334 {
1343 if (!field_sqr(group, tmp, &point->Z, ctx)) goto err; 1335 if (!field_sqr(group, tmp1, &point->Z, ctx)) goto err;
1344 if (!field_sqr(group, Z4, tmp, ctx)) goto err; 1336 if (!field_sqr(group, Z4, tmp1, ctx)) goto err;
1345 if (!field_mul(group, Z6, Z4, tmp, ctx)) goto err; 1337 if (!field_mul(group, Z6, Z4, tmp1, ctx)) goto err;
1346 1338
1347 /* rh := (rh + a*Z^4)*X */ 1339 /* rh := rh + a*X*Z^4 */
1340 if (!field_mul(group, tmp1, &point->X, Z4, ctx)) goto err;
1348 if (group->a_is_minus3) 1341 if (group->a_is_minus3)
1349 { 1342 {
1350 if (!BN_mod_lshift1_quick(tmp, Z4, p)) goto err; 1343 if (!BN_mod_lshift1_quick(tmp2, tmp1, p)) goto err;
1351 if (!BN_mod_add_quick(tmp, tmp, Z4, p)) goto err; 1344 if (!BN_mod_add_quick(tmp2, tmp2, tmp1, p)) goto err;
1352 if (!BN_mod_sub_quick(rh, rh, tmp, p)) goto err; 1345 if (!BN_mod_sub_quick(rh, rh, tmp2, p)) goto err;
1353 if (!field_mul(group, rh, rh, &point->X, ctx)) goto err;
1354 } 1346 }
1355 else 1347 else
1356 { 1348 {
1357 if (!field_mul(group, tmp, Z4, &group->a, ctx)) goto err; 1349 if (!field_mul(group, tmp2, tmp1, &group->a, ctx)) goto err;
1358 if (!BN_mod_add_quick(rh, rh, tmp, p)) goto err; 1350 if (!BN_mod_add_quick(rh, rh, tmp2, p)) goto err;
1359 if (!field_mul(group, rh, rh, &point->X, ctx)) goto err;
1360 } 1351 }
1361 1352
1362 /* rh := rh + b*Z^6 */ 1353 /* rh := rh + b*Z^6 */
1363 if (!field_mul(group, tmp, &group->b, Z6, ctx)) goto err; 1354 if (!field_mul(group, tmp1, &group->b, Z6, ctx)) goto err;
1364 if (!BN_mod_add_quick(rh, rh, tmp, p)) goto err; 1355 if (!BN_mod_add_quick(rh, rh, tmp1, p)) goto err;
1365 } 1356 }
1366 else 1357 else
1367 { 1358 {
1368 /* point->Z_is_one */ 1359 /* point->Z_is_one */
1369 1360
1370 /* rh := (rh + a)*X */ 1361 /* rh := rh + a*X */
1371 if (!BN_mod_add_quick(rh, rh, &group->a, p)) goto err; 1362 if (group->a_is_minus3)
1372 if (!field_mul(group, rh, rh, &point->X, ctx)) goto err; 1363 {
1364 if (!BN_mod_lshift1_quick(tmp2, &point->X, p)) goto err;
1365 if (!BN_mod_add_quick(tmp2, tmp2, &point->X, p)) goto err;
1366 if (!BN_mod_sub_quick(rh, rh, tmp2, p)) goto err;
1367 }
1368 else
1369 {
1370 if (!field_mul(group, tmp2, &point->X, &group->a, ctx)) goto err;
1371 if (!BN_mod_add_quick(rh, rh, tmp2, p)) goto err;
1372 }
1373
1373 /* rh := rh + b */ 1374 /* rh := rh + b */
1374 if (!BN_mod_add_quick(rh, rh, &group->b, p)) goto err; 1375 if (!BN_mod_add_quick(rh, rh, &group->b, p)) goto err;
1375 } 1376 }
1376 1377
1377 /* 'lh' := Y^2 */ 1378 /* 'lh' := Y^2 */
1378 if (!field_sqr(group, tmp, &point->Y, ctx)) goto err; 1379 if (!field_sqr(group, tmp1, &point->Y, ctx)) goto err;
1379 1380
1380 ret = (0 == BN_ucmp(tmp, rh)); 1381 ret = (0 == BN_cmp(tmp1, rh));
1381 1382
1382 err: 1383 err:
1383 BN_CTX_end(ctx); 1384 BN_CTX_end(ctx);
diff --git a/src/lib/libcrypto/ec/ectest.c b/src/lib/libcrypto/ec/ectest.c
new file mode 100644
index 0000000000..fcf969f3cf
--- /dev/null
+++ b/src/lib/libcrypto/ec/ectest.c
@@ -0,0 +1,643 @@
1/* crypto/ec/ectest.c */
2/* ====================================================================
3 * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 *
17 * 3. All advertising materials mentioning features or use of this
18 * software must display the following acknowledgment:
19 * "This product includes software developed by the OpenSSL Project
20 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
21 *
22 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
23 * endorse or promote products derived from this software without
24 * prior written permission. For written permission, please contact
25 * openssl-core@openssl.org.
26 *
27 * 5. Products derived from this software may not be called "OpenSSL"
28 * nor may "OpenSSL" appear in their names without prior written
29 * permission of the OpenSSL Project.
30 *
31 * 6. Redistributions of any form whatsoever must retain the following
32 * acknowledgment:
33 * "This product includes software developed by the OpenSSL Project
34 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
35 *
36 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
37 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
40 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
45 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
47 * OF THE POSSIBILITY OF SUCH DAMAGE.
48 * ====================================================================
49 *
50 * This product includes cryptographic software written by Eric Young
51 * (eay@cryptsoft.com). This product includes software written by Tim
52 * Hudson (tjh@cryptsoft.com).
53 *
54 */
55
56#include <stdio.h>
57#include <stdlib.h>
58#ifdef FLAT_INC
59#include "e_os.h"
60#else
61#include "../e_os.h"
62#endif
63#include <string.h>
64#include <time.h>
65
66
67#ifdef OPENSSL_NO_EC
68int main(int argc, char * argv[]) { puts("Elliptic curves are disabled."); return 0; }
69#else
70
71
72#include <openssl/ec.h>
73#ifndef OPENSSL_NO_ENGINE
74#include <openssl/engine.h>
75#endif
76#include <openssl/err.h>
77
78#define ABORT do { \
79 fflush(stdout); \
80 fprintf(stderr, "%s:%d: ABORT\n", __FILE__, __LINE__); \
81 ERR_print_errors_fp(stderr); \
82 EXIT(1); \
83} while (0)
84
85#if 0
86static void timings(EC_GROUP *group, int multi, BN_CTX *ctx)
87 {
88 clock_t clck;
89 int i, j;
90 BIGNUM *s, *s0;
91 EC_POINT *P;
92
93 s = BN_new();
94 s0 = BN_new();
95 if (s == NULL || s0 == NULL) ABORT;
96
97 if (!EC_GROUP_get_curve_GFp(group, s, NULL, NULL, ctx)) ABORT;
98 fprintf(stdout, "Timings for %d bit prime, ", (int)BN_num_bits(s));
99 if (!EC_GROUP_get_order(group, s, ctx)) ABORT;
100 fprintf(stdout, "%d bit scalars ", (int)BN_num_bits(s));
101 fflush(stdout);
102
103 P = EC_POINT_new(group);
104 if (P == NULL) ABORT;
105 EC_POINT_copy(P, EC_GROUP_get0_generator(group));
106
107 clck = clock();
108 for (i = 0; i < 10; i++)
109 {
110 if (!BN_pseudo_rand(s, BN_num_bits(s), 0, 0)) ABORT;
111 if (multi)
112 {
113 if (!BN_pseudo_rand(s0, BN_num_bits(s), 0, 0)) ABORT;
114 }
115 for (j = 0; j < 10; j++)
116 {
117 if (!EC_POINT_mul(group, P, s, multi ? P : NULL, multi ? s0 : NULL, ctx)) ABORT;
118 }
119 fprintf(stdout, ".");
120 fflush(stdout);
121 }
122 fprintf(stdout, "\n");
123
124 clck = clock() - clck;
125
126#ifdef CLOCKS_PER_SEC
127 /* "To determine the time in seconds, the value returned
128 * by the clock function should be divided by the value
129 * of the macro CLOCKS_PER_SEC."
130 * -- ISO/IEC 9899 */
131# define UNIT "s"
132#else
133 /* "`CLOCKS_PER_SEC' undeclared (first use this function)"
134 * -- cc on NeXTstep/OpenStep */
135# define UNIT "units"
136# define CLOCKS_PER_SEC 1
137#endif
138
139 fprintf(stdout, "%i %s in %.2f " UNIT "\n", i*j,
140 multi ? "s*P+t*Q operations" : "point multiplications",
141 (double)clck/CLOCKS_PER_SEC);
142 fprintf(stdout, "average: %.4f " UNIT "\n", (double)clck/(CLOCKS_PER_SEC*i*j));
143
144 EC_POINT_free(P);
145 BN_free(s);
146 BN_free(s0);
147 }
148#endif
149
150int main(int argc, char *argv[])
151 {
152 BN_CTX *ctx = NULL;
153 BIGNUM *p, *a, *b;
154 EC_GROUP *group;
155 EC_GROUP *P_192 = NULL, *P_224 = NULL, *P_256 = NULL, *P_384 = NULL, *P_521 = NULL;
156 EC_POINT *P, *Q, *R;
157 BIGNUM *x, *y, *z;
158 unsigned char buf[100];
159 size_t i, len;
160 int k;
161
162 /* enable memory leak checking unless explicitly disabled */
163 if (!((getenv("OPENSSL_DEBUG_MEMORY") != NULL) && (0 == strcmp(getenv("OPENSSL_DEBUG_MEMORY"), "off"))))
164 {
165 CRYPTO_malloc_debug_init();
166 CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
167 }
168 else
169 {
170 /* OPENSSL_DEBUG_MEMORY=off */
171 CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0);
172 }
173 CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
174 ERR_load_crypto_strings();
175
176#if 1 /* optional */
177 ctx = BN_CTX_new();
178 if (!ctx) ABORT;
179#endif
180
181 p = BN_new();
182 a = BN_new();
183 b = BN_new();
184 if (!p || !a || !b) ABORT;
185
186 if (!BN_hex2bn(&p, "17")) ABORT;
187 if (!BN_hex2bn(&a, "1")) ABORT;
188 if (!BN_hex2bn(&b, "1")) ABORT;
189
190 group = EC_GROUP_new(EC_GFp_mont_method()); /* applications should use EC_GROUP_new_curve_GFp
191 * so that the library gets to choose the EC_METHOD */
192 if (!group) ABORT;
193
194 if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) ABORT;
195
196 {
197 EC_GROUP *tmp;
198 tmp = EC_GROUP_new(EC_GROUP_method_of(group));
199 if (!tmp) ABORT;
200 if (!EC_GROUP_copy(tmp, group)) ABORT;
201 EC_GROUP_free(group);
202 group = tmp;
203 }
204
205 if (!EC_GROUP_get_curve_GFp(group, p, a, b, ctx)) ABORT;
206
207 fprintf(stdout, "Curve defined by Weierstrass equation\n y^2 = x^3 + a*x + b (mod 0x");
208 BN_print_fp(stdout, p);
209 fprintf(stdout, ")\n a = 0x");
210 BN_print_fp(stdout, a);
211 fprintf(stdout, "\n b = 0x");
212 BN_print_fp(stdout, b);
213 fprintf(stdout, "\n");
214
215 P = EC_POINT_new(group);
216 Q = EC_POINT_new(group);
217 R = EC_POINT_new(group);
218 if (!P || !Q || !R) ABORT;
219
220 if (!EC_POINT_set_to_infinity(group, P)) ABORT;
221 if (!EC_POINT_is_at_infinity(group, P)) ABORT;
222
223 buf[0] = 0;
224 if (!EC_POINT_oct2point(group, Q, buf, 1, ctx)) ABORT;
225
226 if (!EC_POINT_add(group, P, P, Q, ctx)) ABORT;
227 if (!EC_POINT_is_at_infinity(group, P)) ABORT;
228
229 x = BN_new();
230 y = BN_new();
231 z = BN_new();
232 if (!x || !y || !z) ABORT;
233
234 if (!BN_hex2bn(&x, "D")) ABORT;
235 if (!EC_POINT_set_compressed_coordinates_GFp(group, Q, x, 1, ctx)) ABORT;
236 if (!EC_POINT_is_on_curve(group, Q, ctx))
237 {
238 if (!EC_POINT_get_affine_coordinates_GFp(group, Q, x, y, ctx)) ABORT;
239 fprintf(stderr, "Point is not on curve: x = 0x");
240 BN_print_fp(stderr, x);
241 fprintf(stderr, ", y = 0x");
242 BN_print_fp(stderr, y);
243 fprintf(stderr, "\n");
244 ABORT;
245 }
246
247 fprintf(stdout, "A cyclic subgroup:\n");
248 k = 100;
249 do
250 {
251 if (k-- == 0) ABORT;
252
253 if (EC_POINT_is_at_infinity(group, P))
254 fprintf(stdout, " point at infinity\n");
255 else
256 {
257 if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
258
259 fprintf(stdout, " x = 0x");
260 BN_print_fp(stdout, x);
261 fprintf(stdout, ", y = 0x");
262 BN_print_fp(stdout, y);
263 fprintf(stdout, "\n");
264 }
265
266 if (!EC_POINT_copy(R, P)) ABORT;
267 if (!EC_POINT_add(group, P, P, Q, ctx)) ABORT;
268
269#if 0 /* optional */
270 {
271 EC_POINT *points[3];
272
273 points[0] = R;
274 points[1] = Q;
275 points[2] = P;
276 if (!EC_POINTs_make_affine(group, 2, points, ctx)) ABORT;
277 }
278#endif
279
280 }
281 while (!EC_POINT_is_at_infinity(group, P));
282
283 if (!EC_POINT_add(group, P, Q, R, ctx)) ABORT;
284 if (!EC_POINT_is_at_infinity(group, P)) ABORT;
285
286 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_COMPRESSED, buf, sizeof buf, ctx);
287 if (len == 0) ABORT;
288 if (!EC_POINT_oct2point(group, P, buf, len, ctx)) ABORT;
289 if (0 != EC_POINT_cmp(group, P, Q, ctx)) ABORT;
290 fprintf(stdout, "Generator as octect string, compressed form:\n ");
291 for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]);
292
293 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_UNCOMPRESSED, buf, sizeof buf, ctx);
294 if (len == 0) ABORT;
295 if (!EC_POINT_oct2point(group, P, buf, len, ctx)) ABORT;
296 if (0 != EC_POINT_cmp(group, P, Q, ctx)) ABORT;
297 fprintf(stdout, "\nGenerator as octect string, uncompressed form:\n ");
298 for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]);
299
300 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_HYBRID, buf, sizeof buf, ctx);
301 if (len == 0) ABORT;
302 if (!EC_POINT_oct2point(group, P, buf, len, ctx)) ABORT;
303 if (0 != EC_POINT_cmp(group, P, Q, ctx)) ABORT;
304 fprintf(stdout, "\nGenerator as octect string, hybrid form:\n ");
305 for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]);
306
307 if (!EC_POINT_get_Jprojective_coordinates_GFp(group, R, x, y, z, ctx)) ABORT;
308 fprintf(stdout, "\nA representation of the inverse of that generator in\nJacobian projective coordinates:\n X = 0x");
309 BN_print_fp(stdout, x);
310 fprintf(stdout, ", Y = 0x");
311 BN_print_fp(stdout, y);
312 fprintf(stdout, ", Z = 0x");
313 BN_print_fp(stdout, z);
314 fprintf(stdout, "\n");
315
316 if (!EC_POINT_invert(group, P, ctx)) ABORT;
317 if (0 != EC_POINT_cmp(group, P, R, ctx)) ABORT;
318
319
320 /* Curve P-192 (FIPS PUB 186-2, App. 6) */
321
322 if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF")) ABORT;
323 if (1 != BN_is_prime(p, BN_prime_checks, 0, ctx, NULL)) ABORT;
324 if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC")) ABORT;
325 if (!BN_hex2bn(&b, "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1")) ABORT;
326 if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) ABORT;
327
328 if (!BN_hex2bn(&x, "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012")) ABORT;
329 if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1, ctx)) ABORT;
330 if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
331 if (!BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831")) ABORT;
332 if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;
333
334 if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
335 fprintf(stdout, "\nNIST curve P-192 -- Generator:\n x = 0x");
336 BN_print_fp(stdout, x);
337 fprintf(stdout, "\n y = 0x");
338 BN_print_fp(stdout, y);
339 fprintf(stdout, "\n");
340 /* G_y value taken from the standard: */
341 if (!BN_hex2bn(&z, "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811")) ABORT;
342 if (0 != BN_cmp(y, z)) ABORT;
343
344 fprintf(stdout, "verify group order ...");
345 fflush(stdout);
346 if (!EC_GROUP_get_order(group, z, ctx)) ABORT;
347 if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
348 if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
349 fprintf(stdout, ".");
350 fflush(stdout);
351 if (!EC_GROUP_precompute_mult(group, ctx)) ABORT;
352 if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
353 if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
354 fprintf(stdout, " ok\n");
355
356 if (!(P_192 = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT;
357 if (!EC_GROUP_copy(P_192, group)) ABORT;
358
359
360 /* Curve P-224 (FIPS PUB 186-2, App. 6) */
361
362 if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001")) ABORT;
363 if (1 != BN_is_prime(p, BN_prime_checks, 0, ctx, NULL)) ABORT;
364 if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE")) ABORT;
365 if (!BN_hex2bn(&b, "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4")) ABORT;
366 if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) ABORT;
367
368 if (!BN_hex2bn(&x, "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21")) ABORT;
369 if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 0, ctx)) ABORT;
370 if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
371 if (!BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D")) ABORT;
372 if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;
373
374 if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
375 fprintf(stdout, "\nNIST curve P-224 -- Generator:\n x = 0x");
376 BN_print_fp(stdout, x);
377 fprintf(stdout, "\n y = 0x");
378 BN_print_fp(stdout, y);
379 fprintf(stdout, "\n");
380 /* G_y value taken from the standard: */
381 if (!BN_hex2bn(&z, "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34")) ABORT;
382 if (0 != BN_cmp(y, z)) ABORT;
383
384 fprintf(stdout, "verify group order ...");
385 fflush(stdout);
386 if (!EC_GROUP_get_order(group, z, ctx)) ABORT;
387 if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
388 if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
389 fprintf(stdout, ".");
390 fflush(stdout);
391 if (!EC_GROUP_precompute_mult(group, ctx)) ABORT;
392 if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
393 if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
394 fprintf(stdout, " ok\n");
395
396 if (!(P_224 = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT;
397 if (!EC_GROUP_copy(P_224, group)) ABORT;
398
399
400 /* Curve P-256 (FIPS PUB 186-2, App. 6) */
401
402 if (!BN_hex2bn(&p, "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF")) ABORT;
403 if (1 != BN_is_prime(p, BN_prime_checks, 0, ctx, NULL)) ABORT;
404 if (!BN_hex2bn(&a, "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC")) ABORT;
405 if (!BN_hex2bn(&b, "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B")) ABORT;
406 if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) ABORT;
407
408 if (!BN_hex2bn(&x, "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296")) ABORT;
409 if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1, ctx)) ABORT;
410 if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
411 if (!BN_hex2bn(&z, "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E"
412 "84F3B9CAC2FC632551")) ABORT;
413 if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;
414
415 if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
416 fprintf(stdout, "\nNIST curve P-256 -- Generator:\n x = 0x");
417 BN_print_fp(stdout, x);
418 fprintf(stdout, "\n y = 0x");
419 BN_print_fp(stdout, y);
420 fprintf(stdout, "\n");
421 /* G_y value taken from the standard: */
422 if (!BN_hex2bn(&z, "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5")) ABORT;
423 if (0 != BN_cmp(y, z)) ABORT;
424
425 fprintf(stdout, "verify group order ...");
426 fflush(stdout);
427 if (!EC_GROUP_get_order(group, z, ctx)) ABORT;
428 if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
429 if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
430 fprintf(stdout, ".");
431 fflush(stdout);
432 if (!EC_GROUP_precompute_mult(group, ctx)) ABORT;
433 if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
434 if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
435 fprintf(stdout, " ok\n");
436
437 if (!(P_256 = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT;
438 if (!EC_GROUP_copy(P_256, group)) ABORT;
439
440
441 /* Curve P-384 (FIPS PUB 186-2, App. 6) */
442
443 if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
444 "FFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF")) ABORT;
445 if (1 != BN_is_prime(p, BN_prime_checks, 0, ctx, NULL)) ABORT;
446 if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
447 "FFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC")) ABORT;
448 if (!BN_hex2bn(&b, "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141"
449 "120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF")) ABORT;
450 if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) ABORT;
451
452 if (!BN_hex2bn(&x, "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B"
453 "9859F741E082542A385502F25DBF55296C3A545E3872760AB7")) ABORT;
454 if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1, ctx)) ABORT;
455 if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
456 if (!BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
457 "FFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973")) ABORT;
458 if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;
459
460 if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
461 fprintf(stdout, "\nNIST curve P-384 -- Generator:\n x = 0x");
462 BN_print_fp(stdout, x);
463 fprintf(stdout, "\n y = 0x");
464 BN_print_fp(stdout, y);
465 fprintf(stdout, "\n");
466 /* G_y value taken from the standard: */
467 if (!BN_hex2bn(&z, "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A14"
468 "7CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F")) ABORT;
469 if (0 != BN_cmp(y, z)) ABORT;
470
471 fprintf(stdout, "verify group order ...");
472 fflush(stdout);
473 if (!EC_GROUP_get_order(group, z, ctx)) ABORT;
474 if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
475 if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
476 fprintf(stdout, ".");
477 fflush(stdout);
478 if (!EC_GROUP_precompute_mult(group, ctx)) ABORT;
479 if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
480 if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
481 fprintf(stdout, " ok\n");
482
483 if (!(P_384 = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT;
484 if (!EC_GROUP_copy(P_384, group)) ABORT;
485
486
487 /* Curve P-521 (FIPS PUB 186-2, App. 6) */
488
489 if (!BN_hex2bn(&p, "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
490 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
491 "FFFFFFFFFFFFFFFFFFFFFFFFFFFF")) ABORT;
492 if (1 != BN_is_prime(p, BN_prime_checks, 0, ctx, NULL)) ABORT;
493 if (!BN_hex2bn(&a, "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
494 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
495 "FFFFFFFFFFFFFFFFFFFFFFFFFFFC")) ABORT;
496 if (!BN_hex2bn(&b, "051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B"
497 "315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573"
498 "DF883D2C34F1EF451FD46B503F00")) ABORT;
499 if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) ABORT;
500
501 if (!BN_hex2bn(&x, "C6858E06B70404E9CD9E3ECB662395B4429C648139053F"
502 "B521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B"
503 "3C1856A429BF97E7E31C2E5BD66")) ABORT;
504 if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 0, ctx)) ABORT;
505 if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
506 if (!BN_hex2bn(&z, "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
507 "FFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5"
508 "C9B8899C47AEBB6FB71E91386409")) ABORT;
509 if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;
510
511 if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
512 fprintf(stdout, "\nNIST curve P-521 -- Generator:\n x = 0x");
513 BN_print_fp(stdout, x);
514 fprintf(stdout, "\n y = 0x");
515 BN_print_fp(stdout, y);
516 fprintf(stdout, "\n");
517 /* G_y value taken from the standard: */
518 if (!BN_hex2bn(&z, "11839296A789A3BC0045C8A5FB42C7D1BD998F54449579"
519 "B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C"
520 "7086A272C24088BE94769FD16650")) ABORT;
521 if (0 != BN_cmp(y, z)) ABORT;
522
523 fprintf(stdout, "verify group order ...");
524 fflush(stdout);
525 if (!EC_GROUP_get_order(group, z, ctx)) ABORT;
526 if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
527 if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
528 fprintf(stdout, ".");
529 fflush(stdout);
530 if (!EC_GROUP_precompute_mult(group, ctx)) ABORT;
531 if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
532 if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
533 fprintf(stdout, " ok\n");
534
535 if (!(P_521 = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT;
536 if (!EC_GROUP_copy(P_521, group)) ABORT;
537
538
539 /* more tests using the last curve */
540
541 if (!EC_POINT_copy(Q, P)) ABORT;
542 if (EC_POINT_is_at_infinity(group, Q)) ABORT;
543 if (!EC_POINT_dbl(group, P, P, ctx)) ABORT;
544 if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
545 if (!EC_POINT_invert(group, Q, ctx)) ABORT; /* P = -2Q */
546
547 if (!EC_POINT_add(group, R, P, Q, ctx)) ABORT;
548 if (!EC_POINT_add(group, R, R, Q, ctx)) ABORT;
549 if (!EC_POINT_is_at_infinity(group, R)) ABORT; /* R = P + 2Q */
550
551 {
552 const EC_POINT *points[3];
553 const BIGNUM *scalars[3];
554
555 if (EC_POINT_is_at_infinity(group, Q)) ABORT;
556 points[0] = Q;
557 points[1] = Q;
558 points[2] = Q;
559
560 if (!BN_add(y, z, BN_value_one())) ABORT;
561 if (BN_is_odd(y)) ABORT;
562 if (!BN_rshift1(y, y)) ABORT;
563 scalars[0] = y; /* (group order + 1)/2, so y*Q + y*Q = Q */
564 scalars[1] = y;
565
566 fprintf(stdout, "combined multiplication ...");
567 fflush(stdout);
568
569 /* z is still the group order */
570 if (!EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx)) ABORT;
571 if (!EC_POINTs_mul(group, R, z, 2, points, scalars, ctx)) ABORT;
572 if (0 != EC_POINT_cmp(group, P, R, ctx)) ABORT;
573 if (0 != EC_POINT_cmp(group, R, Q, ctx)) ABORT;
574
575 fprintf(stdout, ".");
576 fflush(stdout);
577
578 if (!BN_pseudo_rand(y, BN_num_bits(y), 0, 0)) ABORT;
579 if (!BN_add(z, z, y)) ABORT;
580 z->neg = 1;
581 scalars[0] = y;
582 scalars[1] = z; /* z = -(order + y) */
583
584 if (!EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx)) ABORT;
585 if (!EC_POINT_is_at_infinity(group, P)) ABORT;
586
587 fprintf(stdout, ".");
588 fflush(stdout);
589
590 if (!BN_pseudo_rand(x, BN_num_bits(y) - 1, 0, 0)) ABORT;
591 if (!BN_add(z, x, y)) ABORT;
592 z->neg = 1;
593 scalars[0] = x;
594 scalars[1] = y;
595 scalars[2] = z; /* z = -(x+y) */
596
597 if (!EC_POINTs_mul(group, P, NULL, 3, points, scalars, ctx)) ABORT;
598 if (!EC_POINT_is_at_infinity(group, P)) ABORT;
599
600 fprintf(stdout, " ok\n\n");
601 }
602
603
604#if 0
605 timings(P_192, 0, ctx);
606 timings(P_192, 1, ctx);
607 timings(P_224, 0, ctx);
608 timings(P_224, 1, ctx);
609 timings(P_256, 0, ctx);
610 timings(P_256, 1, ctx);
611 timings(P_384, 0, ctx);
612 timings(P_384, 1, ctx);
613 timings(P_521, 0, ctx);
614 timings(P_521, 1, ctx);
615#endif
616
617
618 if (ctx)
619 BN_CTX_free(ctx);
620 BN_free(p); BN_free(a); BN_free(b);
621 EC_GROUP_free(group);
622 EC_POINT_free(P);
623 EC_POINT_free(Q);
624 EC_POINT_free(R);
625 BN_free(x); BN_free(y); BN_free(z);
626
627 if (P_192) EC_GROUP_free(P_192);
628 if (P_224) EC_GROUP_free(P_224);
629 if (P_256) EC_GROUP_free(P_256);
630 if (P_384) EC_GROUP_free(P_384);
631 if (P_521) EC_GROUP_free(P_521);
632
633#ifndef OPENSSL_NO_ENGINE
634 ENGINE_cleanup();
635#endif
636 CRYPTO_cleanup_all_ex_data();
637 ERR_free_strings();
638 ERR_remove_state(0);
639 CRYPTO_mem_leaks_fp(stderr);
640
641 return 0;
642 }
643#endif