More method functions for elliptic curves,
[openssl.git] / crypto / ec / ectest.c
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
59
60 #ifdef OPENSSL_NO_EC
61 int main(int argc, char * argv[]) { puts("Elliptic curves are disabled."); return 0; }
62 #else
63
64
65 #include <openssl/ec.h>
66 #include <openssl/err.h>
67
68 #define ABORT do { \
69         fprintf(stderr, "%s:%d: ABORT\n", __FILE__, __LINE__); \
70         ERR_print_errors_fp(stderr); \
71         exit(1); \
72 } while (0)
73
74 int main(int argc, char *argv[])
75         {       
76         BN_CTX *ctx = NULL;
77         BIGNUM *p, *a, *b;
78         EC_GROUP *group;
79         EC_POINT *P, *Q, *R;
80         BIGNUM *x, *y, *z;
81         unsigned char buf[100];
82         size_t i, len;
83         
84         CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
85         ERR_load_crypto_strings();
86
87 #if 0 /* optional */
88         ctx = BN_CTX_new();
89         if (!ctx) ABORT;
90 #endif
91
92         p = BN_new();
93         a = BN_new();
94         b = BN_new();
95         if (!p || !a || !b) ABORT;
96
97         if (!BN_hex2bn(&p, "D")) ABORT;
98         if (!BN_hex2bn(&a, "7")) ABORT;
99         if (!BN_hex2bn(&b, "C")) ABORT;
100         
101         group = EC_GROUP_new_curve_GFp(p, a, b, NULL);
102         if (!group) ABORT;
103
104         fprintf(stdout, "Curve defined by Weierstrass equation\n     y^2 = x^3 + a*x + b  (mod 0x");
105         BN_print_fp(stdout, p);
106         fprintf(stdout, ")\n     a = 0x");
107         BN_print_fp(stdout, a);
108         fprintf(stdout, "\n     b = 0x");
109         BN_print_fp(stdout, b);
110         fprintf(stdout, "\n");
111
112         P = EC_POINT_new(group);
113         Q = EC_POINT_new(group);
114         R = EC_POINT_new(group);
115         if (!P || !Q || !R) ABORT;
116         
117         if (!EC_POINT_set_to_infinity(group, P)) ABORT;
118         if (!EC_POINT_is_at_infinity(group, P)) ABORT;
119
120         buf[0] = 0;
121         if (!EC_POINT_oct2point(group, Q, buf, 1, ctx)) ABORT;
122
123         if (!EC_POINT_add(group, P, P, Q, ctx)) ABORT;
124         if (!EC_POINT_is_at_infinity(group, P)) ABORT;
125
126         x = BN_new();
127         y = BN_new();
128         z = BN_new();
129         if (!x || !y || !z) ABORT;
130
131         if (!BN_hex2bn(&x, "C")) ABORT;
132         if (!EC_POINT_set_compressed_coordinates_GFp(group, Q, x, 1, ctx)) ABORT;
133         if (!EC_POINT_is_on_curve(group, Q, ctx))
134                 {
135                 fprintf(stderr, "Point is not on curve, x = 0x");
136                 BN_print_fp(stderr, x);
137                 fprintf(stderr, "\n");
138                 ABORT;
139                 }
140
141         fprintf(stdout, "A cyclic subgroup:\n");
142         do
143                 {
144                 if (EC_POINT_is_at_infinity(group, P))
145                         fprintf(stdout, "     point at infinity\n");
146                 else
147                         {
148                         if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
149
150                         fprintf(stdout, "     x = 0x");
151                         BN_print_fp(stdout, x);
152                         fprintf(stdout, ", y = 0x");
153                         BN_print_fp(stdout, y);
154                         fprintf(stdout, "\n");
155                         }
156                 
157                 if (!EC_POINT_copy(R, P)) ABORT;
158                 if (!EC_POINT_add(group, P, P, Q, ctx)) ABORT;
159
160 #if 0 /* optional */
161                 if (!EC_POINT_make_affine(group, P, ctx)) ABORT;
162 #endif
163                 }
164         while (!EC_POINT_is_at_infinity(group, P));
165
166         if (!EC_POINT_add(group, P, Q, R, ctx)) ABORT;
167         if (!EC_POINT_is_at_infinity(group, P)) ABORT;
168
169         len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_COMPRESSED, buf, sizeof buf, ctx);
170         if (len == 0) ABORT;
171         if (!EC_POINT_oct2point(group, P, buf, len, ctx)) ABORT;
172         if (0 != EC_POINT_cmp(group, P, Q, ctx)) ABORT;
173         fprintf(stdout, "Generator as octect string, compressed form:\n     ");
174         for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]);
175         
176         len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_UNCOMPRESSED, buf, sizeof buf, ctx);
177         if (len == 0) ABORT;
178         if (!EC_POINT_oct2point(group, P, buf, len, ctx)) ABORT;
179         if (0 != EC_POINT_cmp(group, P, Q, ctx)) ABORT;
180         fprintf(stdout, "\nGenerator as octect string, uncompressed form:\n     ");
181         for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]);
182         
183         len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_HYBRID, buf, sizeof buf, ctx);
184         if (len == 0) ABORT;
185         if (!EC_POINT_oct2point(group, P, buf, len, ctx)) ABORT;
186         if (0 != EC_POINT_cmp(group, P, Q, ctx)) ABORT;
187         fprintf(stdout, "\nGenerator as octect string, hybrid form:\n     ");
188         for (i = 0; i < len; i++) fprintf(stdout, "%02X", buf[i]);
189         
190         if (!EC_POINT_get_Jprojective_coordinates_GFp(group, R, x, y, z, ctx)) ABORT;
191         fprintf(stdout, "\nA representation of the inverse of that generator in\nJacobian projective coordinates:\n     X = 0x");
192         BN_print_fp(stdout, x);
193         fprintf(stdout, ", Y = 0x");
194         BN_print_fp(stdout, y);
195         fprintf(stdout, ", Z = 0x");
196         BN_print_fp(stdout, z);
197         fprintf(stdout, "\n");
198
199         if (!EC_POINT_invert(group, P, ctx)) ABORT;
200         if (0 != EC_POINT_cmp(group, P, R, ctx)) ABORT;
201
202         /* ... */
203
204         if (ctx)
205                 BN_CTX_free(ctx);
206         BN_free(p); BN_free(a); BN_free(b);
207         EC_GROUP_free(group);
208         EC_POINT_free(P);
209         EC_POINT_free(Q);
210         EC_POINT_free(R);
211         BN_free(x); BN_free(y); BN_free(z);
212
213         ERR_free_strings();
214         ERR_remove_state(0);
215         CRYPTO_mem_leaks_fp(stderr);
216         
217         return 0;
218         }
219 #endif