This Trac instance is not used for development anymore!

We migrated our development workflow to git and Gitea.
To test the future redirection, replace trac by ariadne in the page URL.

source: ps/trunk/build/premake/premake5/contrib/mbedtls/library/ecp.c

Last change on this file was 20366, checked in by Itms, 7 years ago

Alpha 12 version of Premake 5, including prebuilt binary for Windows.
Directly taken from https://premake.github.io/.

Refs #3729.

File size: 63.1 KB
Line 
1/*
2 * Elliptic curves over GF(p): generic functions
3 *
4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 * This file is part of mbed TLS (https://tls.mbed.org)
20 */
21
22/*
23 * References:
24 *
25 * SEC1 http://www.secg.org/index.php?action=secg,docs_secg
26 * GECC = Guide to Elliptic Curve Cryptography - Hankerson, Menezes, Vanstone
27 * FIPS 186-3 http://csrc.nist.gov/publications/fips/fips186-3/fips_186-3.pdf
28 * RFC 4492 for the related TLS structures and constants
29 *
30 * [Curve25519] http://cr.yp.to/ecdh/curve25519-20060209.pdf
31 *
32 * [2] CORON, Jean-S'ebastien. Resistance against differential power analysis
33 * for elliptic curve cryptosystems. In : Cryptographic Hardware and
34 * Embedded Systems. Springer Berlin Heidelberg, 1999. p. 292-302.
35 * <http://link.springer.com/chapter/10.1007/3-540-48059-5_25>
36 *
37 * [3] HEDABOU, Mustapha, PINEL, Pierre, et B'EN'ETEAU, Lucien. A comb method to
38 * render ECC resistant against Side Channel Attacks. IACR Cryptology
39 * ePrint Archive, 2004, vol. 2004, p. 342.
40 * <http://eprint.iacr.org/2004/342.pdf>
41 */
42
43#if !defined(MBEDTLS_CONFIG_FILE)
44#include "mbedtls/config.h"
45#else
46#include MBEDTLS_CONFIG_FILE
47#endif
48
49#if defined(MBEDTLS_ECP_C)
50
51#include "mbedtls/ecp.h"
52
53#include <string.h>
54
55#if defined(MBEDTLS_PLATFORM_C)
56#include "mbedtls/platform.h"
57#else
58#include <stdlib.h>
59#include <stdio.h>
60#define mbedtls_printf printf
61#define mbedtls_calloc calloc
62#define mbedtls_free free
63#endif
64
65#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
66 !defined(inline) && !defined(__cplusplus)
67#define inline __inline
68#endif
69
70/* Implementation that should never be optimized out by the compiler */
71static void mbedtls_zeroize( void *v, size_t n ) {
72 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
73}
74
75#if defined(MBEDTLS_SELF_TEST)
76/*
77 * Counts of point addition and doubling, and field multiplications.
78 * Used to test resistance of point multiplication to simple timing attacks.
79 */
80static unsigned long add_count, dbl_count, mul_count;
81#endif
82
83#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) || \
84 defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \
85 defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \
86 defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) || \
87 defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) || \
88 defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) || \
89 defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) || \
90 defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) || \
91 defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) || \
92 defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || \
93 defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
94#define ECP_SHORTWEIERSTRASS
95#endif
96
97#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
98#define ECP_MONTGOMERY
99#endif
100
101/*
102 * Curve types: internal for now, might be exposed later
103 */
104typedef enum
105{
106 ECP_TYPE_NONE = 0,
107 ECP_TYPE_SHORT_WEIERSTRASS, /* y^2 = x^3 + a x + b */
108 ECP_TYPE_MONTGOMERY, /* y^2 = x^3 + a x^2 + x */
109} ecp_curve_type;
110
111/*
112 * List of supported curves:
113 * - internal ID
114 * - TLS NamedCurve ID (RFC 4492 sec. 5.1.1, RFC 7071 sec. 2)
115 * - size in bits
116 * - readable name
117 *
118 * Curves are listed in order: largest curves first, and for a given size,
119 * fastest curves first. This provides the default order for the SSL module.
120 *
121 * Reminder: update profiles in x509_crt.c when adding a new curves!
122 */
123static const mbedtls_ecp_curve_info ecp_supported_curves[] =
124{
125#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
126 { MBEDTLS_ECP_DP_SECP521R1, 25, 521, "secp521r1" },
127#endif
128#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED)
129 { MBEDTLS_ECP_DP_BP512R1, 28, 512, "brainpoolP512r1" },
130#endif
131#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
132 { MBEDTLS_ECP_DP_SECP384R1, 24, 384, "secp384r1" },
133#endif
134#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED)
135 { MBEDTLS_ECP_DP_BP384R1, 27, 384, "brainpoolP384r1" },
136#endif
137#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
138 { MBEDTLS_ECP_DP_SECP256R1, 23, 256, "secp256r1" },
139#endif
140#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
141 { MBEDTLS_ECP_DP_SECP256K1, 22, 256, "secp256k1" },
142#endif
143#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED)
144 { MBEDTLS_ECP_DP_BP256R1, 26, 256, "brainpoolP256r1" },
145#endif
146#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
147 { MBEDTLS_ECP_DP_SECP224R1, 21, 224, "secp224r1" },
148#endif
149#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
150 { MBEDTLS_ECP_DP_SECP224K1, 20, 224, "secp224k1" },
151#endif
152#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
153 { MBEDTLS_ECP_DP_SECP192R1, 19, 192, "secp192r1" },
154#endif
155#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
156 { MBEDTLS_ECP_DP_SECP192K1, 18, 192, "secp192k1" },
157#endif
158 { MBEDTLS_ECP_DP_NONE, 0, 0, NULL },
159};
160
161#define ECP_NB_CURVES sizeof( ecp_supported_curves ) / \
162 sizeof( ecp_supported_curves[0] )
163
164static mbedtls_ecp_group_id ecp_supported_grp_id[ECP_NB_CURVES];
165
166/*
167 * List of supported curves and associated info
168 */
169const mbedtls_ecp_curve_info *mbedtls_ecp_curve_list( void )
170{
171 return( ecp_supported_curves );
172}
173
174/*
175 * List of supported curves, group ID only
176 */
177const mbedtls_ecp_group_id *mbedtls_ecp_grp_id_list( void )
178{
179 static int init_done = 0;
180
181 if( ! init_done )
182 {
183 size_t i = 0;
184 const mbedtls_ecp_curve_info *curve_info;
185
186 for( curve_info = mbedtls_ecp_curve_list();
187 curve_info->grp_id != MBEDTLS_ECP_DP_NONE;
188 curve_info++ )
189 {
190 ecp_supported_grp_id[i++] = curve_info->grp_id;
191 }
192 ecp_supported_grp_id[i] = MBEDTLS_ECP_DP_NONE;
193
194 init_done = 1;
195 }
196
197 return( ecp_supported_grp_id );
198}
199
200/*
201 * Get the curve info for the internal identifier
202 */
203const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_grp_id( mbedtls_ecp_group_id grp_id )
204{
205 const mbedtls_ecp_curve_info *curve_info;
206
207 for( curve_info = mbedtls_ecp_curve_list();
208 curve_info->grp_id != MBEDTLS_ECP_DP_NONE;
209 curve_info++ )
210 {
211 if( curve_info->grp_id == grp_id )
212 return( curve_info );
213 }
214
215 return( NULL );
216}
217
218/*
219 * Get the curve info from the TLS identifier
220 */
221const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_tls_id( uint16_t tls_id )
222{
223 const mbedtls_ecp_curve_info *curve_info;
224
225 for( curve_info = mbedtls_ecp_curve_list();
226 curve_info->grp_id != MBEDTLS_ECP_DP_NONE;
227 curve_info++ )
228 {
229 if( curve_info->tls_id == tls_id )
230 return( curve_info );
231 }
232
233 return( NULL );
234}
235
236/*
237 * Get the curve info from the name
238 */
239const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_name( const char *name )
240{
241 const mbedtls_ecp_curve_info *curve_info;
242
243 for( curve_info = mbedtls_ecp_curve_list();
244 curve_info->grp_id != MBEDTLS_ECP_DP_NONE;
245 curve_info++ )
246 {
247 if( strcmp( curve_info->name, name ) == 0 )
248 return( curve_info );
249 }
250
251 return( NULL );
252}
253
254/*
255 * Get the type of a curve
256 */
257static inline ecp_curve_type ecp_get_type( const mbedtls_ecp_group *grp )
258{
259 if( grp->G.X.p == NULL )
260 return( ECP_TYPE_NONE );
261
262 if( grp->G.Y.p == NULL )
263 return( ECP_TYPE_MONTGOMERY );
264 else
265 return( ECP_TYPE_SHORT_WEIERSTRASS );
266}
267
268/*
269 * Initialize (the components of) a point
270 */
271void mbedtls_ecp_point_init( mbedtls_ecp_point *pt )
272{
273 if( pt == NULL )
274 return;
275
276 mbedtls_mpi_init( &pt->X );
277 mbedtls_mpi_init( &pt->Y );
278 mbedtls_mpi_init( &pt->Z );
279}
280
281/*
282 * Initialize (the components of) a group
283 */
284void mbedtls_ecp_group_init( mbedtls_ecp_group *grp )
285{
286 if( grp == NULL )
287 return;
288
289 memset( grp, 0, sizeof( mbedtls_ecp_group ) );
290}
291
292/*
293 * Initialize (the components of) a key pair
294 */
295void mbedtls_ecp_keypair_init( mbedtls_ecp_keypair *key )
296{
297 if( key == NULL )
298 return;
299
300 mbedtls_ecp_group_init( &key->grp );
301 mbedtls_mpi_init( &key->d );
302 mbedtls_ecp_point_init( &key->Q );
303}
304
305/*
306 * Unallocate (the components of) a point
307 */
308void mbedtls_ecp_point_free( mbedtls_ecp_point *pt )
309{
310 if( pt == NULL )
311 return;
312
313 mbedtls_mpi_free( &( pt->X ) );
314 mbedtls_mpi_free( &( pt->Y ) );
315 mbedtls_mpi_free( &( pt->Z ) );
316}
317
318/*
319 * Unallocate (the components of) a group
320 */
321void mbedtls_ecp_group_free( mbedtls_ecp_group *grp )
322{
323 size_t i;
324
325 if( grp == NULL )
326 return;
327
328 if( grp->h != 1 )
329 {
330 mbedtls_mpi_free( &grp->P );
331 mbedtls_mpi_free( &grp->A );
332 mbedtls_mpi_free( &grp->B );
333 mbedtls_ecp_point_free( &grp->G );
334 mbedtls_mpi_free( &grp->N );
335 }
336
337 if( grp->T != NULL )
338 {
339 for( i = 0; i < grp->T_size; i++ )
340 mbedtls_ecp_point_free( &grp->T[i] );
341 mbedtls_free( grp->T );
342 }
343
344 mbedtls_zeroize( grp, sizeof( mbedtls_ecp_group ) );
345}
346
347/*
348 * Unallocate (the components of) a key pair
349 */
350void mbedtls_ecp_keypair_free( mbedtls_ecp_keypair *key )
351{
352 if( key == NULL )
353 return;
354
355 mbedtls_ecp_group_free( &key->grp );
356 mbedtls_mpi_free( &key->d );
357 mbedtls_ecp_point_free( &key->Q );
358}
359
360/*
361 * Copy the contents of a point
362 */
363int mbedtls_ecp_copy( mbedtls_ecp_point *P, const mbedtls_ecp_point *Q )
364{
365 int ret;
366
367 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &P->X, &Q->X ) );
368 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &P->Y, &Q->Y ) );
369 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &P->Z, &Q->Z ) );
370
371cleanup:
372 return( ret );
373}
374
375/*
376 * Copy the contents of a group object
377 */
378int mbedtls_ecp_group_copy( mbedtls_ecp_group *dst, const mbedtls_ecp_group *src )
379{
380 return mbedtls_ecp_group_load( dst, src->id );
381}
382
383/*
384 * Set point to zero
385 */
386int mbedtls_ecp_set_zero( mbedtls_ecp_point *pt )
387{
388 int ret;
389
390 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &pt->X , 1 ) );
391 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &pt->Y , 1 ) );
392 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &pt->Z , 0 ) );
393
394cleanup:
395 return( ret );
396}
397
398/*
399 * Tell if a point is zero
400 */
401int mbedtls_ecp_is_zero( mbedtls_ecp_point *pt )
402{
403 return( mbedtls_mpi_cmp_int( &pt->Z, 0 ) == 0 );
404}
405
406/*
407 * Compare two points lazyly
408 */
409int mbedtls_ecp_point_cmp( const mbedtls_ecp_point *P,
410 const mbedtls_ecp_point *Q )
411{
412 if( mbedtls_mpi_cmp_mpi( &P->X, &Q->X ) == 0 &&
413 mbedtls_mpi_cmp_mpi( &P->Y, &Q->Y ) == 0 &&
414 mbedtls_mpi_cmp_mpi( &P->Z, &Q->Z ) == 0 )
415 {
416 return( 0 );
417 }
418
419 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
420}
421
422/*
423 * Import a non-zero point from ASCII strings
424 */
425int mbedtls_ecp_point_read_string( mbedtls_ecp_point *P, int radix,
426 const char *x, const char *y )
427{
428 int ret;
429
430 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &P->X, radix, x ) );
431 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &P->Y, radix, y ) );
432 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &P->Z, 1 ) );
433
434cleanup:
435 return( ret );
436}
437
438/*
439 * Export a point into unsigned binary data (SEC1 2.3.3)
440 */
441int mbedtls_ecp_point_write_binary( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *P,
442 int format, size_t *olen,
443 unsigned char *buf, size_t buflen )
444{
445 int ret = 0;
446 size_t plen;
447
448 if( format != MBEDTLS_ECP_PF_UNCOMPRESSED &&
449 format != MBEDTLS_ECP_PF_COMPRESSED )
450 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
451
452 /*
453 * Common case: P == 0
454 */
455 if( mbedtls_mpi_cmp_int( &P->Z, 0 ) == 0 )
456 {
457 if( buflen < 1 )
458 return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
459
460 buf[0] = 0x00;
461 *olen = 1;
462
463 return( 0 );
464 }
465
466 plen = mbedtls_mpi_size( &grp->P );
467
468 if( format == MBEDTLS_ECP_PF_UNCOMPRESSED )
469 {
470 *olen = 2 * plen + 1;
471
472 if( buflen < *olen )
473 return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
474
475 buf[0] = 0x04;
476 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &P->X, buf + 1, plen ) );
477 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &P->Y, buf + 1 + plen, plen ) );
478 }
479 else if( format == MBEDTLS_ECP_PF_COMPRESSED )
480 {
481 *olen = plen + 1;
482
483 if( buflen < *olen )
484 return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
485
486 buf[0] = 0x02 + mbedtls_mpi_get_bit( &P->Y, 0 );
487 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &P->X, buf + 1, plen ) );
488 }
489
490cleanup:
491 return( ret );
492}
493
494/*
495 * Import a point from unsigned binary data (SEC1 2.3.4)
496 */
497int mbedtls_ecp_point_read_binary( const mbedtls_ecp_group *grp, mbedtls_ecp_point *pt,
498 const unsigned char *buf, size_t ilen )
499{
500 int ret;
501 size_t plen;
502
503 if( ilen < 1 )
504 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
505
506 if( buf[0] == 0x00 )
507 {
508 if( ilen == 1 )
509 return( mbedtls_ecp_set_zero( pt ) );
510 else
511 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
512 }
513
514 plen = mbedtls_mpi_size( &grp->P );
515
516 if( buf[0] != 0x04 )
517 return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
518
519 if( ilen != 2 * plen + 1 )
520 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
521
522 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &pt->X, buf + 1, plen ) );
523 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &pt->Y, buf + 1 + plen, plen ) );
524 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &pt->Z, 1 ) );
525
526cleanup:
527 return( ret );
528}
529
530/*
531 * Import a point from a TLS ECPoint record (RFC 4492)
532 * struct {
533 * opaque point <1..2^8-1>;
534 * } ECPoint;
535 */
536int mbedtls_ecp_tls_read_point( const mbedtls_ecp_group *grp, mbedtls_ecp_point *pt,
537 const unsigned char **buf, size_t buf_len )
538{
539 unsigned char data_len;
540 const unsigned char *buf_start;
541
542 /*
543 * We must have at least two bytes (1 for length, at least one for data)
544 */
545 if( buf_len < 2 )
546 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
547
548 data_len = *(*buf)++;
549 if( data_len < 1 || data_len > buf_len - 1 )
550 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
551
552 /*
553 * Save buffer start for read_binary and update buf
554 */
555 buf_start = *buf;
556 *buf += data_len;
557
558 return mbedtls_ecp_point_read_binary( grp, pt, buf_start, data_len );
559}
560
561/*
562 * Export a point as a TLS ECPoint record (RFC 4492)
563 * struct {
564 * opaque point <1..2^8-1>;
565 * } ECPoint;
566 */
567int mbedtls_ecp_tls_write_point( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *pt,
568 int format, size_t *olen,
569 unsigned char *buf, size_t blen )
570{
571 int ret;
572
573 /*
574 * buffer length must be at least one, for our length byte
575 */
576 if( blen < 1 )
577 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
578
579 if( ( ret = mbedtls_ecp_point_write_binary( grp, pt, format,
580 olen, buf + 1, blen - 1) ) != 0 )
581 return( ret );
582
583 /*
584 * write length to the first byte and update total length
585 */
586 buf[0] = (unsigned char) *olen;
587 ++*olen;
588
589 return( 0 );
590}
591
592/*
593 * Set a group from an ECParameters record (RFC 4492)
594 */
595int mbedtls_ecp_tls_read_group( mbedtls_ecp_group *grp, const unsigned char **buf, size_t len )
596{
597 uint16_t tls_id;
598 const mbedtls_ecp_curve_info *curve_info;
599
600 /*
601 * We expect at least three bytes (see below)
602 */
603 if( len < 3 )
604 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
605
606 /*
607 * First byte is curve_type; only named_curve is handled
608 */
609 if( *(*buf)++ != MBEDTLS_ECP_TLS_NAMED_CURVE )
610 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
611
612 /*
613 * Next two bytes are the namedcurve value
614 */
615 tls_id = *(*buf)++;
616 tls_id <<= 8;
617 tls_id |= *(*buf)++;
618
619 if( ( curve_info = mbedtls_ecp_curve_info_from_tls_id( tls_id ) ) == NULL )
620 return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
621
622 return mbedtls_ecp_group_load( grp, curve_info->grp_id );
623}
624
625/*
626 * Write the ECParameters record corresponding to a group (RFC 4492)
627 */
628int mbedtls_ecp_tls_write_group( const mbedtls_ecp_group *grp, size_t *olen,
629 unsigned char *buf, size_t blen )
630{
631 const mbedtls_ecp_curve_info *curve_info;
632
633 if( ( curve_info = mbedtls_ecp_curve_info_from_grp_id( grp->id ) ) == NULL )
634 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
635
636 /*
637 * We are going to write 3 bytes (see below)
638 */
639 *olen = 3;
640 if( blen < *olen )
641 return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
642
643 /*
644 * First byte is curve_type, always named_curve
645 */
646 *buf++ = MBEDTLS_ECP_TLS_NAMED_CURVE;
647
648 /*
649 * Next two bytes are the namedcurve value
650 */
651 buf[0] = curve_info->tls_id >> 8;
652 buf[1] = curve_info->tls_id & 0xFF;
653
654 return( 0 );
655}
656
657/*
658 * Wrapper around fast quasi-modp functions, with fall-back to mbedtls_mpi_mod_mpi.
659 * See the documentation of struct mbedtls_ecp_group.
660 *
661 * This function is in the critial loop for mbedtls_ecp_mul, so pay attention to perf.
662 */
663static int ecp_modp( mbedtls_mpi *N, const mbedtls_ecp_group *grp )
664{
665 int ret;
666
667 if( grp->modp == NULL )
668 return( mbedtls_mpi_mod_mpi( N, N, &grp->P ) );
669
670 /* N->s < 0 is a much faster test, which fails only if N is 0 */
671 if( ( N->s < 0 && mbedtls_mpi_cmp_int( N, 0 ) != 0 ) ||
672 mbedtls_mpi_bitlen( N ) > 2 * grp->pbits )
673 {
674 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
675 }
676
677 MBEDTLS_MPI_CHK( grp->modp( N ) );
678
679 /* N->s < 0 is a much faster test, which fails only if N is 0 */
680 while( N->s < 0 && mbedtls_mpi_cmp_int( N, 0 ) != 0 )
681 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( N, N, &grp->P ) );
682
683 while( mbedtls_mpi_cmp_mpi( N, &grp->P ) >= 0 )
684 /* we known P, N and the result are positive */
685 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( N, N, &grp->P ) );
686
687cleanup:
688 return( ret );
689}
690
691/*
692 * Fast mod-p functions expect their argument to be in the 0..p^2 range.
693 *
694 * In order to guarantee that, we need to ensure that operands of
695 * mbedtls_mpi_mul_mpi are in the 0..p range. So, after each operation we will
696 * bring the result back to this range.
697 *
698 * The following macros are shortcuts for doing that.
699 */
700
701/*
702 * Reduce a mbedtls_mpi mod p in-place, general case, to use after mbedtls_mpi_mul_mpi
703 */
704#if defined(MBEDTLS_SELF_TEST)
705#define INC_MUL_COUNT mul_count++;
706#else
707#define INC_MUL_COUNT
708#endif
709
710#define MOD_MUL( N ) do { MBEDTLS_MPI_CHK( ecp_modp( &N, grp ) ); INC_MUL_COUNT } \
711 while( 0 )
712
713/*
714 * Reduce a mbedtls_mpi mod p in-place, to use after mbedtls_mpi_sub_mpi
715 * N->s < 0 is a very fast test, which fails only if N is 0
716 */
717#define MOD_SUB( N ) \
718 while( N.s < 0 && mbedtls_mpi_cmp_int( &N, 0 ) != 0 ) \
719 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &N, &N, &grp->P ) )
720
721/*
722 * Reduce a mbedtls_mpi mod p in-place, to use after mbedtls_mpi_add_mpi and mbedtls_mpi_mul_int.
723 * We known P, N and the result are positive, so sub_abs is correct, and
724 * a bit faster.
725 */
726#define MOD_ADD( N ) \
727 while( mbedtls_mpi_cmp_mpi( &N, &grp->P ) >= 0 ) \
728 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( &N, &N, &grp->P ) )
729
730#if defined(ECP_SHORTWEIERSTRASS)
731/*
732 * For curves in short Weierstrass form, we do all the internal operations in
733 * Jacobian coordinates.
734 *
735 * For multiplication, we'll use a comb method with coutermeasueres against
736 * SPA, hence timing attacks.
737 */
738
739/*
740 * Normalize jacobian coordinates so that Z == 0 || Z == 1 (GECC 3.2.1)
741 * Cost: 1N := 1I + 3M + 1S
742 */
743static int ecp_normalize_jac( const mbedtls_ecp_group *grp, mbedtls_ecp_point *pt )
744{
745 int ret;
746 mbedtls_mpi Zi, ZZi;
747
748 if( mbedtls_mpi_cmp_int( &pt->Z, 0 ) == 0 )
749 return( 0 );
750
751 mbedtls_mpi_init( &Zi ); mbedtls_mpi_init( &ZZi );
752
753 /*
754 * X = X / Z^2 mod p
755 */
756 MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &Zi, &pt->Z, &grp->P ) );
757 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ZZi, &Zi, &Zi ) ); MOD_MUL( ZZi );
758 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &pt->X, &pt->X, &ZZi ) ); MOD_MUL( pt->X );
759
760 /*
761 * Y = Y / Z^3 mod p
762 */
763 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &pt->Y, &pt->Y, &ZZi ) ); MOD_MUL( pt->Y );
764 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &pt->Y, &pt->Y, &Zi ) ); MOD_MUL( pt->Y );
765
766 /*
767 * Z = 1
768 */
769 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &pt->Z, 1 ) );
770
771cleanup:
772
773 mbedtls_mpi_free( &Zi ); mbedtls_mpi_free( &ZZi );
774
775 return( ret );
776}
777
778/*
779 * Normalize jacobian coordinates of an array of (pointers to) points,
780 * using Montgomery's trick to perform only one inversion mod P.
781 * (See for example Cohen's "A Course in Computational Algebraic Number
782 * Theory", Algorithm 10.3.4.)
783 *
784 * Warning: fails (returning an error) if one of the points is zero!
785 * This should never happen, see choice of w in ecp_mul_comb().
786 *
787 * Cost: 1N(t) := 1I + (6t - 3)M + 1S
788 */
789static int ecp_normalize_jac_many( const mbedtls_ecp_group *grp,
790 mbedtls_ecp_point *T[], size_t t_len )
791{
792 int ret;
793 size_t i;
794 mbedtls_mpi *c, u, Zi, ZZi;
795
796 if( t_len < 2 )
797 return( ecp_normalize_jac( grp, *T ) );
798
799 if( ( c = mbedtls_calloc( t_len, sizeof( mbedtls_mpi ) ) ) == NULL )
800 return( MBEDTLS_ERR_ECP_ALLOC_FAILED );
801
802 mbedtls_mpi_init( &u ); mbedtls_mpi_init( &Zi ); mbedtls_mpi_init( &ZZi );
803
804 /*
805 * c[i] = Z_0 * ... * Z_i
806 */
807 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &c[0], &T[0]->Z ) );
808 for( i = 1; i < t_len; i++ )
809 {
810 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &c[i], &c[i-1], &T[i]->Z ) );
811 MOD_MUL( c[i] );
812 }
813
814 /*
815 * u = 1 / (Z_0 * ... * Z_n) mod P
816 */
817 MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &u, &c[t_len-1], &grp->P ) );
818
819 for( i = t_len - 1; ; i-- )
820 {
821 /*
822 * Zi = 1 / Z_i mod p
823 * u = 1 / (Z_0 * ... * Z_i) mod P
824 */
825 if( i == 0 ) {
826 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &Zi, &u ) );
827 }
828 else
829 {
830 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &Zi, &u, &c[i-1] ) ); MOD_MUL( Zi );
831 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &u, &u, &T[i]->Z ) ); MOD_MUL( u );
832 }
833
834 /*
835 * proceed as in normalize()
836 */
837 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ZZi, &Zi, &Zi ) ); MOD_MUL( ZZi );
838 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T[i]->X, &T[i]->X, &ZZi ) ); MOD_MUL( T[i]->X );
839 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T[i]->Y, &T[i]->Y, &ZZi ) ); MOD_MUL( T[i]->Y );
840 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T[i]->Y, &T[i]->Y, &Zi ) ); MOD_MUL( T[i]->Y );
841
842 /*
843 * Post-precessing: reclaim some memory by shrinking coordinates
844 * - not storing Z (always 1)
845 * - shrinking other coordinates, but still keeping the same number of
846 * limbs as P, as otherwise it will too likely be regrown too fast.
847 */
848 MBEDTLS_MPI_CHK( mbedtls_mpi_shrink( &T[i]->X, grp->P.n ) );
849 MBEDTLS_MPI_CHK( mbedtls_mpi_shrink( &T[i]->Y, grp->P.n ) );
850 mbedtls_mpi_free( &T[i]->Z );
851
852 if( i == 0 )
853 break;
854 }
855
856cleanup:
857
858 mbedtls_mpi_free( &u ); mbedtls_mpi_free( &Zi ); mbedtls_mpi_free( &ZZi );
859 for( i = 0; i < t_len; i++ )
860 mbedtls_mpi_free( &c[i] );
861 mbedtls_free( c );
862
863 return( ret );
864}
865
866/*
867 * Conditional point inversion: Q -> -Q = (Q.X, -Q.Y, Q.Z) without leak.
868 * "inv" must be 0 (don't invert) or 1 (invert) or the result will be invalid
869 */
870static int ecp_safe_invert_jac( const mbedtls_ecp_group *grp,
871 mbedtls_ecp_point *Q,
872 unsigned char inv )
873{
874 int ret;
875 unsigned char nonzero;
876 mbedtls_mpi mQY;
877
878 mbedtls_mpi_init( &mQY );
879
880 /* Use the fact that -Q.Y mod P = P - Q.Y unless Q.Y == 0 */
881 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &mQY, &grp->P, &Q->Y ) );
882 nonzero = mbedtls_mpi_cmp_int( &Q->Y, 0 ) != 0;
883 MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_assign( &Q->Y, &mQY, inv & nonzero ) );
884
885cleanup:
886 mbedtls_mpi_free( &mQY );
887
888 return( ret );
889}
890
891/*
892 * Point doubling R = 2 P, Jacobian coordinates
893 *
894 * Based on http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#doubling-dbl-1998-cmo-2 .
895 *
896 * We follow the variable naming fairly closely. The formula variations that trade a MUL for a SQR
897 * (plus a few ADDs) aren't useful as our bignum implementation doesn't distinguish squaring.
898 *
899 * Standard optimizations are applied when curve parameter A is one of { 0, -3 }.
900 *
901 * Cost: 1D := 3M + 4S (A == 0)
902 * 4M + 4S (A == -3)
903 * 3M + 6S + 1a otherwise
904 */
905static int ecp_double_jac( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
906 const mbedtls_ecp_point *P )
907{
908 int ret;
909 mbedtls_mpi M, S, T, U;
910
911#if defined(MBEDTLS_SELF_TEST)
912 dbl_count++;
913#endif
914
915 mbedtls_mpi_init( &M ); mbedtls_mpi_init( &S ); mbedtls_mpi_init( &T ); mbedtls_mpi_init( &U );
916
917 /* Special case for A = -3 */
918 if( grp->A.p == NULL )
919 {
920 /* M = 3(X + Z^2)(X - Z^2) */
921 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S, &P->Z, &P->Z ) ); MOD_MUL( S );
922 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &T, &P->X, &S ) ); MOD_ADD( T );
923 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &U, &P->X, &S ) ); MOD_SUB( U );
924 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S, &T, &U ) ); MOD_MUL( S );
925 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &M, &S, 3 ) ); MOD_ADD( M );
926 }
927 else
928 {
929 /* M = 3.X^2 */
930 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S, &P->X, &P->X ) ); MOD_MUL( S );
931 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &M, &S, 3 ) ); MOD_ADD( M );
932
933 /* Optimize away for "koblitz" curves with A = 0 */
934 if( mbedtls_mpi_cmp_int( &grp->A, 0 ) != 0 )
935 {
936 /* M += A.Z^4 */
937 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S, &P->Z, &P->Z ) ); MOD_MUL( S );
938 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &S, &S ) ); MOD_MUL( T );
939 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S, &T, &grp->A ) ); MOD_MUL( S );
940 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &M, &M, &S ) ); MOD_ADD( M );
941 }
942 }
943
944 /* S = 4.X.Y^2 */
945 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &P->Y, &P->Y ) ); MOD_MUL( T );
946 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &T, 1 ) ); MOD_ADD( T );
947 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S, &P->X, &T ) ); MOD_MUL( S );
948 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &S, 1 ) ); MOD_ADD( S );
949
950 /* U = 8.Y^4 */
951 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &U, &T, &T ) ); MOD_MUL( U );
952 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &U, 1 ) ); MOD_ADD( U );
953
954 /* T = M^2 - 2.S */
955 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &M, &M ) ); MOD_MUL( T );
956 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T, &T, &S ) ); MOD_SUB( T );
957 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T, &T, &S ) ); MOD_SUB( T );
958
959 /* S = M(S - T) - U */
960 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &S, &S, &T ) ); MOD_SUB( S );
961 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S, &S, &M ) ); MOD_MUL( S );
962 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &S, &S, &U ) ); MOD_SUB( S );
963
964 /* U = 2.Y.Z */
965 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &U, &P->Y, &P->Z ) ); MOD_MUL( U );
966 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &U, 1 ) ); MOD_ADD( U );
967
968 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->X, &T ) );
969 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->Y, &S ) );
970 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->Z, &U ) );
971
972cleanup:
973 mbedtls_mpi_free( &M ); mbedtls_mpi_free( &S ); mbedtls_mpi_free( &T ); mbedtls_mpi_free( &U );
974
975 return( ret );
976}
977
978/*
979 * Addition: R = P + Q, mixed affine-Jacobian coordinates (GECC 3.22)
980 *
981 * The coordinates of Q must be normalized (= affine),
982 * but those of P don't need to. R is not normalized.
983 *
984 * Special cases: (1) P or Q is zero, (2) R is zero, (3) P == Q.
985 * None of these cases can happen as intermediate step in ecp_mul_comb():
986 * - at each step, P, Q and R are multiples of the base point, the factor
987 * being less than its order, so none of them is zero;
988 * - Q is an odd multiple of the base point, P an even multiple,
989 * due to the choice of precomputed points in the modified comb method.
990 * So branches for these cases do not leak secret information.
991 *
992 * We accept Q->Z being unset (saving memory in tables) as meaning 1.
993 *
994 * Cost: 1A := 8M + 3S
995 */
996static int ecp_add_mixed( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
997 const mbedtls_ecp_point *P, const mbedtls_ecp_point *Q )
998{
999 int ret;
1000 mbedtls_mpi T1, T2, T3, T4, X, Y, Z;
1001
1002#if defined(MBEDTLS_SELF_TEST)
1003 add_count++;
1004#endif
1005
1006 /*
1007 * Trivial cases: P == 0 or Q == 0 (case 1)
1008 */
1009 if( mbedtls_mpi_cmp_int( &P->Z, 0 ) == 0 )
1010 return( mbedtls_ecp_copy( R, Q ) );
1011
1012 if( Q->Z.p != NULL && mbedtls_mpi_cmp_int( &Q->Z, 0 ) == 0 )
1013 return( mbedtls_ecp_copy( R, P ) );
1014
1015 /*
1016 * Make sure Q coordinates are normalized
1017 */
1018 if( Q->Z.p != NULL && mbedtls_mpi_cmp_int( &Q->Z, 1 ) != 0 )
1019 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
1020
1021 mbedtls_mpi_init( &T1 ); mbedtls_mpi_init( &T2 ); mbedtls_mpi_init( &T3 ); mbedtls_mpi_init( &T4 );
1022 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z );
1023
1024 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T1, &P->Z, &P->Z ) ); MOD_MUL( T1 );
1025 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T2, &T1, &P->Z ) ); MOD_MUL( T2 );
1026 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T1, &T1, &Q->X ) ); MOD_MUL( T1 );
1027 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T2, &T2, &Q->Y ) ); MOD_MUL( T2 );
1028 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T1, &T1, &P->X ) ); MOD_SUB( T1 );
1029 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T2, &T2, &P->Y ) ); MOD_SUB( T2 );
1030
1031 /* Special cases (2) and (3) */
1032 if( mbedtls_mpi_cmp_int( &T1, 0 ) == 0 )
1033 {
1034 if( mbedtls_mpi_cmp_int( &T2, 0 ) == 0 )
1035 {
1036 ret = ecp_double_jac( grp, R, P );
1037 goto cleanup;
1038 }
1039 else
1040 {
1041 ret = mbedtls_ecp_set_zero( R );
1042 goto cleanup;
1043 }
1044 }
1045
1046 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &Z, &P->Z, &T1 ) ); MOD_MUL( Z );
1047 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T3, &T1, &T1 ) ); MOD_MUL( T3 );
1048 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T4, &T3, &T1 ) ); MOD_MUL( T4 );
1049 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T3, &T3, &P->X ) ); MOD_MUL( T3 );
1050 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &T1, &T3, 2 ) ); MOD_ADD( T1 );
1051 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &X, &T2, &T2 ) ); MOD_MUL( X );
1052 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &X, &X, &T1 ) ); MOD_SUB( X );
1053 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &X, &X, &T4 ) ); MOD_SUB( X );
1054 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T3, &T3, &X ) ); MOD_SUB( T3 );
1055 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T3, &T3, &T2 ) ); MOD_MUL( T3 );
1056 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T4, &T4, &P->Y ) ); MOD_MUL( T4 );
1057 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &Y, &T3, &T4 ) ); MOD_SUB( Y );
1058
1059 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->X, &X ) );
1060 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->Y, &Y ) );
1061 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->Z, &Z ) );
1062
1063cleanup:
1064
1065 mbedtls_mpi_free( &T1 ); mbedtls_mpi_free( &T2 ); mbedtls_mpi_free( &T3 ); mbedtls_mpi_free( &T4 );
1066 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z );
1067
1068 return( ret );
1069}
1070
1071/*
1072 * Randomize jacobian coordinates:
1073 * (X, Y, Z) -> (l^2 X, l^3 Y, l Z) for random l
1074 * This is sort of the reverse operation of ecp_normalize_jac().
1075 *
1076 * This countermeasure was first suggested in [2].
1077 */
1078static int ecp_randomize_jac( const mbedtls_ecp_group *grp, mbedtls_ecp_point *pt,
1079 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
1080{
1081 int ret;
1082 mbedtls_mpi l, ll;
1083 size_t p_size = ( grp->pbits + 7 ) / 8;
1084 int count = 0;
1085
1086 mbedtls_mpi_init( &l ); mbedtls_mpi_init( &ll );
1087
1088 /* Generate l such that 1 < l < p */
1089 do
1090 {
1091 mbedtls_mpi_fill_random( &l, p_size, f_rng, p_rng );
1092
1093 while( mbedtls_mpi_cmp_mpi( &l, &grp->P ) >= 0 )
1094 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &l, 1 ) );
1095
1096 if( count++ > 10 )
1097 return( MBEDTLS_ERR_ECP_RANDOM_FAILED );
1098 }
1099 while( mbedtls_mpi_cmp_int( &l, 1 ) <= 0 );
1100
1101 /* Z = l * Z */
1102 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &pt->Z, &pt->Z, &l ) ); MOD_MUL( pt->Z );
1103
1104 /* X = l^2 * X */
1105 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ll, &l, &l ) ); MOD_MUL( ll );
1106 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &pt->X, &pt->X, &ll ) ); MOD_MUL( pt->X );
1107
1108 /* Y = l^3 * Y */
1109 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ll, &ll, &l ) ); MOD_MUL( ll );
1110 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &pt->Y, &pt->Y, &ll ) ); MOD_MUL( pt->Y );
1111
1112cleanup:
1113 mbedtls_mpi_free( &l ); mbedtls_mpi_free( &ll );
1114
1115 return( ret );
1116}
1117
1118/*
1119 * Check and define parameters used by the comb method (see below for details)
1120 */
1121#if MBEDTLS_ECP_WINDOW_SIZE < 2 || MBEDTLS_ECP_WINDOW_SIZE > 7
1122#error "MBEDTLS_ECP_WINDOW_SIZE out of bounds"
1123#endif
1124
1125/* d = ceil( n / w ) */
1126#define COMB_MAX_D ( MBEDTLS_ECP_MAX_BITS + 1 ) / 2
1127
1128/* number of precomputed points */
1129#define COMB_MAX_PRE ( 1 << ( MBEDTLS_ECP_WINDOW_SIZE - 1 ) )
1130
1131/*
1132 * Compute the representation of m that will be used with our comb method.
1133 *
1134 * The basic comb method is described in GECC 3.44 for example. We use a
1135 * modified version that provides resistance to SPA by avoiding zero
1136 * digits in the representation as in [3]. We modify the method further by
1137 * requiring that all K_i be odd, which has the small cost that our
1138 * representation uses one more K_i, due to carries.
1139 *
1140 * Also, for the sake of compactness, only the seven low-order bits of x[i]
1141 * are used to represent K_i, and the msb of x[i] encodes the the sign (s_i in
1142 * the paper): it is set if and only if if s_i == -1;
1143 *
1144 * Calling conventions:
1145 * - x is an array of size d + 1
1146 * - w is the size, ie number of teeth, of the comb, and must be between
1147 * 2 and 7 (in practice, between 2 and MBEDTLS_ECP_WINDOW_SIZE)
1148 * - m is the MPI, expected to be odd and such that bitlength(m) <= w * d
1149 * (the result will be incorrect if these assumptions are not satisfied)
1150 */
1151static void ecp_comb_fixed( unsigned char x[], size_t d,
1152 unsigned char w, const mbedtls_mpi *m )
1153{
1154 size_t i, j;
1155 unsigned char c, cc, adjust;
1156
1157 memset( x, 0, d+1 );
1158
1159 /* First get the classical comb values (except for x_d = 0) */
1160 for( i = 0; i < d; i++ )
1161 for( j = 0; j < w; j++ )
1162 x[i] |= mbedtls_mpi_get_bit( m, i + d * j ) << j;
1163
1164 /* Now make sure x_1 .. x_d are odd */
1165 c = 0;
1166 for( i = 1; i <= d; i++ )
1167 {
1168 /* Add carry and update it */
1169 cc = x[i] & c;
1170 x[i] = x[i] ^ c;
1171 c = cc;
1172
1173 /* Adjust if needed, avoiding branches */
1174 adjust = 1 - ( x[i] & 0x01 );
1175 c |= x[i] & ( x[i-1] * adjust );
1176 x[i] = x[i] ^ ( x[i-1] * adjust );
1177 x[i-1] |= adjust << 7;
1178 }
1179}
1180
1181/*
1182 * Precompute points for the comb method
1183 *
1184 * If i = i_{w-1} ... i_1 is the binary representation of i, then
1185 * T[i] = i_{w-1} 2^{(w-1)d} P + ... + i_1 2^d P + P
1186 *
1187 * T must be able to hold 2^{w - 1} elements
1188 *
1189 * Cost: d(w-1) D + (2^{w-1} - 1) A + 1 N(w-1) + 1 N(2^{w-1} - 1)
1190 */
1191static int ecp_precompute_comb( const mbedtls_ecp_group *grp,
1192 mbedtls_ecp_point T[], const mbedtls_ecp_point *P,
1193 unsigned char w, size_t d )
1194{
1195 int ret;
1196 unsigned char i, k;
1197 size_t j;
1198 mbedtls_ecp_point *cur, *TT[COMB_MAX_PRE - 1];
1199
1200 /*
1201 * Set T[0] = P and
1202 * T[2^{l-1}] = 2^{dl} P for l = 1 .. w-1 (this is not the final value)
1203 */
1204 MBEDTLS_MPI_CHK( mbedtls_ecp_copy( &T[0], P ) );
1205
1206 k = 0;
1207 for( i = 1; i < ( 1U << ( w - 1 ) ); i <<= 1 )
1208 {
1209 cur = T + i;
1210 MBEDTLS_MPI_CHK( mbedtls_ecp_copy( cur, T + ( i >> 1 ) ) );
1211 for( j = 0; j < d; j++ )
1212 MBEDTLS_MPI_CHK( ecp_double_jac( grp, cur, cur ) );
1213
1214 TT[k++] = cur;
1215 }
1216
1217 MBEDTLS_MPI_CHK( ecp_normalize_jac_many( grp, TT, k ) );
1218
1219 /*
1220 * Compute the remaining ones using the minimal number of additions
1221 * Be careful to update T[2^l] only after using it!
1222 */
1223 k = 0;
1224 for( i = 1; i < ( 1U << ( w - 1 ) ); i <<= 1 )
1225 {
1226 j = i;
1227 while( j-- )
1228 {
1229 MBEDTLS_MPI_CHK( ecp_add_mixed( grp, &T[i + j], &T[j], &T[i] ) );
1230 TT[k++] = &T[i + j];
1231 }
1232 }
1233
1234 MBEDTLS_MPI_CHK( ecp_normalize_jac_many( grp, TT, k ) );
1235
1236cleanup:
1237 return( ret );
1238}
1239
1240/*
1241 * Select precomputed point: R = sign(i) * T[ abs(i) / 2 ]
1242 */
1243static int ecp_select_comb( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
1244 const mbedtls_ecp_point T[], unsigned char t_len,
1245 unsigned char i )
1246{
1247 int ret;
1248 unsigned char ii, j;
1249
1250 /* Ignore the "sign" bit and scale down */
1251 ii = ( i & 0x7Fu ) >> 1;
1252
1253 /* Read the whole table to thwart cache-based timing attacks */
1254 for( j = 0; j < t_len; j++ )
1255 {
1256 MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_assign( &R->X, &T[j].X, j == ii ) );
1257 MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_assign( &R->Y, &T[j].Y, j == ii ) );
1258 }
1259
1260 /* Safely invert result if i is "negative" */
1261 MBEDTLS_MPI_CHK( ecp_safe_invert_jac( grp, R, i >> 7 ) );
1262
1263cleanup:
1264 return( ret );
1265}
1266
1267/*
1268 * Core multiplication algorithm for the (modified) comb method.
1269 * This part is actually common with the basic comb method (GECC 3.44)
1270 *
1271 * Cost: d A + d D + 1 R
1272 */
1273static int ecp_mul_comb_core( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
1274 const mbedtls_ecp_point T[], unsigned char t_len,
1275 const unsigned char x[], size_t d,
1276 int (*f_rng)(void *, unsigned char *, size_t),
1277 void *p_rng )
1278{
1279 int ret;
1280 mbedtls_ecp_point Txi;
1281 size_t i;
1282
1283 mbedtls_ecp_point_init( &Txi );
1284
1285 /* Start with a non-zero point and randomize its coordinates */
1286 i = d;
1287 MBEDTLS_MPI_CHK( ecp_select_comb( grp, R, T, t_len, x[i] ) );
1288 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &R->Z, 1 ) );
1289 if( f_rng != 0 )
1290 MBEDTLS_MPI_CHK( ecp_randomize_jac( grp, R, f_rng, p_rng ) );
1291
1292 while( i-- != 0 )
1293 {
1294 MBEDTLS_MPI_CHK( ecp_double_jac( grp, R, R ) );
1295 MBEDTLS_MPI_CHK( ecp_select_comb( grp, &Txi, T, t_len, x[i] ) );
1296 MBEDTLS_MPI_CHK( ecp_add_mixed( grp, R, R, &Txi ) );
1297 }
1298
1299cleanup:
1300 mbedtls_ecp_point_free( &Txi );
1301
1302 return( ret );
1303}
1304
1305/*
1306 * Multiplication using the comb method,
1307 * for curves in short Weierstrass form
1308 */
1309static int ecp_mul_comb( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
1310 const mbedtls_mpi *m, const mbedtls_ecp_point *P,
1311 int (*f_rng)(void *, unsigned char *, size_t),
1312 void *p_rng )
1313{
1314 int ret;
1315 unsigned char w, m_is_odd, p_eq_g, pre_len, i;
1316 size_t d;
1317 unsigned char k[COMB_MAX_D + 1];
1318 mbedtls_ecp_point *T;
1319 mbedtls_mpi M, mm;
1320
1321 mbedtls_mpi_init( &M );
1322 mbedtls_mpi_init( &mm );
1323
1324 /* we need N to be odd to trnaform m in an odd number, check now */
1325 if( mbedtls_mpi_get_bit( &grp->N, 0 ) != 1 )
1326 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
1327
1328 /*
1329 * Minimize the number of multiplications, that is minimize
1330 * 10 * d * w + 18 * 2^(w-1) + 11 * d + 7 * w, with d = ceil( nbits / w )
1331 * (see costs of the various parts, with 1S = 1M)
1332 */
1333 w = grp->nbits >= 384 ? 5 : 4;
1334
1335 /*
1336 * If P == G, pre-compute a bit more, since this may be re-used later.
1337 * Just adding one avoids upping the cost of the first mul too much,
1338 * and the memory cost too.
1339 */
1340#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1
1341 p_eq_g = ( mbedtls_mpi_cmp_mpi( &P->Y, &grp->G.Y ) == 0 &&
1342 mbedtls_mpi_cmp_mpi( &P->X, &grp->G.X ) == 0 );
1343 if( p_eq_g )
1344 w++;
1345#else
1346 p_eq_g = 0;
1347#endif
1348
1349 /*
1350 * Make sure w is within bounds.
1351 * (The last test is useful only for very small curves in the test suite.)
1352 */
1353 if( w > MBEDTLS_ECP_WINDOW_SIZE )
1354 w = MBEDTLS_ECP_WINDOW_SIZE;
1355 if( w >= grp->nbits )
1356 w = 2;
1357
1358 /* Other sizes that depend on w */
1359 pre_len = 1U << ( w - 1 );
1360 d = ( grp->nbits + w - 1 ) / w;
1361
1362 /*
1363 * Prepare precomputed points: if P == G we want to
1364 * use grp->T if already initialized, or initialize it.
1365 */
1366 T = p_eq_g ? grp->T : NULL;
1367
1368 if( T == NULL )
1369 {
1370 T = mbedtls_calloc( pre_len, sizeof( mbedtls_ecp_point ) );
1371 if( T == NULL )
1372 {
1373 ret = MBEDTLS_ERR_ECP_ALLOC_FAILED;
1374 goto cleanup;
1375 }
1376
1377 MBEDTLS_MPI_CHK( ecp_precompute_comb( grp, T, P, w, d ) );
1378
1379 if( p_eq_g )
1380 {
1381 grp->T = T;
1382 grp->T_size = pre_len;
1383 }
1384 }
1385
1386 /*
1387 * Make sure M is odd (M = m or M = N - m, since N is odd)
1388 * using the fact that m * P = - (N - m) * P
1389 */
1390 m_is_odd = ( mbedtls_mpi_get_bit( m, 0 ) == 1 );
1391 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &M, m ) );
1392 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &mm, &grp->N, m ) );
1393 MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_assign( &M, &mm, ! m_is_odd ) );
1394
1395 /*
1396 * Go for comb multiplication, R = M * P
1397 */
1398 ecp_comb_fixed( k, d, w, &M );
1399 MBEDTLS_MPI_CHK( ecp_mul_comb_core( grp, R, T, pre_len, k, d, f_rng, p_rng ) );
1400
1401 /*
1402 * Now get m * P from M * P and normalize it
1403 */
1404 MBEDTLS_MPI_CHK( ecp_safe_invert_jac( grp, R, ! m_is_odd ) );
1405 MBEDTLS_MPI_CHK( ecp_normalize_jac( grp, R ) );
1406
1407cleanup:
1408
1409 if( T != NULL && ! p_eq_g )
1410 {
1411 for( i = 0; i < pre_len; i++ )
1412 mbedtls_ecp_point_free( &T[i] );
1413 mbedtls_free( T );
1414 }
1415
1416 mbedtls_mpi_free( &M );
1417 mbedtls_mpi_free( &mm );
1418
1419 if( ret != 0 )
1420 mbedtls_ecp_point_free( R );
1421
1422 return( ret );
1423}
1424
1425#endif /* ECP_SHORTWEIERSTRASS */
1426
1427#if defined(ECP_MONTGOMERY)
1428/*
1429 * For Montgomery curves, we do all the internal arithmetic in projective
1430 * coordinates. Import/export of points uses only the x coordinates, which is
1431 * internaly represented as X / Z.
1432 *
1433 * For scalar multiplication, we'll use a Montgomery ladder.
1434 */
1435
1436/*
1437 * Normalize Montgomery x/z coordinates: X = X/Z, Z = 1
1438 * Cost: 1M + 1I
1439 */
1440static int ecp_normalize_mxz( const mbedtls_ecp_group *grp, mbedtls_ecp_point *P )
1441{
1442 int ret;
1443
1444 MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &P->Z, &P->Z, &grp->P ) );
1445 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &P->X, &P->X, &P->Z ) ); MOD_MUL( P->X );
1446 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &P->Z, 1 ) );
1447
1448cleanup:
1449 return( ret );
1450}
1451
1452/*
1453 * Randomize projective x/z coordinates:
1454 * (X, Z) -> (l X, l Z) for random l
1455 * This is sort of the reverse operation of ecp_normalize_mxz().
1456 *
1457 * This countermeasure was first suggested in [2].
1458 * Cost: 2M
1459 */
1460static int ecp_randomize_mxz( const mbedtls_ecp_group *grp, mbedtls_ecp_point *P,
1461 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
1462{
1463 int ret;
1464 mbedtls_mpi l;
1465 size_t p_size = ( grp->pbits + 7 ) / 8;
1466 int count = 0;
1467
1468 mbedtls_mpi_init( &l );
1469
1470 /* Generate l such that 1 < l < p */
1471 do
1472 {
1473 mbedtls_mpi_fill_random( &l, p_size, f_rng, p_rng );
1474
1475 while( mbedtls_mpi_cmp_mpi( &l, &grp->P ) >= 0 )
1476 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &l, 1 ) );
1477
1478 if( count++ > 10 )
1479 return( MBEDTLS_ERR_ECP_RANDOM_FAILED );
1480 }
1481 while( mbedtls_mpi_cmp_int( &l, 1 ) <= 0 );
1482
1483 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &P->X, &P->X, &l ) ); MOD_MUL( P->X );
1484 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &P->Z, &P->Z, &l ) ); MOD_MUL( P->Z );
1485
1486cleanup:
1487 mbedtls_mpi_free( &l );
1488
1489 return( ret );
1490}
1491
1492/*
1493 * Double-and-add: R = 2P, S = P + Q, with d = X(P - Q),
1494 * for Montgomery curves in x/z coordinates.
1495 *
1496 * http://www.hyperelliptic.org/EFD/g1p/auto-code/montgom/xz/ladder/mladd-1987-m.op3
1497 * with
1498 * d = X1
1499 * P = (X2, Z2)
1500 * Q = (X3, Z3)
1501 * R = (X4, Z4)
1502 * S = (X5, Z5)
1503 * and eliminating temporary variables tO, ..., t4.
1504 *
1505 * Cost: 5M + 4S
1506 */
1507static int ecp_double_add_mxz( const mbedtls_ecp_group *grp,
1508 mbedtls_ecp_point *R, mbedtls_ecp_point *S,
1509 const mbedtls_ecp_point *P, const mbedtls_ecp_point *Q,
1510 const mbedtls_mpi *d )
1511{
1512 int ret;
1513 mbedtls_mpi A, AA, B, BB, E, C, D, DA, CB;
1514
1515 mbedtls_mpi_init( &A ); mbedtls_mpi_init( &AA ); mbedtls_mpi_init( &B );
1516 mbedtls_mpi_init( &BB ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &C );
1517 mbedtls_mpi_init( &D ); mbedtls_mpi_init( &DA ); mbedtls_mpi_init( &CB );
1518
1519 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &A, &P->X, &P->Z ) ); MOD_ADD( A );
1520 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &AA, &A, &A ) ); MOD_MUL( AA );
1521 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &B, &P->X, &P->Z ) ); MOD_SUB( B );
1522 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &BB, &B, &B ) ); MOD_MUL( BB );
1523 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &E, &AA, &BB ) ); MOD_SUB( E );
1524 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &C, &Q->X, &Q->Z ) ); MOD_ADD( C );
1525 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &D, &Q->X, &Q->Z ) ); MOD_SUB( D );
1526 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &DA, &D, &A ) ); MOD_MUL( DA );
1527 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &CB, &C, &B ) ); MOD_MUL( CB );
1528 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &S->X, &DA, &CB ) ); MOD_MUL( S->X );
1529 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S->X, &S->X, &S->X ) ); MOD_MUL( S->X );
1530 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &S->Z, &DA, &CB ) ); MOD_SUB( S->Z );
1531 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S->Z, &S->Z, &S->Z ) ); MOD_MUL( S->Z );
1532 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S->Z, d, &S->Z ) ); MOD_MUL( S->Z );
1533 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &R->X, &AA, &BB ) ); MOD_MUL( R->X );
1534 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &R->Z, &grp->A, &E ) ); MOD_MUL( R->Z );
1535 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &R->Z, &BB, &R->Z ) ); MOD_ADD( R->Z );
1536 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &R->Z, &E, &R->Z ) ); MOD_MUL( R->Z );
1537
1538cleanup:
1539 mbedtls_mpi_free( &A ); mbedtls_mpi_free( &AA ); mbedtls_mpi_free( &B );
1540 mbedtls_mpi_free( &BB ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &C );
1541 mbedtls_mpi_free( &D ); mbedtls_mpi_free( &DA ); mbedtls_mpi_free( &CB );
1542
1543 return( ret );
1544}
1545
1546/*
1547 * Multiplication with Montgomery ladder in x/z coordinates,
1548 * for curves in Montgomery form
1549 */
1550static int ecp_mul_mxz( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
1551 const mbedtls_mpi *m, const mbedtls_ecp_point *P,
1552 int (*f_rng)(void *, unsigned char *, size_t),
1553 void *p_rng )
1554{
1555 int ret;
1556 size_t i;
1557 unsigned char b;
1558 mbedtls_ecp_point RP;
1559 mbedtls_mpi PX;
1560
1561 mbedtls_ecp_point_init( &RP ); mbedtls_mpi_init( &PX );
1562
1563 /* Save PX and read from P before writing to R, in case P == R */
1564 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &PX, &P->X ) );
1565 MBEDTLS_MPI_CHK( mbedtls_ecp_copy( &RP, P ) );
1566
1567 /* Set R to zero in modified x/z coordinates */
1568 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &R->X, 1 ) );
1569 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &R->Z, 0 ) );
1570 mbedtls_mpi_free( &R->Y );
1571
1572 /* RP.X might be sligtly larger than P, so reduce it */
1573 MOD_ADD( RP.X );
1574
1575 /* Randomize coordinates of the starting point */
1576 if( f_rng != NULL )
1577 MBEDTLS_MPI_CHK( ecp_randomize_mxz( grp, &RP, f_rng, p_rng ) );
1578
1579 /* Loop invariant: R = result so far, RP = R + P */
1580 i = mbedtls_mpi_bitlen( m ); /* one past the (zero-based) most significant bit */
1581 while( i-- > 0 )
1582 {
1583 b = mbedtls_mpi_get_bit( m, i );
1584 /*
1585 * if (b) R = 2R + P else R = 2R,
1586 * which is:
1587 * if (b) double_add( RP, R, RP, R )
1588 * else double_add( R, RP, R, RP )
1589 * but using safe conditional swaps to avoid leaks
1590 */
1591 MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_swap( &R->X, &RP.X, b ) );
1592 MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_swap( &R->Z, &RP.Z, b ) );
1593 MBEDTLS_MPI_CHK( ecp_double_add_mxz( grp, R, &RP, R, &RP, &PX ) );
1594 MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_swap( &R->X, &RP.X, b ) );
1595 MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_swap( &R->Z, &RP.Z, b ) );
1596 }
1597
1598 MBEDTLS_MPI_CHK( ecp_normalize_mxz( grp, R ) );
1599
1600cleanup:
1601 mbedtls_ecp_point_free( &RP ); mbedtls_mpi_free( &PX );
1602
1603 return( ret );
1604}
1605
1606#endif /* ECP_MONTGOMERY */
1607
1608/*
1609 * Multiplication R = m * P
1610 */
1611int mbedtls_ecp_mul( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
1612 const mbedtls_mpi *m, const mbedtls_ecp_point *P,
1613 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
1614{
1615 int ret;
1616
1617 /* Common sanity checks */
1618 if( mbedtls_mpi_cmp_int( &P->Z, 1 ) != 0 )
1619 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
1620
1621 if( ( ret = mbedtls_ecp_check_privkey( grp, m ) ) != 0 ||
1622 ( ret = mbedtls_ecp_check_pubkey( grp, P ) ) != 0 )
1623 return( ret );
1624
1625#if defined(ECP_MONTGOMERY)
1626 if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY )
1627 return( ecp_mul_mxz( grp, R, m, P, f_rng, p_rng ) );
1628#endif
1629#if defined(ECP_SHORTWEIERSTRASS)
1630 if( ecp_get_type( grp ) == ECP_TYPE_SHORT_WEIERSTRASS )
1631 return( ecp_mul_comb( grp, R, m, P, f_rng, p_rng ) );
1632#endif
1633 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
1634}
1635
1636#if defined(ECP_SHORTWEIERSTRASS)
1637/*
1638 * Check that an affine point is valid as a public key,
1639 * short weierstrass curves (SEC1 3.2.3.1)
1640 */
1641static int ecp_check_pubkey_sw( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *pt )
1642{
1643 int ret;
1644 mbedtls_mpi YY, RHS;
1645
1646 /* pt coordinates must be normalized for our checks */
1647 if( mbedtls_mpi_cmp_int( &pt->X, 0 ) < 0 ||
1648 mbedtls_mpi_cmp_int( &pt->Y, 0 ) < 0 ||
1649 mbedtls_mpi_cmp_mpi( &pt->X, &grp->P ) >= 0 ||
1650 mbedtls_mpi_cmp_mpi( &pt->Y, &grp->P ) >= 0 )
1651 return( MBEDTLS_ERR_ECP_INVALID_KEY );
1652
1653 mbedtls_mpi_init( &YY ); mbedtls_mpi_init( &RHS );
1654
1655 /*
1656 * YY = Y^2
1657 * RHS = X (X^2 + A) + B = X^3 + A X + B
1658 */
1659 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &YY, &pt->Y, &pt->Y ) ); MOD_MUL( YY );
1660 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &RHS, &pt->X, &pt->X ) ); MOD_MUL( RHS );
1661
1662 /* Special case for A = -3 */
1663 if( grp->A.p == NULL )
1664 {
1665 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &RHS, &RHS, 3 ) ); MOD_SUB( RHS );
1666 }
1667 else
1668 {
1669 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &RHS, &RHS, &grp->A ) ); MOD_ADD( RHS );
1670 }
1671
1672 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &RHS, &RHS, &pt->X ) ); MOD_MUL( RHS );
1673 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &RHS, &RHS, &grp->B ) ); MOD_ADD( RHS );
1674
1675 if( mbedtls_mpi_cmp_mpi( &YY, &RHS ) != 0 )
1676 ret = MBEDTLS_ERR_ECP_INVALID_KEY;
1677
1678cleanup:
1679
1680 mbedtls_mpi_free( &YY ); mbedtls_mpi_free( &RHS );
1681
1682 return( ret );
1683}
1684#endif /* ECP_SHORTWEIERSTRASS */
1685
1686/*
1687 * R = m * P with shortcuts for m == 1 and m == -1
1688 * NOT constant-time - ONLY for short Weierstrass!
1689 */
1690static int mbedtls_ecp_mul_shortcuts( mbedtls_ecp_group *grp,
1691 mbedtls_ecp_point *R,
1692 const mbedtls_mpi *m,
1693 const mbedtls_ecp_point *P )
1694{
1695 int ret;
1696
1697 if( mbedtls_mpi_cmp_int( m, 1 ) == 0 )
1698 {
1699 MBEDTLS_MPI_CHK( mbedtls_ecp_copy( R, P ) );
1700 }
1701 else if( mbedtls_mpi_cmp_int( m, -1 ) == 0 )
1702 {
1703 MBEDTLS_MPI_CHK( mbedtls_ecp_copy( R, P ) );
1704 if( mbedtls_mpi_cmp_int( &R->Y, 0 ) != 0 )
1705 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &R->Y, &grp->P, &R->Y ) );
1706 }
1707 else
1708 {
1709 MBEDTLS_MPI_CHK( mbedtls_ecp_mul( grp, R, m, P, NULL, NULL ) );
1710 }
1711
1712cleanup:
1713 return( ret );
1714}
1715
1716/*
1717 * Linear combination
1718 * NOT constant-time
1719 */
1720int mbedtls_ecp_muladd( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
1721 const mbedtls_mpi *m, const mbedtls_ecp_point *P,
1722 const mbedtls_mpi *n, const mbedtls_ecp_point *Q )
1723{
1724 int ret;
1725 mbedtls_ecp_point mP;
1726
1727 if( ecp_get_type( grp ) != ECP_TYPE_SHORT_WEIERSTRASS )
1728 return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
1729
1730 mbedtls_ecp_point_init( &mP );
1731
1732 MBEDTLS_MPI_CHK( mbedtls_ecp_mul_shortcuts( grp, &mP, m, P ) );
1733 MBEDTLS_MPI_CHK( mbedtls_ecp_mul_shortcuts( grp, R, n, Q ) );
1734
1735 MBEDTLS_MPI_CHK( ecp_add_mixed( grp, R, &mP, R ) );
1736 MBEDTLS_MPI_CHK( ecp_normalize_jac( grp, R ) );
1737
1738cleanup:
1739 mbedtls_ecp_point_free( &mP );
1740
1741 return( ret );
1742}
1743
1744
1745#if defined(ECP_MONTGOMERY)
1746/*
1747 * Check validity of a public key for Montgomery curves with x-only schemes
1748 */
1749static int ecp_check_pubkey_mx( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *pt )
1750{
1751 /* [Curve25519 p. 5] Just check X is the correct number of bytes */
1752 if( mbedtls_mpi_size( &pt->X ) > ( grp->nbits + 7 ) / 8 )
1753 return( MBEDTLS_ERR_ECP_INVALID_KEY );
1754
1755 return( 0 );
1756}
1757#endif /* ECP_MONTGOMERY */
1758
1759/*
1760 * Check that a point is valid as a public key
1761 */
1762int mbedtls_ecp_check_pubkey( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *pt )
1763{
1764 /* Must use affine coordinates */
1765 if( mbedtls_mpi_cmp_int( &pt->Z, 1 ) != 0 )
1766 return( MBEDTLS_ERR_ECP_INVALID_KEY );
1767
1768#if defined(ECP_MONTGOMERY)
1769 if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY )
1770 return( ecp_check_pubkey_mx( grp, pt ) );
1771#endif
1772#if defined(ECP_SHORTWEIERSTRASS)
1773 if( ecp_get_type( grp ) == ECP_TYPE_SHORT_WEIERSTRASS )
1774 return( ecp_check_pubkey_sw( grp, pt ) );
1775#endif
1776 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
1777}
1778
1779/*
1780 * Check that an mbedtls_mpi is valid as a private key
1781 */
1782int mbedtls_ecp_check_privkey( const mbedtls_ecp_group *grp, const mbedtls_mpi *d )
1783{
1784#if defined(ECP_MONTGOMERY)
1785 if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY )
1786 {
1787 /* see [Curve25519] page 5 */
1788 if( mbedtls_mpi_get_bit( d, 0 ) != 0 ||
1789 mbedtls_mpi_get_bit( d, 1 ) != 0 ||
1790 mbedtls_mpi_get_bit( d, 2 ) != 0 ||
1791 mbedtls_mpi_bitlen( d ) - 1 != grp->nbits ) /* mbedtls_mpi_bitlen is one-based! */
1792 return( MBEDTLS_ERR_ECP_INVALID_KEY );
1793 else
1794 return( 0 );
1795 }
1796#endif /* ECP_MONTGOMERY */
1797#if defined(ECP_SHORTWEIERSTRASS)
1798 if( ecp_get_type( grp ) == ECP_TYPE_SHORT_WEIERSTRASS )
1799 {
1800 /* see SEC1 3.2 */
1801 if( mbedtls_mpi_cmp_int( d, 1 ) < 0 ||
1802 mbedtls_mpi_cmp_mpi( d, &grp->N ) >= 0 )
1803 return( MBEDTLS_ERR_ECP_INVALID_KEY );
1804 else
1805 return( 0 );
1806 }
1807#endif /* ECP_SHORTWEIERSTRASS */
1808
1809 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
1810}
1811
1812/*
1813 * Generate a keypair with configurable base point
1814 */
1815int mbedtls_ecp_gen_keypair_base( mbedtls_ecp_group *grp,
1816 const mbedtls_ecp_point *G,
1817 mbedtls_mpi *d, mbedtls_ecp_point *Q,
1818 int (*f_rng)(void *, unsigned char *, size_t),
1819 void *p_rng )
1820{
1821 int ret;
1822 size_t n_size = ( grp->nbits + 7 ) / 8;
1823
1824#if defined(ECP_MONTGOMERY)
1825 if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY )
1826 {
1827 /* [M225] page 5 */
1828 size_t b;
1829
1830 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( d, n_size, f_rng, p_rng ) );
1831
1832 /* Make sure the most significant bit is nbits */
1833 b = mbedtls_mpi_bitlen( d ) - 1; /* mbedtls_mpi_bitlen is one-based */
1834 if( b > grp->nbits )
1835 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( d, b - grp->nbits ) );
1836 else
1837 MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, grp->nbits, 1 ) );
1838
1839 /* Make sure the last three bits are unset */
1840 MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, 0, 0 ) );
1841 MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, 1, 0 ) );
1842 MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, 2, 0 ) );
1843 }
1844 else
1845#endif /* ECP_MONTGOMERY */
1846#if defined(ECP_SHORTWEIERSTRASS)
1847 if( ecp_get_type( grp ) == ECP_TYPE_SHORT_WEIERSTRASS )
1848 {
1849 /* SEC1 3.2.1: Generate d such that 1 <= n < N */
1850 int count = 0;
1851 unsigned char rnd[MBEDTLS_ECP_MAX_BYTES];
1852
1853 /*
1854 * Match the procedure given in RFC 6979 (deterministic ECDSA):
1855 * - use the same byte ordering;
1856 * - keep the leftmost nbits bits of the generated octet string;
1857 * - try until result is in the desired range.
1858 * This also avoids any biais, which is especially important for ECDSA.
1859 */
1860 do
1861 {
1862 MBEDTLS_MPI_CHK( f_rng( p_rng, rnd, n_size ) );
1863 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( d, rnd, n_size ) );
1864 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( d, 8 * n_size - grp->nbits ) );
1865
1866 /*
1867 * Each try has at worst a probability 1/2 of failing (the msb has
1868 * a probability 1/2 of being 0, and then the result will be < N),
1869 * so after 30 tries failure probability is a most 2**(-30).
1870 *
1871 * For most curves, 1 try is enough with overwhelming probability,
1872 * since N starts with a lot of 1s in binary, but some curves
1873 * such as secp224k1 are actually very close to the worst case.
1874 */
1875 if( ++count > 30 )
1876 return( MBEDTLS_ERR_ECP_RANDOM_FAILED );
1877 }
1878 while( mbedtls_mpi_cmp_int( d, 1 ) < 0 ||
1879 mbedtls_mpi_cmp_mpi( d, &grp->N ) >= 0 );
1880 }
1881 else
1882#endif /* ECP_SHORTWEIERSTRASS */
1883 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
1884
1885cleanup:
1886 if( ret != 0 )
1887 return( ret );
1888
1889 return( mbedtls_ecp_mul( grp, Q, d, G, f_rng, p_rng ) );
1890}
1891
1892/*
1893 * Generate key pair, wrapper for conventional base point
1894 */
1895int mbedtls_ecp_gen_keypair( mbedtls_ecp_group *grp,
1896 mbedtls_mpi *d, mbedtls_ecp_point *Q,
1897 int (*f_rng)(void *, unsigned char *, size_t),
1898 void *p_rng )
1899{
1900 return( mbedtls_ecp_gen_keypair_base( grp, &grp->G, d, Q, f_rng, p_rng ) );
1901}
1902
1903/*
1904 * Generate a keypair, prettier wrapper
1905 */
1906int mbedtls_ecp_gen_key( mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key,
1907 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
1908{
1909 int ret;
1910
1911 if( ( ret = mbedtls_ecp_group_load( &key->grp, grp_id ) ) != 0 )
1912 return( ret );
1913
1914 return( mbedtls_ecp_gen_keypair( &key->grp, &key->d, &key->Q, f_rng, p_rng ) );
1915}
1916
1917/*
1918 * Check a public-private key pair
1919 */
1920int mbedtls_ecp_check_pub_priv( const mbedtls_ecp_keypair *pub, const mbedtls_ecp_keypair *prv )
1921{
1922 int ret;
1923 mbedtls_ecp_point Q;
1924 mbedtls_ecp_group grp;
1925
1926 if( pub->grp.id == MBEDTLS_ECP_DP_NONE ||
1927 pub->grp.id != prv->grp.id ||
1928 mbedtls_mpi_cmp_mpi( &pub->Q.X, &prv->Q.X ) ||
1929 mbedtls_mpi_cmp_mpi( &pub->Q.Y, &prv->Q.Y ) ||
1930 mbedtls_mpi_cmp_mpi( &pub->Q.Z, &prv->Q.Z ) )
1931 {
1932 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
1933 }
1934
1935 mbedtls_ecp_point_init( &Q );
1936 mbedtls_ecp_group_init( &grp );
1937
1938 /* mbedtls_ecp_mul() needs a non-const group... */
1939 mbedtls_ecp_group_copy( &grp, &prv->grp );
1940
1941 /* Also checks d is valid */
1942 MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &Q, &prv->d, &prv->grp.G, NULL, NULL ) );
1943
1944 if( mbedtls_mpi_cmp_mpi( &Q.X, &prv->Q.X ) ||
1945 mbedtls_mpi_cmp_mpi( &Q.Y, &prv->Q.Y ) ||
1946 mbedtls_mpi_cmp_mpi( &Q.Z, &prv->Q.Z ) )
1947 {
1948 ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
1949 goto cleanup;
1950 }
1951
1952cleanup:
1953 mbedtls_ecp_point_free( &Q );
1954 mbedtls_ecp_group_free( &grp );
1955
1956 return( ret );
1957}
1958
1959#if defined(MBEDTLS_SELF_TEST)
1960
1961/*
1962 * Checkup routine
1963 */
1964int mbedtls_ecp_self_test( int verbose )
1965{
1966 int ret;
1967 size_t i;
1968 mbedtls_ecp_group grp;
1969 mbedtls_ecp_point R, P;
1970 mbedtls_mpi m;
1971 unsigned long add_c_prev, dbl_c_prev, mul_c_prev;
1972 /* exponents especially adapted for secp192r1 */
1973 const char *exponents[] =
1974 {
1975 "000000000000000000000000000000000000000000000001", /* one */
1976 "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22830", /* N - 1 */
1977 "5EA6F389A38B8BC81E767753B15AA5569E1782E30ABE7D25", /* random */
1978 "400000000000000000000000000000000000000000000000", /* one and zeros */
1979 "7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", /* all ones */
1980 "555555555555555555555555555555555555555555555555", /* 101010... */
1981 };
1982
1983 mbedtls_ecp_group_init( &grp );
1984 mbedtls_ecp_point_init( &R );
1985 mbedtls_ecp_point_init( &P );
1986 mbedtls_mpi_init( &m );
1987
1988 /* Use secp192r1 if available, or any available curve */
1989#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
1990 MBEDTLS_MPI_CHK( mbedtls_ecp_group_load( &grp, MBEDTLS_ECP_DP_SECP192R1 ) );
1991#else
1992 MBEDTLS_MPI_CHK( mbedtls_ecp_group_load( &grp, mbedtls_ecp_curve_list()->grp_id ) );
1993#endif
1994
1995 if( verbose != 0 )
1996 mbedtls_printf( " ECP test #1 (constant op_count, base point G): " );
1997
1998 /* Do a dummy multiplication first to trigger precomputation */
1999 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &m, 2 ) );
2000 MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &P, &m, &grp.G, NULL, NULL ) );
2001
2002 add_count = 0;
2003 dbl_count = 0;
2004 mul_count = 0;
2005 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &m, 16, exponents[0] ) );
2006 MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &R, &m, &grp.G, NULL, NULL ) );
2007
2008 for( i = 1; i < sizeof( exponents ) / sizeof( exponents[0] ); i++ )
2009 {
2010 add_c_prev = add_count;
2011 dbl_c_prev = dbl_count;
2012 mul_c_prev = mul_count;
2013 add_count = 0;
2014 dbl_count = 0;
2015 mul_count = 0;
2016
2017 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &m, 16, exponents[i] ) );
2018 MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &R, &m, &grp.G, NULL, NULL ) );
2019
2020 if( add_count != add_c_prev ||
2021 dbl_count != dbl_c_prev ||
2022 mul_count != mul_c_prev )
2023 {
2024 if( verbose != 0 )
2025 mbedtls_printf( "failed (%u)\n", (unsigned int) i );
2026
2027 ret = 1;
2028 goto cleanup;
2029 }
2030 }
2031
2032 if( verbose != 0 )
2033 mbedtls_printf( "passed\n" );
2034
2035 if( verbose != 0 )
2036 mbedtls_printf( " ECP test #2 (constant op_count, other point): " );
2037 /* We computed P = 2G last time, use it */
2038
2039 add_count = 0;
2040 dbl_count = 0;
2041 mul_count = 0;
2042 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &m, 16, exponents[0] ) );
2043 MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &R, &m, &P, NULL, NULL ) );
2044
2045 for( i = 1; i < sizeof( exponents ) / sizeof( exponents[0] ); i++ )
2046 {
2047 add_c_prev = add_count;
2048 dbl_c_prev = dbl_count;
2049 mul_c_prev = mul_count;
2050 add_count = 0;
2051 dbl_count = 0;
2052 mul_count = 0;
2053
2054 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &m, 16, exponents[i] ) );
2055 MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &R, &m, &P, NULL, NULL ) );
2056
2057 if( add_count != add_c_prev ||
2058 dbl_count != dbl_c_prev ||
2059 mul_count != mul_c_prev )
2060 {
2061 if( verbose != 0 )
2062 mbedtls_printf( "failed (%u)\n", (unsigned int) i );
2063
2064 ret = 1;
2065 goto cleanup;
2066 }
2067 }
2068
2069 if( verbose != 0 )
2070 mbedtls_printf( "passed\n" );
2071
2072cleanup:
2073
2074 if( ret < 0 && verbose != 0 )
2075 mbedtls_printf( "Unexpected error, return code = %08X\n", ret );
2076
2077 mbedtls_ecp_group_free( &grp );
2078 mbedtls_ecp_point_free( &R );
2079 mbedtls_ecp_point_free( &P );
2080 mbedtls_mpi_free( &m );
2081
2082 if( verbose != 0 )
2083 mbedtls_printf( "\n" );
2084
2085 return( ret );
2086}
2087
2088#endif /* MBEDTLS_SELF_TEST */
2089
2090#endif /* MBEDTLS_ECP_C */
Note: See TracBrowser for help on using the repository browser.