2
* seccure - Copyright 2009 B. Poettering
4
* Maintained by R. Tyler Ballance <tyler@slide.com>
6
* This library is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU Lesser General Public
8
* License as published by the Free Software Foundation; either
9
* version 2.1 of the License, or (at your option) any later version.
11
* This library is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
* Lesser General Public License for more details.
16
* You should have received a copy of the GNU Lesser General Public
17
* License along with this library; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22
* SECCURE Elliptic Curve Crypto Utility for Reliable Encryption
24
* Current homepage: http://slideinc.github.com/PyECC
25
* Original homepage: http://point-at-infinity.org/seccure/
28
* seccure implements a selection of asymmetric algorithms based on
29
* elliptic curve cryptography (ECC). See the manpage or the project's
30
* homepage for further details.
32
* This code links against the GNU gcrypt library "libgcrypt" (which
33
* is part of the GnuPG project). Use the included Makefile to build
36
* Report bugs to: http://github.com/rtyler/PyECC/issues
45
#include "serialize.h"
47
/******************************************************************************/
52
const char *name, *a, *b, *m, *base_x, *base_y, *order;
57
static const struct curve curves[CURVE_NUM] = {
59
"db7c2abf62e35e668076bead2088",
60
"659ef8ba043916eede8911702b22",
61
"db7c2abf62e35e668076bead208b",
62
"09487239995a5ee76b55f9c2f098",
63
"a89ce5af8724c0a23e0e0ff77500",
64
"db7c2abf62e35e7628dfac6561c5",
68
"fffffffdfffffffffffffffffffffffc",
69
"e87579c11079f43dd824993c2cee5ed3",
70
"fffffffdffffffffffffffffffffffff",
71
"161ff7528b899b2d0c28607ca52c5b86",
72
"cf5ac8395bafeb13c02da292dded7a83",
73
"fffffffe0000000075a30d1b9038a115",
77
"ffffffffffffffffffffffffffffffff7ffffffc",
78
"1c97befc54bd7a8b65acf89f81d4d4adc565fa45",
79
"ffffffffffffffffffffffffffffffff7fffffff",
80
"4a96b5688ef573284664698968c38bb913cbfc82",
81
"23a628553168947d59dcc912042351377ac5fb32",
82
"0100000000000000000001f4c8f927aed3ca752257",
85
{ "secp192r1/nistp192",
86
"fffffffffffffffffffffffffffffffefffffffffffffffc",
87
"64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1",
88
"fffffffffffffffffffffffffffffffeffffffffffffffff",
89
"188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012",
90
"07192b95ffc8da78631011ed6b24cdd573f977a11e794811",
91
"ffffffffffffffffffffffff99def836146bc9b1b4d22831",
94
{ "secp224r1/nistp224",
95
"fffffffffffffffffffffffffffffffefffffffffffffffffffffffe",
96
"b4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4",
97
"ffffffffffffffffffffffffffffffff000000000000000000000001",
98
"b70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21",
99
"bd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34",
100
"ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3d",
103
{ "secp256r1/nistp256",
104
"ffffffff00000001000000000000000000000000fffffffffffffffffffffffc",
105
"5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b",
106
"ffffffff00000001000000000000000000000000ffffffffffffffffffffffff",
107
"6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
108
"4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5",
109
"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551",
112
{ "secp384r1/nistp384",
113
"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000fffffffc",
114
"b3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875ac656398d8a2ed19d2a85c8edd3ec2aef",
115
"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff",
116
"aa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab7",
117
"3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5f",
118
"ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52973",
121
{ "secp521r1/nistp521",
122
"1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc",
123
"051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00",
124
"1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
125
"0c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66",
126
"11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650",
127
"1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409",
131
/******************************************************************************/
133
static void SCAN(gcry_mpi_t *x, const char *s)
135
if (gcry_mpi_scan(x, GCRYMPI_FMT_HEX, s, 0, NULL) != 0) {
136
fprintf(stderr, "Error scanning curve into MPI: %s\n", s);
139
gcry_mpi_set_flag(*x, GCRYMPI_FLAG_SECURE);
142
static struct curve_params* load_curve(const struct curve *c)
145
struct curve_params *cp;
146
struct domain_params *dp;
148
if (! (cp = malloc(sizeof(struct curve_params))))
157
SCAN(&dp->order, c->order);
158
SCAN(&dp->base.x, c->base_x);
159
SCAN(&dp->base.y, c->base_y);
160
dp->cofactor = c->cofactor;
164
gcry_mpi_add(h, dp->m, dp->m);
165
gcry_mpi_sub_ui(h, h, 1);
166
cp->pk_len_bin = get_serialization_len(h, DF_BIN);
167
cp->pk_len_compact = get_serialization_len(h, DF_COMPACT);
169
gcry_mpi_mul(h, dp->order, dp->order);
170
gcry_mpi_sub_ui(h, h, 1);
171
cp->sig_len_bin = get_serialization_len(h, DF_BIN);
172
cp->sig_len_compact = get_serialization_len(h, DF_COMPACT);
174
cp->dh_len_bin = (gcry_mpi_get_nbits(dp->order) / 2 + 7) / 8;
175
if (cp->dh_len_bin > 32)
178
gcry_mpi_set_ui(h, 0);
179
gcry_mpi_set_bit(h, 8 * cp->dh_len_bin);
180
gcry_mpi_sub_ui(h, h, 1);
181
cp->dh_len_compact = get_serialization_len(h, DF_COMPACT);
183
cp->elem_len_bin = get_serialization_len(dp->m, DF_BIN);
184
cp->order_len_bin = get_serialization_len(dp->order, DF_BIN);
186
#if 0 /* enable this when adding a new curve to do some sanity checks */
187
if (! gcry_mpi_cmp_ui(dp->b, 0)) {
188
fprintf(stderr, "FATAL: b == 0\n");
191
if (cp->pk_len_compact != c->pk_len_compact) {
192
fprintf(stderr, "FATAL: c->pk_len_compact != %d\n", cp->pk_len_compact);
195
if (! point_on_curve(&dp->base, dp)) {
196
fprintf(stderr, "FATAL: base point not on curve!\n");
199
struct affine_point p = pointmul(&dp->base, dp->order, dp);
200
if (! point_is_zero(&p)) {
201
fprintf(stderr, "FATAL: wrong point order!\n");
206
gcry_mpi_mul_ui(h, dp->order, dp->cofactor);
207
gcry_mpi_sub(h, h, dp->m);
208
gcry_mpi_sub_ui(h, h, 1);
209
gcry_mpi_mul(h, h, h);
210
gcry_mpi_rshift(h, h, 2);
211
if (gcry_mpi_cmp(h, dp->m) > 0) {
212
fprintf(stderr, "FATAL: invalid cofactor!\n");
221
struct curve_params* curve_by_name(const char *name)
223
const struct curve *c = curves;
225
for(i = 0; i < CURVE_NUM; i++, c++)
226
if (strstr(c->name, name))
227
return load_curve(c);
231
struct curve_params* curve_by_pk_len_compact(int len)
233
const struct curve *c = curves;
235
for(i = 0; i < CURVE_NUM; i++, c++)
236
if (c->pk_len_compact == len)
237
return load_curve(c);
241
void curve_release(struct curve_params *cp)
243
struct domain_params *dp = &cp->dp;
244
gcry_mpi_release(dp->a);
245
gcry_mpi_release(dp->b);
246
gcry_mpi_release(dp->m);
247
gcry_mpi_release(dp->order);
248
gcry_mpi_release(dp->base.x);
249
gcry_mpi_release(dp->base.y);