2014-11-15 15:28:10 +00:00
/**********************************************************************
2015-04-22 19:07:31 +00:00
* Copyright (c) 2013, 2014, 2015 Pieter Wuille, Gregory Maxwell *
2014-11-15 15:28:10 +00:00
* Distributed under the MIT software license, see the accompanying *
* file COPYING or http://www.opensource.org/licenses/mit-license.php.*
**********************************************************************/
2013-05-09 15:24:32 +02:00
2014-01-17 22:52:33 -05:00
#if defined HAVE_CONFIG_H
#include "libsecp256k1-config.h"
#endif
2014-01-17 22:52:33 -05:00
#include <stdio.h>
2014-06-16 01:30:17 +02:00
#include <stdlib.h>
2013-03-10 21:25:19 +01:00
2014-12-08 20:48:58 +01:00
#include <time.h>
2014-08-03 19:54:41 +02:00
#include "secp256k1.c"
2015-09-27 23:47:01 +00:00
#include "include/secp256k1.h"
2014-11-12 15:41:47 -08:00
#include "testrand_impl.h"
2013-03-10 21:25:19 +01:00
2013-05-05 16:55:05 +02:00
#ifdef ENABLE_OPENSSL_TESTS
#include "openssl/bn.h"
#include "openssl/ec.h"
#include "openssl/ecdsa.h"
#include "openssl/obj_mac.h"
#endif
2015-10-14 17:43:20 +02:00
#include "contrib/lax_der_parsing.h"
2015-09-27 23:47:01 +00:00
#if !defined(VG_CHECK)
# if defined(VALGRIND)
# include <valgrind/memcheck.h>
# define VG_UNDEF(x,y) VALGRIND_MAKE_MEM_UNDEFINED((x),(y))
# define VG_CHECK(x,y) VALGRIND_CHECK_MEM_IS_DEFINED((x),(y))
# else
# define VG_UNDEF(x,y)
# define VG_CHECK(x,y)
# endif
#endif
2014-10-27 02:25:48 -07:00
static int count = 64 ;
2015-09-21 20:57:54 +02:00
static secp256k1_context * ctx = NULL ;
2013-03-24 10:38:35 +01:00
2015-09-21 20:57:54 +02:00
void random_field_element_test ( secp256k1_fe * fe ) {
2014-11-11 10:32:50 -08:00
do {
unsigned char b32 [ 32 ];
secp256k1_rand256_test ( b32 );
2014-11-27 19:12:13 +01:00
if ( secp256k1_fe_set_b32 ( fe , b32 )) {
break ;
}
2014-11-11 10:32:50 -08:00
} while ( 1 );
}
2015-09-21 20:57:54 +02:00
void random_field_element_magnitude ( secp256k1_fe * fe ) {
secp256k1_fe zero ;
2015-10-17 21:15:15 +02:00
int n = secp256k1_rand_int ( 9 );
2014-11-11 10:32:50 -08:00
secp256k1_fe_normalize ( fe );
2014-12-29 15:38:17 +01:00
if ( n == 0 ) {
return ;
2014-11-11 10:32:50 -08:00
}
2014-12-29 15:38:17 +01:00
secp256k1_fe_clear ( & zero );
secp256k1_fe_negate ( & zero , & zero , 0 );
secp256k1_fe_mul_int ( & zero , n - 1 );
secp256k1_fe_add ( fe , & zero );
2015-07-06 12:41:30 +09:30
VERIFY_CHECK ( fe -> magnitude == n );
2014-11-11 10:32:50 -08:00
}
2015-09-21 20:57:54 +02:00
void random_group_element_test ( secp256k1_ge * ge ) {
secp256k1_fe fe ;
2014-11-11 10:32:50 -08:00
do {
random_field_element_test ( & fe );
2015-10-17 21:15:15 +02:00
if ( secp256k1_ge_set_xo_var ( ge , & fe , secp256k1_rand_bits ( 1 ))) {
2015-05-13 21:16:13 -05:00
secp256k1_fe_normalize ( & ge -> y );
2014-11-11 10:32:50 -08:00
break ;
2015-03-27 23:14:17 +00:00
}
2014-11-11 10:32:50 -08:00
} while ( 1 );
}
2015-09-21 20:57:54 +02:00
void random_group_element_jacobian_test ( secp256k1_gej * gej , const secp256k1_ge * ge ) {
secp256k1_fe z2 , z3 ;
2014-11-11 10:32:50 -08:00
do {
random_field_element_test ( & gej -> z );
if ( ! secp256k1_fe_is_zero ( & gej -> z )) {
break ;
}
} while ( 1 );
2015-01-25 15:47:04 +00:00
secp256k1_fe_sqr ( & z2 , & gej -> z );
secp256k1_fe_mul ( & z3 , & z2 , & gej -> z );
2014-11-11 10:32:50 -08:00
secp256k1_fe_mul ( & gej -> x , & ge -> x , & z2 );
secp256k1_fe_mul ( & gej -> y , & ge -> y , & z3 );
gej -> infinity = ge -> infinity ;
}
2015-09-21 20:57:54 +02:00
void random_scalar_order_test ( secp256k1_scalar * num ) {
2014-10-28 04:08:15 -07:00
do {
unsigned char b32 [ 32 ];
int overflow = 0 ;
2015-01-25 15:47:04 +00:00
secp256k1_rand256_test ( b32 );
2014-10-29 00:35:09 -07:00
secp256k1_scalar_set_b32 ( num , b32 , & overflow );
2015-03-27 23:14:17 +00:00
if ( overflow || secp256k1_scalar_is_zero ( num )) {
2014-10-28 04:08:15 -07:00
continue ;
2015-03-27 23:14:17 +00:00
}
2014-10-28 04:08:15 -07:00
break ;
} while ( 1 );
}
2015-09-21 20:57:54 +02:00
void random_scalar_order ( secp256k1_scalar * num ) {
2014-11-26 17:26:39 +01:00
do {
unsigned char b32 [ 32 ];
int overflow = 0 ;
2015-01-25 15:47:04 +00:00
secp256k1_rand256 ( b32 );
2014-11-26 17:26:39 +01:00
secp256k1_scalar_set_b32 ( num , b32 , & overflow );
2015-03-27 23:14:17 +00:00
if ( overflow || secp256k1_scalar_is_zero ( num )) {
2014-11-26 17:26:39 +01:00
continue ;
2015-03-27 23:14:17 +00:00
}
2014-11-26 17:26:39 +01:00
break ;
} while ( 1 );
}
2015-04-11 14:06:54 -05:00
void run_context_tests ( void ) {
2015-09-21 20:57:54 +02:00
secp256k1_context * none = secp256k1_context_create ( 0 );
secp256k1_context * sign = secp256k1_context_create ( SECP256K1_CONTEXT_SIGN );
secp256k1_context * vrfy = secp256k1_context_create ( SECP256K1_CONTEXT_VERIFY );
secp256k1_context * both = secp256k1_context_create ( SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY );
2015-04-11 14:06:54 -05:00
2015-09-21 20:57:54 +02:00
secp256k1_gej pubj ;
secp256k1_ge pub ;
secp256k1_scalar msg , key , nonce ;
secp256k1_scalar sigr , sigs ;
2015-04-11 14:06:54 -05:00
/*** clone and destroy all of them to make sure cloning was complete ***/
{
2015-09-21 20:57:54 +02:00
secp256k1_context * ctx_tmp ;
2015-04-11 14:06:54 -05:00
ctx_tmp = none ; none = secp256k1_context_clone ( none ); secp256k1_context_destroy ( ctx_tmp );
ctx_tmp = sign ; sign = secp256k1_context_clone ( sign ); secp256k1_context_destroy ( ctx_tmp );
ctx_tmp = vrfy ; vrfy = secp256k1_context_clone ( vrfy ); secp256k1_context_destroy ( ctx_tmp );
ctx_tmp = both ; both = secp256k1_context_clone ( both ); secp256k1_context_destroy ( ctx_tmp );
}
/*** attempt to use them ***/
random_scalar_order_test ( & msg );
random_scalar_order_test ( & key );
secp256k1_ecmult_gen ( & both -> ecmult_gen_ctx , & pubj , & key );
secp256k1_ge_set_gej ( & pub , & pubj );
/* obtain a working nonce */
do {
random_scalar_order_test ( & nonce );
2015-07-26 16:51:58 +02:00
} while ( ! secp256k1_ecdsa_sig_sign ( & both -> ecmult_gen_ctx , & sigr , & sigs , & key , & msg , & nonce , NULL ));
2015-04-11 14:06:54 -05:00
/* try signing */
2015-07-26 16:51:58 +02:00
CHECK ( secp256k1_ecdsa_sig_sign ( & sign -> ecmult_gen_ctx , & sigr , & sigs , & key , & msg , & nonce , NULL ));
CHECK ( secp256k1_ecdsa_sig_sign ( & both -> ecmult_gen_ctx , & sigr , & sigs , & key , & msg , & nonce , NULL ));
2015-04-11 14:06:54 -05:00
/* try verifying */
2015-07-26 16:51:58 +02:00
CHECK ( secp256k1_ecdsa_sig_verify ( & vrfy -> ecmult_ctx , & sigr , & sigs , & pub , & msg ));
CHECK ( secp256k1_ecdsa_sig_verify ( & both -> ecmult_ctx , & sigr , & sigs , & pub , & msg ));
2015-04-16 15:56:04 -05:00
/* cleanup */
secp256k1_context_destroy ( none );
secp256k1_context_destroy ( sign );
secp256k1_context_destroy ( vrfy );
secp256k1_context_destroy ( both );
2015-04-11 14:06:54 -05:00
}
2014-12-13 17:02:30 +01:00
/***** HASH TESTS *****/
void run_sha256_tests ( void ) {
static const char * inputs [ 8 ] = {
"" , "abc" , "message digest" , "secure hash algorithm" , "SHA256 is considered to be safe" ,
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" ,
"For this sample, this 63-byte string will be used as input data" ,
"This is exactly 64 bytes long, not counting the terminating byte"
};
static const unsigned char outputs [ 8 ][ 32 ] = {
{ 0xe3 , 0xb0 , 0xc4 , 0x42 , 0x98 , 0xfc , 0x1c , 0x14 , 0x9a , 0xfb , 0xf4 , 0xc8 , 0x99 , 0x6f , 0xb9 , 0x24 , 0x27 , 0xae , 0x41 , 0xe4 , 0x64 , 0x9b , 0x93 , 0x4c , 0xa4 , 0x95 , 0x99 , 0x1b , 0x78 , 0x52 , 0xb8 , 0x55 },
{ 0xba , 0x78 , 0x16 , 0xbf , 0x8f , 0x01 , 0xcf , 0xea , 0x41 , 0x41 , 0x40 , 0xde , 0x5d , 0xae , 0x22 , 0x23 , 0xb0 , 0x03 , 0x61 , 0xa3 , 0x96 , 0x17 , 0x7a , 0x9c , 0xb4 , 0x10 , 0xff , 0x61 , 0xf2 , 0x00 , 0x15 , 0xad },
{ 0xf7 , 0x84 , 0x6f , 0x55 , 0xcf , 0x23 , 0xe1 , 0x4e , 0xeb , 0xea , 0xb5 , 0xb4 , 0xe1 , 0x55 , 0x0c , 0xad , 0x5b , 0x50 , 0x9e , 0x33 , 0x48 , 0xfb , 0xc4 , 0xef , 0xa3 , 0xa1 , 0x41 , 0x3d , 0x39 , 0x3c , 0xb6 , 0x50 },
{ 0xf3 , 0x0c , 0xeb , 0x2b , 0xb2 , 0x82 , 0x9e , 0x79 , 0xe4 , 0xca , 0x97 , 0x53 , 0xd3 , 0x5a , 0x8e , 0xcc , 0x00 , 0x26 , 0x2d , 0x16 , 0x4c , 0xc0 , 0x77 , 0x08 , 0x02 , 0x95 , 0x38 , 0x1c , 0xbd , 0x64 , 0x3f , 0x0d },
{ 0x68 , 0x19 , 0xd9 , 0x15 , 0xc7 , 0x3f , 0x4d , 0x1e , 0x77 , 0xe4 , 0xe1 , 0xb5 , 0x2d , 0x1f , 0xa0 , 0xf9 , 0xcf , 0x9b , 0xea , 0xea , 0xd3 , 0x93 , 0x9f , 0x15 , 0x87 , 0x4b , 0xd9 , 0x88 , 0xe2 , 0xa2 , 0x36 , 0x30 },
{ 0x24 , 0x8d , 0x6a , 0x61 , 0xd2 , 0x06 , 0x38 , 0xb8 , 0xe5 , 0xc0 , 0x26 , 0x93 , 0x0c , 0x3e , 0x60 , 0x39 , 0xa3 , 0x3c , 0xe4 , 0x59 , 0x64 , 0xff , 0x21 , 0x67 , 0xf6 , 0xec , 0xed , 0xd4 , 0x19 , 0xdb , 0x06 , 0xc1 },
{ 0xf0 , 0x8a , 0x78 , 0xcb , 0xba , 0xee , 0x08 , 0x2b , 0x05 , 0x2a , 0xe0 , 0x70 , 0x8f , 0x32 , 0xfa , 0x1e , 0x50 , 0xc5 , 0xc4 , 0x21 , 0xaa , 0x77 , 0x2b , 0xa5 , 0xdb , 0xb4 , 0x06 , 0xa2 , 0xea , 0x6b , 0xe3 , 0x42 },
{ 0xab , 0x64 , 0xef , 0xf7 , 0xe8 , 0x8e , 0x2e , 0x46 , 0x16 , 0x5e , 0x29 , 0xf2 , 0xbc , 0xe4 , 0x18 , 0x26 , 0xbd , 0x4c , 0x7b , 0x35 , 0x52 , 0xf6 , 0xb3 , 0x82 , 0xa9 , 0xe7 , 0xd3 , 0xaf , 0x47 , 0xc2 , 0x45 , 0xf8 }
};
2015-01-25 15:47:04 +00:00
int i ;
for ( i = 0 ; i < 8 ; i ++ ) {
unsigned char out [ 32 ];
2014-12-13 17:02:30 +01:00
secp256k1_sha256_t hasher ;
secp256k1_sha256_initialize ( & hasher );
secp256k1_sha256_write ( & hasher , ( const unsigned char * )( inputs [ i ]), strlen ( inputs [ i ]));
secp256k1_sha256_finalize ( & hasher , out );
CHECK ( memcmp ( out , outputs [ i ], 32 ) == 0 );
if ( strlen ( inputs [ i ]) > 0 ) {
2015-10-17 21:15:15 +02:00
int split = secp256k1_rand_int ( strlen ( inputs [ i ]));
2015-01-25 15:47:04 +00:00
secp256k1_sha256_initialize ( & hasher );
2014-12-13 17:02:30 +01:00
secp256k1_sha256_write ( & hasher , ( const unsigned char * )( inputs [ i ]), split );
secp256k1_sha256_write ( & hasher , ( const unsigned char * )( inputs [ i ] + split ), strlen ( inputs [ i ]) - split );
secp256k1_sha256_finalize ( & hasher , out );
CHECK ( memcmp ( out , outputs [ i ], 32 ) == 0 );
}
}
}
void run_hmac_sha256_tests ( void ) {
static const char * keys [ 6 ] = {
" \x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b " ,
" \x4a\x65\x66\x65 " ,
" \xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa " ,
" \x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19 " ,
" \xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa " ,
" \xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa "
};
static const char * inputs [ 6 ] = {
" \x48\x69\x20\x54\x68\x65\x72\x65 " ,
" \x77\x68\x61\x74\x20\x64\x6f\x20\x79\x61\x20\x77\x61\x6e\x74\x20\x66\x6f\x72\x20\x6e\x6f\x74\x68\x69\x6e\x67\x3f " ,
" \xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd " ,
" \xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd " ,
" \x54\x65\x73\x74\x20\x55\x73\x69\x6e\x67\x20\x4c\x61\x72\x67\x65\x72\x20\x54\x68\x61\x6e\x20\x42\x6c\x6f\x63\x6b\x2d\x53\x69\x7a\x65\x20\x4b\x65\x79\x20\x2d\x20\x48\x61\x73\x68\x20\x4b\x65\x79\x20\x46\x69\x72\x73\x74 " ,
" \x54\x68\x69\x73\x20\x69\x73\x20\x61\x20\x74\x65\x73\x74\x20\x75\x73\x69\x6e\x67\x20\x61\x20\x6c\x61\x72\x67\x65\x72\x20\x74\x68\x61\x6e\x20\x62\x6c\x6f\x63\x6b\x2d\x73\x69\x7a\x65\x20\x6b\x65\x79\x20\x61\x6e\x64\x20\x61\x20\x6c\x61\x72\x67\x65\x72\x20\x74\x68\x61\x6e\x20\x62\x6c\x6f\x63\x6b\x2d\x73\x69\x7a\x65\x20\x64\x61\x74\x61\x2e\x20\x54\x68\x65\x20\x6b\x65\x79\x20\x6e\x65\x65\x64\x73\x20\x74\x6f\x20\x62\x65\x20\x68\x61\x73\x68\x65\x64\x20\x62\x65\x66\x6f\x72\x65\x20\x62\x65\x69\x6e\x67\x20\x75\x73\x65\x64\x20\x62\x79\x20\x74\x68\x65\x20\x48\x4d\x41\x43\x20\x61\x6c\x67\x6f\x72\x69\x74\x68\x6d\x2e "
};
static const unsigned char outputs [ 6 ][ 32 ] = {
{ 0xb0 , 0x34 , 0x4c , 0x61 , 0xd8 , 0xdb , 0x38 , 0x53 , 0x5c , 0xa8 , 0xaf , 0xce , 0xaf , 0x0b , 0xf1 , 0x2b , 0x88 , 0x1d , 0xc2 , 0x00 , 0xc9 , 0x83 , 0x3d , 0xa7 , 0x26 , 0xe9 , 0x37 , 0x6c , 0x2e , 0x32 , 0xcf , 0xf7 },
{ 0x5b , 0xdc , 0xc1 , 0x46 , 0xbf , 0x60 , 0x75 , 0x4e , 0x6a , 0x04 , 0x24 , 0x26 , 0x08 , 0x95 , 0x75 , 0xc7 , 0x5a , 0x00 , 0x3f , 0x08 , 0x9d , 0x27 , 0x39 , 0x83 , 0x9d , 0xec , 0x58 , 0xb9 , 0x64 , 0xec , 0x38 , 0x43 },
{ 0x77 , 0x3e , 0xa9 , 0x1e , 0x36 , 0x80 , 0x0e , 0x46 , 0x85 , 0x4d , 0xb8 , 0xeb , 0xd0 , 0x91 , 0x81 , 0xa7 , 0x29 , 0x59 , 0x09 , 0x8b , 0x3e , 0xf8 , 0xc1 , 0x22 , 0xd9 , 0x63 , 0x55 , 0x14 , 0xce , 0xd5 , 0x65 , 0xfe },
{ 0x82 , 0x55 , 0x8a , 0x38 , 0x9a , 0x44 , 0x3c , 0x0e , 0xa4 , 0xcc , 0x81 , 0x98 , 0x99 , 0xf2 , 0x08 , 0x3a , 0x85 , 0xf0 , 0xfa , 0xa3 , 0xe5 , 0x78 , 0xf8 , 0x07 , 0x7a , 0x2e , 0x3f , 0xf4 , 0x67 , 0x29 , 0x66 , 0x5b },
{ 0x60 , 0xe4 , 0x31 , 0x59 , 0x1e , 0xe0 , 0xb6 , 0x7f , 0x0d , 0x8a , 0x26 , 0xaa , 0xcb , 0xf5 , 0xb7 , 0x7f , 0x8e , 0x0b , 0xc6 , 0x21 , 0x37 , 0x28 , 0xc5 , 0x14 , 0x05 , 0x46 , 0x04 , 0x0f , 0x0e , 0xe3 , 0x7f , 0x54 },
{ 0x9b , 0x09 , 0xff , 0xa7 , 0x1b , 0x94 , 0x2f , 0xcb , 0x27 , 0x63 , 0x5f , 0xbc , 0xd5 , 0xb0 , 0xe9 , 0x44 , 0xbf , 0xdc , 0x63 , 0x64 , 0x4f , 0x07 , 0x13 , 0x93 , 0x8a , 0x7f , 0x51 , 0x53 , 0x5c , 0x3a , 0x35 , 0xe2 }
};
2015-01-25 15:47:04 +00:00
int i ;
for ( i = 0 ; i < 6 ; i ++ ) {
2014-12-13 17:02:30 +01:00
secp256k1_hmac_sha256_t hasher ;
2015-01-25 15:47:04 +00:00
unsigned char out [ 32 ];
2014-12-13 17:02:30 +01:00
secp256k1_hmac_sha256_initialize ( & hasher , ( const unsigned char * )( keys [ i ]), strlen ( keys [ i ]));
secp256k1_hmac_sha256_write ( & hasher , ( const unsigned char * )( inputs [ i ]), strlen ( inputs [ i ]));
secp256k1_hmac_sha256_finalize ( & hasher , out );
CHECK ( memcmp ( out , outputs [ i ], 32 ) == 0 );
if ( strlen ( inputs [ i ]) > 0 ) {
2015-10-17 21:15:15 +02:00
int split = secp256k1_rand_int ( strlen ( inputs [ i ]));
2015-01-25 15:47:04 +00:00
secp256k1_hmac_sha256_initialize ( & hasher , ( const unsigned char * )( keys [ i ]), strlen ( keys [ i ]));
2014-12-13 17:02:30 +01:00
secp256k1_hmac_sha256_write ( & hasher , ( const unsigned char * )( inputs [ i ]), split );
secp256k1_hmac_sha256_write ( & hasher , ( const unsigned char * )( inputs [ i ] + split ), strlen ( inputs [ i ]) - split );
secp256k1_hmac_sha256_finalize ( & hasher , out );
CHECK ( memcmp ( out , outputs [ i ], 32 ) == 0 );
}
}
}
void run_rfc6979_hmac_sha256_tests ( void ) {
2015-07-08 18:10:25 -04:00
static const unsigned char key1 [ 65 ] = { 0x01 , 0x02 , 0x03 , 0x04 , 0x05 , 0x06 , 0x07 , 0x08 , 0x09 , 0x0a , 0x0b , 0x0c , 0x0d , 0x0e , 0x0f , 0x10 , 0x11 , 0x12 , 0x13 , 0x14 , 0x15 , 0x16 , 0x17 , 0x18 , 0x19 , 0x1a , 0x1b , 0x1c , 0x1d , 0x1e , 0x1f , 0x00 , 0x4b , 0xf5 , 0x12 , 0x2f , 0x34 , 0x45 , 0x54 , 0xc5 , 0x3b , 0xde , 0x2e , 0xbb , 0x8c , 0xd2 , 0xb7 , 0xe3 , 0xd1 , 0x60 , 0x0a , 0xd6 , 0x31 , 0xc3 , 0x85 , 0xa5 , 0xd7 , 0xcc , 0xe2 , 0x3c , 0x77 , 0x85 , 0x45 , 0x9a , 0 };
2014-12-13 17:02:30 +01:00
static const unsigned char out1 [ 3 ][ 32 ] = {
{ 0x4f , 0xe2 , 0x95 , 0x25 , 0xb2 , 0x08 , 0x68 , 0x09 , 0x15 , 0x9a , 0xcd , 0xf0 , 0x50 , 0x6e , 0xfb , 0x86 , 0xb0 , 0xec , 0x93 , 0x2c , 0x7b , 0xa4 , 0x42 , 0x56 , 0xab , 0x32 , 0x1e , 0x42 , 0x1e , 0x67 , 0xe9 , 0xfb },
{ 0x2b , 0xf0 , 0xff , 0xf1 , 0xd3 , 0xc3 , 0x78 , 0xa2 , 0x2d , 0xc5 , 0xde , 0x1d , 0x85 , 0x65 , 0x22 , 0x32 , 0x5c , 0x65 , 0xb5 , 0x04 , 0x49 , 0x1a , 0x0c , 0xbd , 0x01 , 0xcb , 0x8f , 0x3a , 0xa6 , 0x7f , 0xfd , 0x4a },
{ 0xf5 , 0x28 , 0xb4 , 0x10 , 0xcb , 0x54 , 0x1f , 0x77 , 0x00 , 0x0d , 0x7a , 0xfb , 0x6c , 0x5b , 0x53 , 0xc5 , 0xc4 , 0x71 , 0xea , 0xb4 , 0x3e , 0x46 , 0x6d , 0x9a , 0xc5 , 0x19 , 0x0c , 0x39 , 0xc8 , 0x2f , 0xd8 , 0x2e }
};
2015-07-08 18:10:25 -04:00
static const unsigned char key2 [ 64 ] = { 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xe3 , 0xb0 , 0xc4 , 0x42 , 0x98 , 0xfc , 0x1c , 0x14 , 0x9a , 0xfb , 0xf4 , 0xc8 , 0x99 , 0x6f , 0xb9 , 0x24 , 0x27 , 0xae , 0x41 , 0xe4 , 0x64 , 0x9b , 0x93 , 0x4c , 0xa4 , 0x95 , 0x99 , 0x1b , 0x78 , 0x52 , 0xb8 , 0x55 };
2014-12-13 17:02:30 +01:00
static const unsigned char out2 [ 3 ][ 32 ] = {
{ 0x9c , 0x23 , 0x6c , 0x16 , 0x5b , 0x82 , 0xae , 0x0c , 0xd5 , 0x90 , 0x65 , 0x9e , 0x10 , 0x0b , 0x6b , 0xab , 0x30 , 0x36 , 0xe7 , 0xba , 0x8b , 0x06 , 0x74 , 0x9b , 0xaf , 0x69 , 0x81 , 0xe1 , 0x6f , 0x1a , 0x2b , 0x95 },
{ 0xdf , 0x47 , 0x10 , 0x61 , 0x62 , 0x5b , 0xc0 , 0xea , 0x14 , 0xb6 , 0x82 , 0xfe , 0xee , 0x2c , 0x9c , 0x02 , 0xf2 , 0x35 , 0xda , 0x04 , 0x20 , 0x4c , 0x1d , 0x62 , 0xa1 , 0x53 , 0x6c , 0x6e , 0x17 , 0xae , 0xd7 , 0xa9 },
{ 0x75 , 0x97 , 0x88 , 0x7c , 0xbd , 0x76 , 0x32 , 0x1f , 0x32 , 0xe3 , 0x04 , 0x40 , 0x67 , 0x9a , 0x22 , 0xcf , 0x7f , 0x8d , 0x9d , 0x2e , 0xac , 0x39 , 0x0e , 0x58 , 0x1f , 0xea , 0x09 , 0x1c , 0xe2 , 0x02 , 0xba , 0x94 }
};
secp256k1_rfc6979_hmac_sha256_t rng ;
unsigned char out [ 32 ];
2015-01-25 15:47:04 +00:00
int i ;
2014-12-13 17:02:30 +01:00
2015-07-08 18:10:25 -04:00
secp256k1_rfc6979_hmac_sha256_initialize ( & rng , key1 , 64 );
2015-01-25 15:47:04 +00:00
for ( i = 0 ; i < 3 ; i ++ ) {
2014-12-13 17:02:30 +01:00
secp256k1_rfc6979_hmac_sha256_generate ( & rng , out , 32 );
CHECK ( memcmp ( out , out1 [ i ], 32 ) == 0 );
}
secp256k1_rfc6979_hmac_sha256_finalize ( & rng );
2015-07-08 18:10:25 -04:00
secp256k1_rfc6979_hmac_sha256_initialize ( & rng , key1 , 65 );
2015-03-20 09:19:38 -07:00
for ( i = 0 ; i < 3 ; i ++ ) {
secp256k1_rfc6979_hmac_sha256_generate ( & rng , out , 32 );
CHECK ( memcmp ( out , out1 [ i ], 32 ) != 0 );
}
secp256k1_rfc6979_hmac_sha256_finalize ( & rng );
2015-07-08 18:10:25 -04:00
secp256k1_rfc6979_hmac_sha256_initialize ( & rng , key2 , 64 );
2015-01-25 15:47:04 +00:00
for ( i = 0 ; i < 3 ; i ++ ) {
2014-12-13 17:02:30 +01:00
secp256k1_rfc6979_hmac_sha256_generate ( & rng , out , 32 );
CHECK ( memcmp ( out , out2 [ i ], 32 ) == 0 );
}
secp256k1_rfc6979_hmac_sha256_finalize ( & rng );
}
2015-10-17 17:46:01 +02:00
/***** RANDOM TESTS *****/
void test_rand_bits ( int rand32 , int bits ) {
/* (1-1/2^B)^rounds[B] < 1/10^9, so rounds is the number of iterations to
* get a false negative chance below once in a billion */
static const unsigned int rounds [ 7 ] = { 1 , 30 , 73 , 156 , 322 , 653 , 1316 };
/* We try multiplying the results with various odd numbers, which shouldn't
* influence the uniform distribution modulo a power of 2. */
static const uint32_t mults [ 6 ] = { 1 , 3 , 21 , 289 , 0x9999 , 0x80402011 };
/* We only select up to 6 bits from the output to analyse */
unsigned int usebits = bits > 6 ? 6 : bits ;
unsigned int maxshift = bits - usebits ;
/* For each of the maxshift+1 usebits-bit sequences inside a bits-bit
number, track all observed outcomes, one per bit in a uint64_t. */
uint64_t x [ 6 ][ 27 ] = {{ 0 }};
unsigned int i , shift , m ;
/* Multiply the output of all rand calls with the odd number m, which
should not change the uniformity of its distribution. */
for ( i = 0 ; i < rounds [ usebits ]; i ++ ) {
uint32_t r = ( rand32 ? secp256k1_rand32 () : secp256k1_rand_bits ( bits ));
CHECK (((( uint64_t ) r ) >> bits ) == 0 );
for ( m = 0 ; m < sizeof ( mults ) / sizeof ( mults [ 0 ]); m ++ ) {
uint32_t rm = r * mults [ m ];
for ( shift = 0 ; shift <= maxshift ; shift ++ ) {
x [ m ][ shift ] |= ((( uint64_t ) 1 ) << (( rm >> shift ) & (( 1 << usebits ) - 1 )));
}
}
}
for ( m = 0 ; m < sizeof ( mults ) / sizeof ( mults [ 0 ]); m ++ ) {
for ( shift = 0 ; shift <= maxshift ; shift ++ ) {
/* Test that the lower usebits bits of x[shift] are 1 */
CHECK ((( ~ x [ m ][ shift ]) << ( 64 - ( 1 << usebits ))) == 0 );
}
}
}
/* Subrange must be a whole divisor of range, and at most 64 */
void test_rand_int ( uint32_t range , uint32_t subrange ) {
/* (1-1/subrange)^rounds < 1/10^9 */
int rounds = ( subrange * 2073 ) / 100 ;
int i ;
uint64_t x = 0 ;
CHECK (( range % subrange ) == 0 );
for ( i = 0 ; i < rounds ; i ++ ) {
uint32_t r = secp256k1_rand_int ( range );
CHECK ( r < range );
r = r % subrange ;
x |= ((( uint64_t ) 1 ) << r );
}
/* Test that the lower subrange bits of x are 1. */
CHECK ((( ~ x ) << ( 64 - subrange )) == 0 );
}
void run_rand_bits ( void ) {
size_t b ;
test_rand_bits ( 1 , 32 );
for ( b = 1 ; b <= 32 ; b ++ ) {
test_rand_bits ( 0 , b );
}
}
void run_rand_int ( void ) {
static const uint32_t ms [] = { 1 , 3 , 17 , 1000 , 13771 , 999999 , 33554432 };
static const uint32_t ss [] = { 1 , 3 , 6 , 9 , 13 , 31 , 64 };
unsigned int m , s ;
for ( m = 0 ; m < sizeof ( ms ) / sizeof ( ms [ 0 ]); m ++ ) {
for ( s = 0 ; s < sizeof ( ss ) / sizeof ( ss [ 0 ]); s ++ ) {
test_rand_int ( ms [ m ] * ss [ s ], ss [ s ]);
}
}
}
2014-11-27 19:12:13 +01:00
/***** NUM TESTS *****/
2014-11-28 01:23:55 +01:00
#ifndef USE_NUM_NONE
2015-09-21 20:57:54 +02:00
void random_num_negate ( secp256k1_num * num ) {
2015-10-17 21:15:15 +02:00
if ( secp256k1_rand_bits ( 1 )) {
2014-11-27 19:12:13 +01:00
secp256k1_num_negate ( num );
2015-03-27 23:14:17 +00:00
}
2014-11-27 19:12:13 +01:00
}
2015-09-21 20:57:54 +02:00
void random_num_order_test ( secp256k1_num * num ) {
secp256k1_scalar sc ;
2014-11-27 19:12:13 +01:00
random_scalar_order_test ( & sc );
secp256k1_scalar_get_num ( num , & sc );
}
2015-09-21 20:57:54 +02:00
void random_num_order ( secp256k1_num * num ) {
secp256k1_scalar sc ;
2014-11-27 19:12:13 +01:00
random_scalar_order ( & sc );
secp256k1_scalar_get_num ( num , & sc );
2013-04-21 19:07:21 +02:00
}
2014-11-12 13:24:12 -08:00
void test_num_negate ( void ) {
2015-09-21 20:57:54 +02:00
secp256k1_num n1 ;
secp256k1_num n2 ;
2014-11-15 15:28:10 +00:00
random_num_order_test ( & n1 ); /* n1 = R */
2013-04-22 01:52:56 +02:00
random_num_negate ( & n1 );
2014-11-15 15:28:10 +00:00
secp256k1_num_copy ( & n2 , & n1 ); /* n2 = R */
secp256k1_num_sub ( & n1 , & n2 , & n1 ); /* n1 = n2-n1 = 0 */
2014-06-16 01:30:17 +02:00
CHECK ( secp256k1_num_is_zero ( & n1 ));
2014-11-15 15:28:10 +00:00
secp256k1_num_copy ( & n1 , & n2 ); /* n1 = R */
secp256k1_num_negate ( & n1 ); /* n1 = -R */
2014-06-16 01:30:17 +02:00
CHECK ( ! secp256k1_num_is_zero ( & n1 ));
2014-11-15 15:28:10 +00:00
secp256k1_num_add ( & n1 , & n2 , & n1 ); /* n1 = n2+n1 = 0 */
2014-06-16 01:30:17 +02:00
CHECK ( secp256k1_num_is_zero ( & n1 ));
2014-11-15 15:28:10 +00:00
secp256k1_num_copy ( & n1 , & n2 ); /* n1 = R */
secp256k1_num_negate ( & n1 ); /* n1 = -R */
2014-06-16 01:30:17 +02:00
CHECK ( secp256k1_num_is_neg ( & n1 ) != secp256k1_num_is_neg ( & n2 ));
2014-11-15 15:28:10 +00:00
secp256k1_num_negate ( & n1 ); /* n1 = R */
2014-08-09 19:22:42 +02:00
CHECK ( secp256k1_num_eq ( & n1 , & n2 ));
2013-04-22 01:52:56 +02:00
}
2014-11-12 13:24:12 -08:00
void test_num_add_sub ( void ) {
2015-09-21 20:57:54 +02:00
secp256k1_num n1 ;
secp256k1_num n2 ;
secp256k1_num n1p2 , n2p1 , n1m2 , n2m1 ;
2014-11-15 15:28:10 +00:00
random_num_order_test ( & n1 ); /* n1 = R1 */
2015-10-17 21:15:15 +02:00
if ( secp256k1_rand_bits ( 1 )) {
2014-08-09 19:22:42 +02:00
random_num_negate ( & n1 );
}
2014-11-15 15:28:10 +00:00
random_num_order_test ( & n2 ); /* n2 = R2 */
2015-10-17 21:15:15 +02:00
if ( secp256k1_rand_bits ( 1 )) {
2014-08-09 19:22:42 +02:00
random_num_negate ( & n2 );
}
2014-11-15 15:28:10 +00:00
secp256k1_num_add ( & n1p2 , & n1 , & n2 ); /* n1p2 = R1 + R2 */
secp256k1_num_add ( & n2p1 , & n2 , & n1 ); /* n2p1 = R2 + R1 */
secp256k1_num_sub ( & n1m2 , & n1 , & n2 ); /* n1m2 = R1 - R2 */
secp256k1_num_sub ( & n2m1 , & n2 , & n1 ); /* n2m1 = R2 - R1 */
2014-08-09 19:22:42 +02:00
CHECK ( secp256k1_num_eq ( & n1p2 , & n2p1 ));
CHECK ( ! secp256k1_num_eq ( & n1p2 , & n1m2 ));
2014-11-15 15:28:10 +00:00
secp256k1_num_negate ( & n2m1 ); /* n2m1 = -R2 + R1 */
2014-08-09 19:22:42 +02:00
CHECK ( secp256k1_num_eq ( & n2m1 , & n1m2 ));
CHECK ( ! secp256k1_num_eq ( & n2m1 , & n1 ));
2014-11-15 15:28:10 +00:00
secp256k1_num_add ( & n2m1 , & n2m1 , & n2 ); /* n2m1 = -R2 + R1 + R2 = R1 */
2014-08-09 19:22:42 +02:00
CHECK ( secp256k1_num_eq ( & n2m1 , & n1 ));
CHECK ( ! secp256k1_num_eq ( & n2p1 , & n1 ));
2014-11-15 15:28:10 +00:00
secp256k1_num_sub ( & n2p1 , & n2p1 , & n2 ); /* n2p1 = R2 + R1 - R2 = R1 */
2014-08-09 19:22:42 +02:00
CHECK ( secp256k1_num_eq ( & n2p1 , & n1 ));
2013-04-22 01:52:56 +02:00
}
2014-11-12 13:24:12 -08:00
void run_num_smalltests ( void ) {
2015-01-25 15:47:04 +00:00
int i ;
for ( i = 0 ; i < 100 * count ; i ++ ) {
2013-04-22 01:52:56 +02:00
test_num_negate ();
test_num_add_sub ();
}
}
2014-11-28 01:23:55 +01:00
#endif
2013-04-22 01:52:56 +02:00
2014-10-29 00:35:38 -07:00
/***** SCALAR TESTS *****/
void scalar_test ( void ) {
2015-09-21 20:57:54 +02:00
secp256k1_scalar s ;
secp256k1_scalar s1 ;
secp256k1_scalar s2 ;
2015-01-25 15:47:04 +00:00
#ifndef USE_NUM_NONE
2015-09-21 20:57:54 +02:00
secp256k1_num snum , s1num , s2num ;
secp256k1_num order , half_order ;
2015-01-25 15:47:04 +00:00
#endif
2014-10-29 00:35:38 -07:00
unsigned char c [ 32 ];
2014-11-15 15:28:10 +00:00
/* Set 's' to a random scalar, with value 'snum'. */
2014-11-27 19:12:13 +01:00
random_scalar_order_test ( & s );
2014-10-29 00:35:38 -07:00
2014-11-15 15:28:10 +00:00
/* Set 's1' to a random scalar, with value 's1num'. */
2014-11-27 19:12:13 +01:00
random_scalar_order_test ( & s1 );
2014-10-29 00:35:38 -07:00
2014-11-15 15:28:10 +00:00
/* Set 's2' to a random scalar, with value 'snum2', and byte array representation 'c'. */
2014-11-27 19:12:13 +01:00
random_scalar_order_test ( & s2 );
secp256k1_scalar_get_b32 ( c , & s2 );
2014-11-28 01:23:55 +01:00
#ifndef USE_NUM_NONE
2014-11-27 19:12:13 +01:00
secp256k1_scalar_get_num ( & snum , & s );
secp256k1_scalar_get_num ( & s1num , & s1 );
secp256k1_scalar_get_num ( & s2num , & s2 );
secp256k1_scalar_order_get_num ( & order );
2015-01-25 15:47:04 +00:00
half_order = order ;
2014-11-27 19:12:13 +01:00
secp256k1_num_shift ( & half_order , 1 );
2014-11-28 01:23:55 +01:00
#endif
2014-10-29 00:35:38 -07:00
{
2015-01-25 15:47:04 +00:00
int i ;
2014-11-15 15:28:10 +00:00
/* Test that fetching groups of 4 bits from a scalar and recursing n(i)=16*n(i-1)+p(i) reconstructs it. */
2015-09-21 20:57:54 +02:00
secp256k1_scalar n ;
2014-11-25 15:55:21 +01:00
secp256k1_scalar_set_int ( & n , 0 );
2015-01-25 15:47:04 +00:00
for ( i = 0 ; i < 256 ; i += 4 ) {
2015-09-21 20:57:54 +02:00
secp256k1_scalar t ;
2015-01-25 15:47:04 +00:00
int j ;
2014-11-25 15:55:21 +01:00
secp256k1_scalar_set_int ( & t , secp256k1_scalar_get_bits ( & s , 256 - 4 - i , 4 ));
2015-01-25 15:47:04 +00:00
for ( j = 0 ; j < 4 ; j ++ ) {
2014-11-25 15:55:21 +01:00
secp256k1_scalar_add ( & n , & n , & n );
}
secp256k1_scalar_add ( & n , & n , & t );
2014-10-29 00:35:38 -07:00
}
2014-11-25 15:55:21 +01:00
CHECK ( secp256k1_scalar_eq ( & n , & s ));
}
{
/* Test that fetching groups of randomly-sized bits from a scalar and recursing n(i)=b*n(i-1)+p(i) reconstructs it. */
2015-09-21 20:57:54 +02:00
secp256k1_scalar n ;
2014-11-25 15:55:21 +01:00
int i = 0 ;
2015-01-25 15:47:04 +00:00
secp256k1_scalar_set_int ( & n , 0 );
2014-11-25 15:55:21 +01:00
while ( i < 256 ) {
2015-09-21 20:57:54 +02:00
secp256k1_scalar t ;
2015-01-25 15:47:04 +00:00
int j ;
2015-10-17 21:15:15 +02:00
int now = secp256k1_rand_int ( 15 ) + 1 ;
2014-11-25 15:55:21 +01:00
if ( now + i > 256 ) {
now = 256 - i ;
}
secp256k1_scalar_set_int ( & t , secp256k1_scalar_get_bits_var ( & s , 256 - now - i , now ));
2015-01-25 15:47:04 +00:00
for ( j = 0 ; j < now ; j ++ ) {
2014-11-25 15:55:21 +01:00
secp256k1_scalar_add ( & n , & n , & n );
}
secp256k1_scalar_add ( & n , & n , & t );
i += now ;
}
CHECK ( secp256k1_scalar_eq ( & n , & s ));
2014-10-29 00:35:38 -07:00
}
2014-11-28 01:23:55 +01:00
#ifndef USE_NUM_NONE
2014-10-29 00:35:38 -07:00
{
2014-11-15 15:28:10 +00:00
/* Test that adding the scalars together is equal to adding their numbers together modulo the order. */
2015-09-21 20:57:54 +02:00
secp256k1_num rnum ;
secp256k1_num r2num ;
secp256k1_scalar r ;
2014-10-29 00:35:38 -07:00
secp256k1_num_add ( & rnum , & snum , & s2num );
2014-11-27 19:12:13 +01:00
secp256k1_num_mod ( & rnum , & order );
2014-10-29 00:35:38 -07:00
secp256k1_scalar_add ( & r , & s , & s2 );
secp256k1_scalar_get_num ( & r2num , & r );
CHECK ( secp256k1_num_eq ( & rnum , & r2num ));
}
{
2014-11-15 15:28:10 +00:00
/* Test that multipying the scalars is equal to multiplying their numbers modulo the order. */
2015-09-21 20:57:54 +02:00
secp256k1_scalar r ;
secp256k1_num r2num ;
secp256k1_num rnum ;
2014-10-29 00:35:38 -07:00
secp256k1_num_mul ( & rnum , & snum , & s2num );
2014-11-27 19:12:13 +01:00
secp256k1_num_mod ( & rnum , & order );
2014-10-29 00:35:38 -07:00
secp256k1_scalar_mul ( & r , & s , & s2 );
secp256k1_scalar_get_num ( & r2num , & r );
CHECK ( secp256k1_num_eq ( & rnum , & r2num ));
2014-11-15 15:28:10 +00:00
/* The result can only be zero if at least one of the factors was zero. */
2014-10-29 00:35:38 -07:00
CHECK ( secp256k1_scalar_is_zero ( & r ) == ( secp256k1_scalar_is_zero ( & s ) || secp256k1_scalar_is_zero ( & s2 )));
2014-11-15 15:28:10 +00:00
/* The results can only be equal to one of the factors if that factor was zero, or the other factor was one. */
2014-10-29 00:35:38 -07:00
CHECK ( secp256k1_num_eq ( & rnum , & snum ) == ( secp256k1_scalar_is_zero ( & s ) || secp256k1_scalar_is_one ( & s2 )));
CHECK ( secp256k1_num_eq ( & rnum , & s2num ) == ( secp256k1_scalar_is_zero ( & s2 ) || secp256k1_scalar_is_one ( & s )));
}
{
2015-09-21 20:57:54 +02:00
secp256k1_scalar neg ;
secp256k1_num negnum ;
secp256k1_num negnum2 ;
2014-11-15 15:28:10 +00:00
/* Check that comparison with zero matches comparison with zero on the number. */
2014-10-29 00:35:38 -07:00
CHECK ( secp256k1_num_is_zero ( & snum ) == secp256k1_scalar_is_zero ( & s ));
2014-11-15 15:28:10 +00:00
/* Check that comparison with the half order is equal to testing for high scalar. */
2014-11-27 19:12:13 +01:00
CHECK ( secp256k1_scalar_is_high ( & s ) == ( secp256k1_num_cmp ( & snum , & half_order ) > 0 ));
2014-10-29 00:35:38 -07:00
secp256k1_scalar_negate ( & neg , & s );
2014-11-27 19:12:13 +01:00
secp256k1_num_sub ( & negnum , & order , & snum );
secp256k1_num_mod ( & negnum , & order );
2014-11-15 15:28:10 +00:00
/* Check that comparison with the half order is equal to testing for high scalar after negation. */
2014-11-27 19:12:13 +01:00
CHECK ( secp256k1_scalar_is_high ( & neg ) == ( secp256k1_num_cmp ( & negnum , & half_order ) > 0 ));
2014-11-15 15:28:10 +00:00
/* Negating should change the high property, unless the value was already zero. */
2014-10-29 00:35:38 -07:00
CHECK (( secp256k1_scalar_is_high ( & s ) == secp256k1_scalar_is_high ( & neg )) == secp256k1_scalar_is_zero ( & s ));
secp256k1_scalar_get_num ( & negnum2 , & neg );
2014-11-15 15:28:10 +00:00
/* Negating a scalar should be equal to (order - n) mod order on the number. */
2014-10-29 00:35:38 -07:00
CHECK ( secp256k1_num_eq ( & negnum , & negnum2 ));
secp256k1_scalar_add ( & neg , & neg , & s );
2014-11-15 15:28:10 +00:00
/* Adding a number to its negation should result in zero. */
2014-10-29 00:35:38 -07:00
CHECK ( secp256k1_scalar_is_zero ( & neg ));
secp256k1_scalar_negate ( & neg , & neg );
2014-11-15 15:28:10 +00:00
/* Negating zero should still result in zero. */
2014-10-29 00:35:38 -07:00
CHECK ( secp256k1_scalar_is_zero ( & neg ));
}
2014-12-01 17:11:59 +01:00
{
/* Test secp256k1_scalar_mul_shift_var. */
2015-09-21 20:57:54 +02:00
secp256k1_scalar r ;
secp256k1_num one ;
secp256k1_num rnum ;
secp256k1_num rnum2 ;
2015-01-25 15:47:04 +00:00
unsigned char cone [ 1 ] = { 0x01 };
2015-10-17 21:15:15 +02:00
unsigned int shift = 256 + secp256k1_rand_int ( 257 );
2014-12-01 17:11:59 +01:00
secp256k1_scalar_mul_shift_var ( & r , & s1 , & s2 , shift );
secp256k1_num_mul ( & rnum , & s1num , & s2num );
secp256k1_num_shift ( & rnum , shift - 1 );
secp256k1_num_set_bin ( & one , cone , 1 );
secp256k1_num_add ( & rnum , & rnum , & one );
secp256k1_num_shift ( & rnum , 1 );
secp256k1_scalar_get_num ( & rnum2 , & r );
CHECK ( secp256k1_num_eq ( & rnum , & rnum2 ));
}
2015-05-13 17:31:47 -05:00
{
/* test secp256k1_scalar_shr_int */
2015-09-21 20:57:54 +02:00
secp256k1_scalar r ;
2015-05-13 17:31:47 -05:00
int i ;
random_scalar_order_test ( & r );
for ( i = 0 ; i < 100 ; ++ i ) {
2015-09-24 08:42:37 +00:00
int low ;
2015-10-17 21:15:15 +02:00
int shift = 1 + secp256k1_rand_int ( 15 );
2015-05-13 17:31:47 -05:00
int expected = r . d [ 0 ] % ( 1 << shift );
low = secp256k1_scalar_shr_int ( & r , shift );
CHECK ( expected == low );
}
}
2014-11-28 01:23:55 +01:00
#endif
2014-10-29 00:35:38 -07:00
{
2014-11-15 15:28:10 +00:00
/* Test that scalar inverses are equal to the inverse of their number modulo the order. */
2014-10-29 00:35:38 -07:00
if ( ! secp256k1_scalar_is_zero ( & s )) {
2015-09-21 20:57:54 +02:00
secp256k1_scalar inv ;
2014-11-28 01:23:55 +01:00
#ifndef USE_NUM_NONE
2015-09-21 20:57:54 +02:00
secp256k1_num invnum ;
secp256k1_num invnum2 ;
2015-01-25 15:47:04 +00:00
#endif
secp256k1_scalar_inverse ( & inv , & s );
#ifndef USE_NUM_NONE
secp256k1_num_mod_inverse ( & invnum , & snum , & order );
2014-10-29 00:35:38 -07:00
secp256k1_scalar_get_num ( & invnum2 , & inv );
CHECK ( secp256k1_num_eq ( & invnum , & invnum2 ));
2014-11-28 01:23:55 +01:00
#endif
2014-10-29 00:35:38 -07:00
secp256k1_scalar_mul ( & inv , & inv , & s );
2014-11-15 15:28:10 +00:00
/* Multiplying a scalar with its inverse must result in one. */
2014-10-29 00:35:38 -07:00
CHECK ( secp256k1_scalar_is_one ( & inv ));
secp256k1_scalar_inverse ( & inv , & inv );
2014-11-15 15:28:10 +00:00
/* Inverting one must result in one. */
2014-10-29 00:35:38 -07:00
CHECK ( secp256k1_scalar_is_one ( & inv ));
}
}
{
2014-11-15 15:28:10 +00:00
/* Test commutativity of add. */
2015-09-21 20:57:54 +02:00
secp256k1_scalar r1 , r2 ;
2014-10-29 00:35:38 -07:00
secp256k1_scalar_add ( & r1 , & s1 , & s2 );
secp256k1_scalar_add ( & r2 , & s2 , & s1 );
CHECK ( secp256k1_scalar_eq ( & r1 , & r2 ));
}
2014-11-25 15:20:44 +01:00
{
2015-09-21 20:57:54 +02:00
secp256k1_scalar r1 , r2 ;
secp256k1_scalar b ;
2015-01-25 15:47:04 +00:00
int i ;
2014-11-25 15:20:44 +01:00
/* Test add_bit. */
2015-10-17 21:15:15 +02:00
int bit = secp256k1_rand_bits ( 8 );
2014-11-25 15:55:21 +01:00
secp256k1_scalar_set_int ( & b , 1 );
2014-11-25 15:20:44 +01:00
CHECK ( secp256k1_scalar_is_one ( & b ));
2015-01-25 15:47:04 +00:00
for ( i = 0 ; i < bit ; i ++ ) {
2014-11-25 15:20:44 +01:00
secp256k1_scalar_add ( & b , & b , & b );
}
2015-01-25 15:47:04 +00:00
r1 = s1 ;
r2 = s1 ;
2014-12-03 18:30:17 +01:00
if ( ! secp256k1_scalar_add ( & r1 , & r1 , & b )) {
2014-11-25 15:20:44 +01:00
/* No overflow happened. */
2015-05-22 11:51:51 -05:00
secp256k1_scalar_cadd_bit ( & r2 , bit , 1 );
CHECK ( secp256k1_scalar_eq ( & r1 , & r2 ));
/* cadd is a noop when flag is zero */
secp256k1_scalar_cadd_bit ( & r2 , bit , 0 );
2014-11-25 15:20:44 +01:00
CHECK ( secp256k1_scalar_eq ( & r1 , & r2 ));
}
}
2014-10-29 00:35:38 -07:00
{
2014-11-15 15:28:10 +00:00
/* Test commutativity of mul. */
2015-09-21 20:57:54 +02:00
secp256k1_scalar r1 , r2 ;
2014-10-29 00:35:38 -07:00
secp256k1_scalar_mul ( & r1 , & s1 , & s2 );
secp256k1_scalar_mul ( & r2 , & s2 , & s1 );
CHECK ( secp256k1_scalar_eq ( & r1 , & r2 ));
}
{
2014-11-15 15:28:10 +00:00
/* Test associativity of add. */
2015-09-21 20:57:54 +02:00
secp256k1_scalar r1 , r2 ;
2014-10-29 00:35:38 -07:00
secp256k1_scalar_add ( & r1 , & s1 , & s2 );
secp256k1_scalar_add ( & r1 , & r1 , & s );
secp256k1_scalar_add ( & r2 , & s2 , & s );
secp256k1_scalar_add ( & r2 , & s1 , & r2 );
CHECK ( secp256k1_scalar_eq ( & r1 , & r2 ));
}
{
2014-11-15 15:28:10 +00:00
/* Test associativity of mul. */
2015-09-21 20:57:54 +02:00
secp256k1_scalar r1 , r2 ;
2014-10-29 00:35:38 -07:00
secp256k1_scalar_mul ( & r1 , & s1 , & s2 );
secp256k1_scalar_mul ( & r1 , & r1 , & s );
secp256k1_scalar_mul ( & r2 , & s2 , & s );
secp256k1_scalar_mul ( & r2 , & s1 , & r2 );
CHECK ( secp256k1_scalar_eq ( & r1 , & r2 ));
}
{
2014-11-15 15:28:10 +00:00
/* Test distributitivity of mul over add. */
2015-09-21 20:57:54 +02:00
secp256k1_scalar r1 , r2 , t ;
2014-10-29 00:35:38 -07:00
secp256k1_scalar_add ( & r1 , & s1 , & s2 );
secp256k1_scalar_mul ( & r1 , & r1 , & s );
secp256k1_scalar_mul ( & r2 , & s1 , & s );
secp256k1_scalar_mul ( & t , & s2 , & s );
secp256k1_scalar_add ( & r2 , & r2 , & t );
CHECK ( secp256k1_scalar_eq ( & r1 , & r2 ));
}
2014-10-29 00:35:49 -07:00
{
2014-11-15 15:28:10 +00:00
/* Test square. */
2015-09-21 20:57:54 +02:00
secp256k1_scalar r1 , r2 ;
2014-10-29 00:35:49 -07:00
secp256k1_scalar_sqr ( & r1 , & s1 );
secp256k1_scalar_mul ( & r2 , & s1 , & s1 );
CHECK ( secp256k1_scalar_eq ( & r1 , & r2 ));
}
2014-12-01 17:11:59 +01:00
2014-12-08 00:48:53 -08:00
{
/* Test multiplicative identity. */
2015-09-21 20:57:54 +02:00
secp256k1_scalar r1 , v1 ;
2014-12-08 00:48:53 -08:00
secp256k1_scalar_set_int ( & v1 , 1 );
secp256k1_scalar_mul ( & r1 , & s1 , & v1 );
CHECK ( secp256k1_scalar_eq ( & r1 , & s1 ));
}
{
/* Test additive identity. */
2015-09-21 20:57:54 +02:00
secp256k1_scalar r1 , v0 ;
2014-12-08 00:48:53 -08:00
secp256k1_scalar_set_int ( & v0 , 0 );
secp256k1_scalar_add ( & r1 , & s1 , & v0 );
CHECK ( secp256k1_scalar_eq ( & r1 , & s1 ));
}
{
/* Test zero product property. */
2015-09-21 20:57:54 +02:00
secp256k1_scalar r1 , v0 ;
2014-12-08 00:48:53 -08:00
secp256k1_scalar_set_int ( & v0 , 0 );
secp256k1_scalar_mul ( & r1 , & s1 , & v0 );
CHECK ( secp256k1_scalar_eq ( & r1 , & v0 ));
}
2014-10-29 00:35:38 -07:00
}
void run_scalar_tests ( void ) {
2015-01-25 15:47:04 +00:00
int i ;
for ( i = 0 ; i < 128 * count ; i ++ ) {
2014-10-29 00:35:38 -07:00
scalar_test ();
}
2014-11-27 19:12:13 +01:00
{
2014-12-04 01:04:00 -08:00
/* (-1)+1 should be zero. */
2015-09-21 20:57:54 +02:00
secp256k1_scalar s , o ;
2014-11-27 19:12:13 +01:00
secp256k1_scalar_set_int ( & s , 1 );
2014-12-08 00:48:53 -08:00
CHECK ( secp256k1_scalar_is_one ( & s ));
2014-11-27 19:12:13 +01:00
secp256k1_scalar_negate ( & o , & s );
secp256k1_scalar_add ( & o , & o , & s );
CHECK ( secp256k1_scalar_is_zero ( & o ));
2014-12-08 00:48:53 -08:00
secp256k1_scalar_negate ( & o , & o );
CHECK ( secp256k1_scalar_is_zero ( & o ));
2014-11-27 19:12:13 +01:00
}
2014-11-28 01:23:55 +01:00
#ifndef USE_NUM_NONE
2014-11-27 19:12:13 +01:00
{
2014-12-04 01:04:00 -08:00
/* A scalar with value of the curve order should be 0. */
2015-09-21 20:57:54 +02:00
secp256k1_num order ;
secp256k1_scalar zero ;
2015-01-25 15:47:04 +00:00
unsigned char bin [ 32 ];
2014-11-27 19:12:13 +01:00
int overflow = 0 ;
2015-01-25 15:47:04 +00:00
secp256k1_scalar_order_get_num ( & order );
secp256k1_num_get_bin ( bin , 32 , & order );
2014-11-27 19:12:13 +01:00
secp256k1_scalar_set_b32 ( & zero , bin , & overflow );
CHECK ( overflow == 1 );
CHECK ( secp256k1_scalar_is_zero ( & zero ));
}
2014-11-28 01:23:55 +01:00
#endif
2014-10-29 00:35:38 -07:00
}
2014-05-21 10:22:14 +07:00
/***** FIELD TESTS *****/
2015-09-21 20:57:54 +02:00
void random_fe ( secp256k1_fe * x ) {
2014-05-21 10:22:14 +07:00
unsigned char bin [ 32 ];
2014-11-24 12:38:05 +01:00
do {
secp256k1_rand256 ( bin );
if ( secp256k1_fe_set_b32 ( x , bin )) {
return ;
}
} while ( 1 );
2014-05-21 10:22:14 +07:00
}
2015-09-21 20:57:54 +02:00
void random_fe_non_zero ( secp256k1_fe * nz ) {
2014-06-03 17:50:27 +07:00
int tries = 10 ;
2014-05-21 10:22:14 +07:00
while ( -- tries >= 0 ) {
2014-06-03 17:50:27 +07:00
random_fe ( nz );
secp256k1_fe_normalize ( nz );
2015-03-27 23:14:17 +00:00
if ( ! secp256k1_fe_is_zero ( nz )) {
2014-05-21 10:22:14 +07:00
break ;
2015-03-27 23:14:17 +00:00
}
2014-05-21 10:22:14 +07:00
}
2014-11-15 15:28:10 +00:00
/* Infinitesimal probability of spurious failure here */
2014-06-16 01:30:17 +02:00
CHECK ( tries >= 0 );
2014-05-21 10:22:14 +07:00
}
2015-09-21 20:57:54 +02:00
void random_fe_non_square ( secp256k1_fe * ns ) {
secp256k1_fe r ;
2015-01-25 15:47:04 +00:00
random_fe_non_zero ( ns );
2014-12-05 03:37:42 +01:00
if ( secp256k1_fe_sqrt_var ( & r , ns )) {
2014-06-03 17:50:27 +07:00
secp256k1_fe_negate ( ns , ns , 1 );
}
}
2015-09-21 20:57:54 +02:00
int check_fe_equal ( const secp256k1_fe * a , const secp256k1_fe * b ) {
secp256k1_fe an = * a ;
secp256k1_fe bn = * b ;
2015-01-25 15:47:04 +00:00
secp256k1_fe_normalize_weak ( & an );
secp256k1_fe_normalize_var ( & bn );
2014-12-10 14:52:18 +01:00
return secp256k1_fe_equal_var ( & an , & bn );
2014-07-02 16:01:26 +07:00
}
2015-09-21 20:57:54 +02:00
int check_fe_inverse ( const secp256k1_fe * a , const secp256k1_fe * ai ) {
secp256k1_fe x ;
secp256k1_fe one = SECP256K1_FE_CONST ( 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 );
2015-01-25 15:47:04 +00:00
secp256k1_fe_mul ( & x , a , ai );
2014-07-02 16:01:26 +07:00
return check_fe_equal ( & x , & one );
}
2015-01-24 23:04:48 -04:00
void run_field_convert ( void ) {
static const unsigned char b32 [ 32 ] = {
0x00 , 0x01 , 0x02 , 0x03 , 0x04 , 0x05 , 0x06 , 0x07 ,
0x11 , 0x12 , 0x13 , 0x14 , 0x15 , 0x16 , 0x17 , 0x18 ,
0x22 , 0x23 , 0x24 , 0x25 , 0x26 , 0x27 , 0x28 , 0x29 ,
0x33 , 0x34 , 0x35 , 0x36 , 0x37 , 0x38 , 0x39 , 0x40
};
2015-09-21 20:57:54 +02:00
static const secp256k1_fe_storage fes = SECP256K1_FE_STORAGE_CONST (
2015-01-24 23:04:48 -04:00
0x00010203UL , 0x04050607UL , 0x11121314UL , 0x15161718UL ,
0x22232425UL , 0x26272829UL , 0x33343536UL , 0x37383940UL
);
2015-09-21 20:57:54 +02:00
static const secp256k1_fe fe = SECP256K1_FE_CONST (
2015-01-24 23:04:48 -04:00
0x00010203UL , 0x04050607UL , 0x11121314UL , 0x15161718UL ,
0x22232425UL , 0x26272829UL , 0x33343536UL , 0x37383940UL
);
2015-09-21 20:57:54 +02:00
secp256k1_fe fe2 ;
2015-01-24 23:04:48 -04:00
unsigned char b322 [ 32 ];
2015-09-21 20:57:54 +02:00
secp256k1_fe_storage fes2 ;
2015-01-24 23:04:48 -04:00
/* Check conversions to fe. */
CHECK ( secp256k1_fe_set_b32 ( & fe2 , b32 ));
CHECK ( secp256k1_fe_equal_var ( & fe , & fe2 ));
secp256k1_fe_from_storage ( & fe2 , & fes );
CHECK ( secp256k1_fe_equal_var ( & fe , & fe2 ));
/* Check conversion from fe. */
secp256k1_fe_get_b32 ( b322 , & fe );
CHECK ( memcmp ( b322 , b32 , 32 ) == 0 );
secp256k1_fe_to_storage ( & fes2 , & fe );
CHECK ( memcmp ( & fes2 , & fes , sizeof ( fes )) == 0 );
}
2015-09-21 20:57:54 +02:00
int fe_memcmp ( const secp256k1_fe * a , const secp256k1_fe * b ) {
secp256k1_fe t = * b ;
2015-07-04 13:50:15 +09:30
#ifdef VERIFY
t . magnitude = a -> magnitude ;
t . normalized = a -> normalized ;
#endif
2015-09-21 20:57:54 +02:00
return memcmp ( a , & t , sizeof ( secp256k1_fe ));
2015-07-04 13:50:15 +09:30
}
2014-12-08 00:48:53 -08:00
void run_field_misc ( void ) {
2015-09-21 20:57:54 +02:00
secp256k1_fe x ;
secp256k1_fe y ;
secp256k1_fe z ;
secp256k1_fe q ;
secp256k1_fe fe5 = SECP256K1_FE_CONST ( 0 , 0 , 0 , 0 , 0 , 0 , 0 , 5 );
2015-07-06 12:41:30 +09:30
int i , j ;
2015-01-25 15:47:04 +00:00
for ( i = 0 ; i < 5 * count ; i ++ ) {
2015-09-21 20:57:54 +02:00
secp256k1_fe_storage xs , ys , zs ;
2014-12-08 00:48:53 -08:00
random_fe ( & x );
random_fe_non_zero ( & y );
/* Test the fe equality and comparison operations. */
CHECK ( secp256k1_fe_cmp_var ( & x , & x ) == 0 );
2014-12-10 14:52:18 +01:00
CHECK ( secp256k1_fe_equal_var ( & x , & x ));
2014-12-08 00:48:53 -08:00
z = x ;
secp256k1_fe_add ( & z , & y );
2015-04-22 19:07:31 +00:00
/* Test fe conditional move; z is not normalized here. */
q = x ;
secp256k1_fe_cmov ( & x , & z , 0 );
2015-07-06 12:41:30 +09:30
VERIFY_CHECK ( ! x . normalized && x . magnitude == z . magnitude );
2015-04-22 19:07:31 +00:00
secp256k1_fe_cmov ( & x , & x , 1 );
2015-07-04 13:50:15 +09:30
CHECK ( fe_memcmp ( & x , & z ) != 0 );
CHECK ( fe_memcmp ( & x , & q ) == 0 );
2015-04-22 19:07:31 +00:00
secp256k1_fe_cmov ( & q , & z , 1 );
2015-07-06 12:41:30 +09:30
VERIFY_CHECK ( ! q . normalized && q . magnitude == z . magnitude );
2015-07-04 13:50:15 +09:30
CHECK ( fe_memcmp ( & q , & z ) == 0 );
secp256k1_fe_normalize_var ( & x );
secp256k1_fe_normalize_var ( & z );
2015-04-22 19:07:31 +00:00
CHECK ( ! secp256k1_fe_equal_var ( & x , & z ));
2015-07-06 12:41:30 +09:30
secp256k1_fe_normalize_var ( & q );
secp256k1_fe_cmov ( & q , & z , ( i & 1 ));
VERIFY_CHECK ( q . normalized && q . magnitude == 1 );
for ( j = 0 ; j < 6 ; j ++ ) {
secp256k1_fe_negate ( & z , & z , j + 1 );
secp256k1_fe_normalize_var ( & q );
secp256k1_fe_cmov ( & q , & z , ( j & 1 ));
VERIFY_CHECK ( ! q . normalized && q . magnitude == ( j + 2 ));
}
secp256k1_fe_normalize_var ( & z );
/* Test storage conversion and conditional moves. */
2015-01-25 00:56:22 -04:00
secp256k1_fe_to_storage ( & xs , & x );
secp256k1_fe_to_storage ( & ys , & y );
secp256k1_fe_to_storage ( & zs , & z );
secp256k1_fe_storage_cmov ( & zs , & xs , 0 );
2015-04-22 19:07:31 +00:00
secp256k1_fe_storage_cmov ( & zs , & zs , 1 );
2015-01-25 00:56:22 -04:00
CHECK ( memcmp ( & xs , & zs , sizeof ( xs )) != 0 );
secp256k1_fe_storage_cmov ( & ys , & xs , 1 );
CHECK ( memcmp ( & xs , & ys , sizeof ( xs )) == 0 );
secp256k1_fe_from_storage ( & x , & xs );
secp256k1_fe_from_storage ( & y , & ys );
secp256k1_fe_from_storage ( & z , & zs );
2014-12-08 00:48:53 -08:00
/* Test that mul_int, mul, and add agree. */
secp256k1_fe_add ( & y , & x );
secp256k1_fe_add ( & y , & x );
z = x ;
secp256k1_fe_mul_int ( & z , 3 );
CHECK ( check_fe_equal ( & y , & z ));
secp256k1_fe_add ( & y , & x );
secp256k1_fe_add ( & z , & x );
CHECK ( check_fe_equal ( & z , & y ));
z = x ;
secp256k1_fe_mul_int ( & z , 5 );
secp256k1_fe_mul ( & q , & x , & fe5 );
CHECK ( check_fe_equal ( & z , & q ));
secp256k1_fe_negate ( & x , & x , 1 );
secp256k1_fe_add ( & z , & x );
secp256k1_fe_add ( & q , & x );
CHECK ( check_fe_equal ( & y , & z ));
CHECK ( check_fe_equal ( & q , & y ));
}
}
2014-11-12 13:24:12 -08:00
void run_field_inv ( void ) {
2015-09-21 20:57:54 +02:00
secp256k1_fe x , xi , xii ;
2015-01-25 15:47:04 +00:00
int i ;
for ( i = 0 ; i < 10 * count ; i ++ ) {
2014-07-02 16:01:26 +07:00
random_fe_non_zero ( & x );
secp256k1_fe_inv ( & xi , & x );
CHECK ( check_fe_inverse ( & x , & xi ));
secp256k1_fe_inv ( & xii , & xi );
CHECK ( check_fe_equal ( & x , & xii ));
}
}
2014-11-12 13:24:12 -08:00
void run_field_inv_var ( void ) {
2015-09-21 20:57:54 +02:00
secp256k1_fe x , xi , xii ;
2015-01-25 15:47:04 +00:00
int i ;
for ( i = 0 ; i < 10 * count ; i ++ ) {
2014-07-02 16:01:26 +07:00
random_fe_non_zero ( & x );
secp256k1_fe_inv_var ( & xi , & x );
CHECK ( check_fe_inverse ( & x , & xi ));
secp256k1_fe_inv_var ( & xii , & xi );
CHECK ( check_fe_equal ( & x , & xii ));
}
}
2014-11-12 13:24:12 -08:00
void run_field_inv_all_var ( void ) {
2015-09-21 20:57:54 +02:00
secp256k1_fe x [ 16 ], xi [ 16 ], xii [ 16 ];
2015-01-25 15:47:04 +00:00
int i ;
2014-11-15 15:28:10 +00:00
/* Check it's safe to call for 0 elements */
2014-07-02 16:01:26 +07:00
secp256k1_fe_inv_all_var ( 0 , xi , x );
2015-01-25 15:47:04 +00:00
for ( i = 0 ; i < count ; i ++ ) {
size_t j ;
2015-10-17 21:15:15 +02:00
size_t len = secp256k1_rand_int ( 15 ) + 1 ;
2015-03-27 23:14:17 +00:00
for ( j = 0 ; j < len ; j ++ ) {
2014-07-02 16:01:26 +07:00
random_fe_non_zero ( & x [ j ]);
2015-03-27 23:14:17 +00:00
}
2014-07-02 16:01:26 +07:00
secp256k1_fe_inv_all_var ( len , xi , x );
2015-03-27 23:14:17 +00:00
for ( j = 0 ; j < len ; j ++ ) {
2014-07-02 16:01:26 +07:00
CHECK ( check_fe_inverse ( & x [ j ], & xi [ j ]));
2015-03-27 23:14:17 +00:00
}
2014-07-02 16:01:26 +07:00
secp256k1_fe_inv_all_var ( len , xii , xi );
2015-03-27 23:14:17 +00:00
for ( j = 0 ; j < len ; j ++ ) {
2014-07-02 16:01:26 +07:00
CHECK ( check_fe_equal ( & x [ j ], & xii [ j ]));
2015-03-27 23:14:17 +00:00
}
2014-07-02 16:01:26 +07:00
}
}
2014-11-12 13:24:12 -08:00
void run_sqr ( void ) {
2015-09-21 20:57:54 +02:00
secp256k1_fe x , s ;
2014-06-22 15:03:29 +07:00
{
2015-01-25 15:47:04 +00:00
int i ;
2014-06-22 15:03:29 +07:00
secp256k1_fe_set_int ( & x , 1 );
secp256k1_fe_negate ( & x , & x , 1 );
2015-01-25 15:47:04 +00:00
for ( i = 1 ; i <= 512 ; ++ i ) {
2014-06-22 15:03:29 +07:00
secp256k1_fe_mul_int ( & x , 2 );
secp256k1_fe_normalize ( & x );
secp256k1_fe_sqr ( & s , & x );
}
}
}
2015-09-21 20:57:54 +02:00
void test_sqrt ( const secp256k1_fe * a , const secp256k1_fe * k ) {
secp256k1_fe r1 , r2 ;
2014-12-05 03:37:42 +01:00
int v = secp256k1_fe_sqrt_var ( & r1 , a );
2014-06-16 01:30:17 +02:00
CHECK (( v == 0 ) == ( k == NULL ));
2014-05-21 10:22:14 +07:00
if ( k != NULL ) {
2014-11-15 15:28:10 +00:00
/* Check that the returned root is +/- the given known answer */
2014-05-21 10:22:14 +07:00
secp256k1_fe_negate ( & r2 , & r1 , 1 );
secp256k1_fe_add ( & r1 , k ); secp256k1_fe_add ( & r2 , k );
secp256k1_fe_normalize ( & r1 ); secp256k1_fe_normalize ( & r2 );
2014-06-16 01:30:17 +02:00
CHECK ( secp256k1_fe_is_zero ( & r1 ) || secp256k1_fe_is_zero ( & r2 ));
2014-05-21 10:22:14 +07:00
}
}
2014-11-12 13:24:12 -08:00
void run_sqrt ( void ) {
2015-09-21 20:57:54 +02:00
secp256k1_fe ns , x , s , t ;
2015-01-25 15:47:04 +00:00
int i ;
2014-06-03 17:50:27 +07:00
2014-11-15 15:28:10 +00:00
/* Check sqrt(0) is 0 */
2014-06-03 17:50:27 +07:00
secp256k1_fe_set_int ( & x , 0 );
secp256k1_fe_sqr ( & s , & x );
test_sqrt ( & s , & x );
2014-11-15 15:28:10 +00:00
/* Check sqrt of small squares (and their negatives) */
2015-01-25 15:47:04 +00:00
for ( i = 1 ; i <= 100 ; i ++ ) {
2014-06-03 17:50:27 +07:00
secp256k1_fe_set_int ( & x , i );
2014-05-21 10:22:14 +07:00
secp256k1_fe_sqr ( & s , & x );
test_sqrt ( & s , & x );
2014-06-03 17:50:27 +07:00
secp256k1_fe_negate ( & t , & s , 1 );
2014-05-21 10:22:14 +07:00
test_sqrt ( & t , NULL );
}
2014-06-03 17:50:27 +07:00
2014-11-15 15:28:10 +00:00
/* Consistency checks for large random values */
2015-01-25 15:47:04 +00:00
for ( i = 0 ; i < 10 ; i ++ ) {
int j ;
2014-06-03 17:50:27 +07:00
random_fe_non_square ( & ns );
2015-01-25 15:47:04 +00:00
for ( j = 0 ; j < count ; j ++ ) {
2014-06-03 17:50:27 +07:00
random_fe ( & x );
secp256k1_fe_sqr ( & s , & x );
test_sqrt ( & s , & x );
secp256k1_fe_negate ( & t , & s , 1 );
test_sqrt ( & t , NULL );
secp256k1_fe_mul ( & t , & s , & ns );
test_sqrt ( & t , NULL );
}
}
2014-05-21 10:22:14 +07:00
}
2014-11-11 10:32:50 -08:00
/***** GROUP TESTS *****/
2015-09-21 20:57:54 +02:00
void ge_equals_ge ( const secp256k1_ge * a , const secp256k1_ge * b ) {
2014-12-29 15:38:17 +01:00
CHECK ( a -> infinity == b -> infinity );
2015-03-27 23:14:17 +00:00
if ( a -> infinity ) {
2014-12-29 15:38:17 +01:00
return ;
2015-03-27 23:14:17 +00:00
}
2014-12-29 15:38:17 +01:00
CHECK ( secp256k1_fe_equal_var ( & a -> x , & b -> x ));
2015-05-13 21:16:13 -05:00
CHECK ( secp256k1_fe_equal_var ( & a -> y , & b -> y ));
2014-11-11 10:32:50 -08:00
}
2015-04-15 21:35:50 +00:00
/* This compares jacobian points including their Z, not just their geometric meaning. */
2015-09-21 20:57:54 +02:00
int gej_xyz_equals_gej ( const secp256k1_gej * a , const secp256k1_gej * b ) {
secp256k1_gej a2 ;
secp256k1_gej b2 ;
2015-04-15 21:35:50 +00:00
int ret = 1 ;
ret &= a -> infinity == b -> infinity ;
if ( ret && ! a -> infinity ) {
a2 = * a ;
b2 = * b ;
secp256k1_fe_normalize ( & a2 . x );
secp256k1_fe_normalize ( & a2 . y );
secp256k1_fe_normalize ( & a2 . z );
secp256k1_fe_normalize ( & b2 . x );
secp256k1_fe_normalize ( & b2 . y );
secp256k1_fe_normalize ( & b2 . z );
ret &= secp256k1_fe_cmp_var ( & a2 . x , & b2 . x ) == 0 ;
ret &= secp256k1_fe_cmp_var ( & a2 . y , & b2 . y ) == 0 ;
ret &= secp256k1_fe_cmp_var ( & a2 . z , & b2 . z ) == 0 ;
}
return ret ;
}
2015-09-21 20:57:54 +02:00
void ge_equals_gej ( const secp256k1_ge * a , const secp256k1_gej * b ) {
secp256k1_fe z2s ;
secp256k1_fe u1 , u2 , s1 , s2 ;
2014-12-29 15:38:17 +01:00
CHECK ( a -> infinity == b -> infinity );
2015-03-27 23:14:17 +00:00
if ( a -> infinity ) {
2014-12-29 15:38:17 +01:00
return ;
2015-03-27 23:14:17 +00:00
}
2014-12-29 15:38:17 +01:00
/* Check a.x * b.z^2 == b.x && a.y * b.z^3 == b.y, to avoid inverses. */
secp256k1_fe_sqr ( & z2s , & b -> z );
secp256k1_fe_mul ( & u1 , & a -> x , & z2s );
u2 = b -> x ; secp256k1_fe_normalize_weak ( & u2 );
secp256k1_fe_mul ( & s1 , & a -> y , & z2s ); secp256k1_fe_mul ( & s1 , & s1 , & b -> z );
s2 = b -> y ; secp256k1_fe_normalize_weak ( & s2 );
CHECK ( secp256k1_fe_equal_var ( & u1 , & u2 ));
CHECK ( secp256k1_fe_equal_var ( & s1 , & s2 ));
2014-11-11 10:32:50 -08:00
}
2014-11-12 13:24:12 -08:00
void test_ge ( void ) {
2015-01-25 15:47:04 +00:00
int i , i1 ;
2015-06-23 12:33:49 +02:00
#ifdef USE_ENDOMORPHISM
int runs = 6 ;
#else
2014-12-29 15:38:17 +01:00
int runs = 4 ;
2015-06-23 12:33:49 +02:00
#endif
2014-12-29 15:38:17 +01:00
/* Points: (infinity, p1, p1, -p1, -p1, p2, p2, -p2, -p2, p3, p3, -p3, -p3, p4, p4, -p4, -p4).
* The second in each pair of identical points uses a random Z coordinate in the Jacobian form.
* All magnitudes are randomized.
* All 17*17 combinations of points are added to eachother, using all applicable methods.
2015-06-23 12:33:49 +02:00
*
* When the endomorphism code is compiled in, p5 = lambda*p1 and p6 = lambda^2*p1 are added as well.
2014-12-29 15:38:17 +01:00
*/
2015-09-21 20:57:54 +02:00
secp256k1_ge * ge = ( secp256k1_ge * ) malloc ( sizeof ( secp256k1_ge ) * ( 1 + 4 * runs ));
secp256k1_gej * gej = ( secp256k1_gej * ) malloc ( sizeof ( secp256k1_gej ) * ( 1 + 4 * runs ));
secp256k1_fe * zinv = ( secp256k1_fe * ) malloc ( sizeof ( secp256k1_fe ) * ( 1 + 4 * runs ));
secp256k1_fe zf ;
secp256k1_fe zfi2 , zfi3 ;
2014-11-04 19:16:55 +07:00
2014-12-29 15:38:17 +01:00
secp256k1_gej_set_infinity ( & gej [ 0 ]);
secp256k1_ge_clear ( & ge [ 0 ]);
secp256k1_ge_set_gej_var ( & ge [ 0 ], & gej [ 0 ]);
2015-01-25 15:47:04 +00:00
for ( i = 0 ; i < runs ; i ++ ) {
int j ;
2015-09-21 20:57:54 +02:00
secp256k1_ge g ;
2014-12-29 15:38:17 +01:00
random_group_element_test ( & g );
2015-06-23 12:33:49 +02:00
#ifdef USE_ENDOMORPHISM
if ( i >= runs - 2 ) {
secp256k1_ge_mul_lambda ( & g , & ge [ 1 ]);
}
if ( i >= runs - 1 ) {
secp256k1_ge_mul_lambda ( & g , & g );
}
#endif
2014-12-29 15:38:17 +01:00
ge [ 1 + 4 * i ] = g ;
ge [ 2 + 4 * i ] = g ;
secp256k1_ge_neg ( & ge [ 3 + 4 * i ], & g );
secp256k1_ge_neg ( & ge [ 4 + 4 * i ], & g );
secp256k1_gej_set_ge ( & gej [ 1 + 4 * i ], & ge [ 1 + 4 * i ]);
random_group_element_jacobian_test ( & gej [ 2 + 4 * i ], & ge [ 2 + 4 * i ]);
secp256k1_gej_set_ge ( & gej [ 3 + 4 * i ], & ge [ 3 + 4 * i ]);
random_group_element_jacobian_test ( & gej [ 4 + 4 * i ], & ge [ 4 + 4 * i ]);
2015-01-25 15:47:04 +00:00
for ( j = 0 ; j < 4 ; j ++ ) {
2014-12-29 15:38:17 +01:00
random_field_element_magnitude ( & ge [ 1 + j + 4 * i ]. x );
random_field_element_magnitude ( & ge [ 1 + j + 4 * i ]. y );
random_field_element_magnitude ( & gej [ 1 + j + 4 * i ]. x );
random_field_element_magnitude ( & gej [ 1 + j + 4 * i ]. y );
random_field_element_magnitude ( & gej [ 1 + j + 4 * i ]. z );
}
}
2014-11-04 19:16:55 +07:00
/* Compute z inverses. */
{
2015-09-21 20:57:54 +02:00
secp256k1_fe * zs = malloc ( sizeof ( secp256k1_fe ) * ( 1 + 4 * runs ));
2014-11-04 19:16:55 +07:00
for ( i = 0 ; i < 4 * runs + 1 ; i ++ ) {
if ( i == 0 ) {
/* The point at infinity does not have a meaningful z inverse. Any should do. */
do {
random_field_element_test ( & zs [ i ]);
} while ( secp256k1_fe_is_zero ( & zs [ i ]));
} else {
zs [ i ] = gej [ i ]. z ;
}
}
secp256k1_fe_inv_all_var ( 4 * runs + 1 , zinv , zs );
free ( zs );
}
/* Generate random zf, and zfi2 = 1/zf^2, zfi3 = 1/zf^3 */
do {
random_field_element_test ( & zf );
} while ( secp256k1_fe_is_zero ( & zf ));
random_field_element_magnitude ( & zf );
secp256k1_fe_inv_var ( & zfi3 , & zf );
secp256k1_fe_sqr ( & zfi2 , & zfi3 );
secp256k1_fe_mul ( & zfi3 , & zfi3 , & zfi2 );
2015-01-25 15:47:04 +00:00
for ( i1 = 0 ; i1 < 1 + 4 * runs ; i1 ++ ) {
int i2 ;
for ( i2 = 0 ; i2 < 1 + 4 * runs ; i2 ++ ) {
2014-12-29 15:38:17 +01:00
/* Compute reference result using gej + gej (var). */
2015-09-21 20:57:54 +02:00
secp256k1_gej refj , resj ;
secp256k1_ge ref ;
secp256k1_fe zr ;
2014-11-04 19:16:55 +07:00
secp256k1_gej_add_var ( & refj , & gej [ i1 ], & gej [ i2 ], secp256k1_gej_is_infinity ( & gej [ i1 ]) ? NULL : & zr );
/* Check Z ratio. */
if ( ! secp256k1_gej_is_infinity ( & gej [ i1 ]) && ! secp256k1_gej_is_infinity ( & refj )) {
2015-09-21 20:57:54 +02:00
secp256k1_fe zrz ; secp256k1_fe_mul ( & zrz , & zr , & gej [ i1 ]. z );
2014-11-04 19:16:55 +07:00
CHECK ( secp256k1_fe_equal_var ( & zrz , & refj . z ));
}
2014-12-29 15:38:17 +01:00
secp256k1_ge_set_gej_var ( & ref , & refj );
2015-02-09 16:34:24 +07:00
/* Test gej + ge with Z ratio result (var). */
secp256k1_gej_add_ge_var ( & resj , & gej [ i1 ], & ge [ i2 ], secp256k1_gej_is_infinity ( & gej [ i1 ]) ? NULL : & zr );
2014-12-29 15:38:17 +01:00
ge_equals_gej ( & ref , & resj );
2015-02-09 16:34:24 +07:00
if ( ! secp256k1_gej_is_infinity ( & gej [ i1 ]) && ! secp256k1_gej_is_infinity ( & resj )) {
2015-09-21 20:57:54 +02:00
secp256k1_fe zrz ; secp256k1_fe_mul ( & zrz , & zr , & gej [ i1 ]. z );
2015-02-09 16:34:24 +07:00
CHECK ( secp256k1_fe_equal_var ( & zrz , & resj . z ));
}
2014-12-29 15:38:17 +01:00
2014-11-04 19:16:55 +07:00
/* Test gej + ge (var, with additional Z factor). */
{
2015-09-21 20:57:54 +02:00
secp256k1_ge ge2_zfi = ge [ i2 ]; /* the second term with x and y rescaled for z = 1/zf */
2014-11-04 19:16:55 +07:00
secp256k1_fe_mul ( & ge2_zfi . x , & ge2_zfi . x , & zfi2 );
secp256k1_fe_mul ( & ge2_zfi . y , & ge2_zfi . y , & zfi3 );
random_field_element_magnitude ( & ge2_zfi . x );
random_field_element_magnitude ( & ge2_zfi . y );
secp256k1_gej_add_zinv_var ( & resj , & gej [ i1 ], & ge2_zfi , & zf );
ge_equals_gej ( & ref , & resj );
}
2014-12-29 15:38:17 +01:00
/* Test gej + ge (const). */
if ( i2 != 0 ) {
/* secp256k1_gej_add_ge does not support its second argument being infinity. */
secp256k1_gej_add_ge ( & resj , & gej [ i1 ], & ge [ i2 ]);
ge_equals_gej ( & ref , & resj );
}
/* Test doubling (var). */
if (( i1 == 0 && i2 == 0 ) || (( i1 + 3 ) / 4 == ( i2 + 3 ) / 4 && (( i1 + 3 ) % 4 ) / 2 == (( i2 + 3 ) % 4 ) / 2 )) {
2015-09-21 20:57:54 +02:00
secp256k1_fe zr2 ;
2014-11-04 19:16:55 +07:00
/* Normal doubling with Z ratio result. */
secp256k1_gej_double_var ( & resj , & gej [ i1 ], & zr2 );
2014-12-29 15:38:17 +01:00
ge_equals_gej ( & ref , & resj );
2014-11-04 19:16:55 +07:00
/* Check Z ratio. */
secp256k1_fe_mul ( & zr2 , & zr2 , & gej [ i1 ]. z );
CHECK ( secp256k1_fe_equal_var ( & zr2 , & resj . z ));
/* Normal doubling. */
secp256k1_gej_double_var ( & resj , & gej [ i2 ], NULL );
2014-12-29 15:38:17 +01:00
ge_equals_gej ( & ref , & resj );
}
/* Test adding opposites. */
if (( i1 == 0 && i2 == 0 ) || (( i1 + 3 ) / 4 == ( i2 + 3 ) / 4 && (( i1 + 3 ) % 4 ) / 2 != (( i2 + 3 ) % 4 ) / 2 )) {
CHECK ( secp256k1_ge_is_infinity ( & ref ));
}
/* Test adding infinity. */
if ( i1 == 0 ) {
CHECK ( secp256k1_ge_is_infinity ( & ge [ i1 ]));
CHECK ( secp256k1_gej_is_infinity ( & gej [ i1 ]));
ge_equals_gej ( & ref , & gej [ i2 ]);
}
if ( i2 == 0 ) {
CHECK ( secp256k1_ge_is_infinity ( & ge [ i2 ]));
CHECK ( secp256k1_gej_is_infinity ( & gej [ i2 ]));
ge_equals_gej ( & ref , & gej [ i1 ]);
}
}
}
2014-12-29 17:21:39 +01:00
/* Test adding all points together in random order equals infinity. */
{
2015-09-21 20:57:54 +02:00
secp256k1_gej sum = SECP256K1_GEJ_CONST_INFINITY ;
secp256k1_gej * gej_shuffled = ( secp256k1_gej * ) malloc (( 4 * runs + 1 ) * sizeof ( secp256k1_gej ));
2015-01-25 15:47:04 +00:00
for ( i = 0 ; i < 4 * runs + 1 ; i ++ ) {
2014-12-29 17:21:39 +01:00
gej_shuffled [ i ] = gej [ i ];
}
2015-01-25 15:47:04 +00:00
for ( i = 0 ; i < 4 * runs + 1 ; i ++ ) {
2015-10-17 21:15:15 +02:00
int swap = i + secp256k1_rand_int ( 4 * runs + 1 - i );
2014-12-29 17:21:39 +01:00
if ( swap != i ) {
2015-09-21 20:57:54 +02:00
secp256k1_gej t = gej_shuffled [ i ];
2014-12-29 17:21:39 +01:00
gej_shuffled [ i ] = gej_shuffled [ swap ];
gej_shuffled [ swap ] = t ;
}
}
2015-01-25 15:47:04 +00:00
for ( i = 0 ; i < 4 * runs + 1 ; i ++ ) {
2014-11-04 19:16:55 +07:00
secp256k1_gej_add_var ( & sum , & sum , & gej_shuffled [ i ], NULL );
2014-12-29 17:21:39 +01:00
}
CHECK ( secp256k1_gej_is_infinity ( & sum ));
free ( gej_shuffled );
}
2014-11-04 19:16:55 +07:00
/* Test batch gej -> ge conversion with and without known z ratios. */
2014-12-29 15:38:17 +01:00
{
2015-09-21 20:57:54 +02:00
secp256k1_fe * zr = ( secp256k1_fe * ) malloc (( 4 * runs + 1 ) * sizeof ( secp256k1_fe ));
secp256k1_ge * ge_set_table = ( secp256k1_ge * ) malloc (( 4 * runs + 1 ) * sizeof ( secp256k1_ge ));
secp256k1_ge * ge_set_all = ( secp256k1_ge * ) malloc (( 4 * runs + 1 ) * sizeof ( secp256k1_ge ));
2014-11-04 19:16:55 +07:00
for ( i = 0 ; i < 4 * runs + 1 ; i ++ ) {
/* Compute gej[i + 1].z / gez[i].z (with gej[n].z taken to be 1). */
if ( i < 4 * runs ) {
secp256k1_fe_mul ( & zr [ i + 1 ], & zinv [ i ], & gej [ i + 1 ]. z );
}
}
secp256k1_ge_set_table_gej_var ( 4 * runs + 1 , ge_set_table , gej , zr );
2015-07-18 16:29:10 -04:00
secp256k1_ge_set_all_gej_var ( 4 * runs + 1 , ge_set_all , gej , & ctx -> error_callback );
2015-01-25 15:47:04 +00:00
for ( i = 0 ; i < 4 * runs + 1 ; i ++ ) {
2015-09-21 20:57:54 +02:00
secp256k1_fe s ;
2015-04-15 21:35:50 +00:00
random_fe_non_zero ( & s );
secp256k1_gej_rescale ( & gej [ i ], & s );
2014-11-04 19:16:55 +07:00
ge_equals_gej ( & ge_set_table [ i ], & gej [ i ]);
2014-12-29 15:38:17 +01:00
ge_equals_gej ( & ge_set_all [ i ], & gej [ i ]);
}
2014-11-04 19:16:55 +07:00
free ( ge_set_table );
2014-12-29 15:38:17 +01:00
free ( ge_set_all );
2014-11-04 19:16:55 +07:00
free ( zr );
2014-12-29 15:38:17 +01:00
}
free ( ge );
free ( gej );
2014-11-04 19:16:55 +07:00
free ( zinv );
2014-11-11 10:32:50 -08:00
}
2015-06-21 10:11:50 -07:00
void test_add_neg_y_diff_x ( void ) {
/* The point of this test is to check that we can add two points
* whose y-coordinates are negatives of each other but whose x
* coordinates differ. If the x-coordinates were the same, these
* points would be negatives of each other and their sum is
* infinity. This is cool because it "covers up" any degeneracy
* in the addition algorithm that would cause the xy coordinates
* of the sum to be wrong (since infinity has no xy coordinates).
* HOWEVER, if the x-coordinates are different, infinity is the
* wrong answer, and such degeneracies are exposed. This is the
* root of https://github.com/bitcoin/secp256k1/issues/257 which
* this test is a regression test for.
*
* These points were generated in sage as
* # secp256k1 params
* F = FiniteField (0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F)
* C = EllipticCurve ([F (0), F (7)])
* G = C.lift_x(0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798)
* N = FiniteField(G.order())
*
* # endomorphism values (lambda is 1^{1/3} in N, beta is 1^{1/3} in F)
* x = polygen(N)
* lam = (1 - x^3).roots()[1][0]
*
* # random "bad pair"
* P = C.random_element()
* Q = -int(lam) * P
* print " P: %x %x" % P.xy()
* print " Q: %x %x" % Q.xy()
* print "P + Q: %x %x" % (P + Q).xy()
*/
2015-09-21 20:57:54 +02:00
secp256k1_gej aj = SECP256K1_GEJ_CONST (
2015-06-21 10:11:50 -07:00
0x8d24cd95 , 0x0a355af1 , 0x3c543505 , 0x44238d30 ,
0x0643d79f , 0x05a59614 , 0x2f8ec030 , 0xd58977cb ,
0x001e337a , 0x38093dcd , 0x6c0f386d , 0x0b1293a8 ,
0x4d72c879 , 0xd7681924 , 0x44e6d2f3 , 0x9190117d
);
2015-09-21 20:57:54 +02:00
secp256k1_gej bj = SECP256K1_GEJ_CONST (
2015-06-21 10:11:50 -07:00
0xc7b74206 , 0x1f788cd9 , 0xabd0937d , 0x164a0d86 ,
0x95f6ff75 , 0xf19a4ce9 , 0xd013bd7b , 0xbf92d2a7 ,
0xffe1cc85 , 0xc7f6c232 , 0x93f0c792 , 0xf4ed6c57 ,
0xb28d3786 , 0x2897e6db , 0xbb192d0b , 0x6e6feab2
);
2015-09-21 20:57:54 +02:00
secp256k1_gej sumj = SECP256K1_GEJ_CONST (
2015-06-21 10:11:50 -07:00
0x671a63c0 , 0x3efdad4c , 0x389a7798 , 0x24356027 ,
0xb3d69010 , 0x278625c3 , 0x5c86d390 , 0x184a8f7a ,
0x5f6409c2 , 0x2ce01f2b , 0x511fd375 , 0x25071d08 ,
0xda651801 , 0x70e95caf , 0x8f0d893c , 0xbed8fbbe
);
2015-09-21 20:57:54 +02:00
secp256k1_ge b ;
secp256k1_gej resj ;
secp256k1_ge res ;
2015-06-21 10:11:50 -07:00
secp256k1_ge_set_gej ( & b , & bj );
secp256k1_gej_add_var ( & resj , & aj , & bj , NULL );
secp256k1_ge_set_gej ( & res , & resj );
ge_equals_gej ( & res , & sumj );
secp256k1_gej_add_ge ( & resj , & aj , & b );
secp256k1_ge_set_gej ( & res , & resj );
ge_equals_gej ( & res , & sumj );
secp256k1_gej_add_ge_var ( & resj , & aj , & b , NULL );
secp256k1_ge_set_gej ( & res , & resj );
ge_equals_gej ( & res , & sumj );
}
2014-11-12 13:24:12 -08:00
void run_ge ( void ) {
2015-01-25 15:47:04 +00:00
int i ;
for ( i = 0 ; i < count * 32 ; i ++ ) {
2014-11-11 10:32:50 -08:00
test_ge ();
}
2015-06-21 10:11:50 -07:00
test_add_neg_y_diff_x ();
2014-11-11 10:32:50 -08:00
}
2015-07-24 15:44:49 +02:00
void test_ec_combine ( void ) {
2015-09-21 20:57:54 +02:00
secp256k1_scalar sum = SECP256K1_SCALAR_CONST ( 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 );
secp256k1_pubkey data [ 6 ];
const secp256k1_pubkey * d [ 6 ];
secp256k1_pubkey sd ;
secp256k1_pubkey sd2 ;
secp256k1_gej Qj ;
secp256k1_ge Q ;
2015-07-24 15:44:49 +02:00
int i ;
for ( i = 1 ; i <= 6 ; i ++ ) {
2015-09-21 20:57:54 +02:00
secp256k1_scalar s ;
2015-07-24 15:44:49 +02:00
random_scalar_order_test ( & s );
secp256k1_scalar_add ( & sum , & sum , & s );
secp256k1_ecmult_gen ( & ctx -> ecmult_gen_ctx , & Qj , & s );
secp256k1_ge_set_gej ( & Q , & Qj );
secp256k1_pubkey_save ( & data [ i - 1 ], & Q );
d [ i - 1 ] = & data [ i - 1 ];
secp256k1_ecmult_gen ( & ctx -> ecmult_gen_ctx , & Qj , & sum );
secp256k1_ge_set_gej ( & Q , & Qj );
secp256k1_pubkey_save ( & sd , & Q );
2015-08-28 01:50:47 +02:00
CHECK ( secp256k1_ec_pubkey_combine ( ctx , & sd2 , d , i ) == 1 );
2015-07-24 15:44:49 +02:00
CHECK ( memcmp ( & sd , & sd2 , sizeof ( sd )) == 0 );
}
}
void run_ec_combine ( void ) {
int i ;
for ( i = 0 ; i < count * 8 ; i ++ ) {
test_ec_combine ();
}
}
2014-05-21 10:22:14 +07:00
/***** ECMULT TESTS *****/
2014-11-12 13:24:12 -08:00
void run_ecmult_chain ( void ) {
2015-02-23 04:17:37 -08:00
/* random starting point A (on the curve) */
2015-09-21 20:57:54 +02:00
secp256k1_gej a = SECP256K1_GEJ_CONST (
2015-02-23 04:17:37 -08:00
0x8b30bbe9 , 0xae2a9906 , 0x96b22f67 , 0x0709dff3 ,
0x727fd8bc , 0x04d3362c , 0x6c7bf458 , 0xe2846004 ,
0xa357ae91 , 0x5c4a6528 , 0x1309edf2 , 0x0504740f ,
0x0eb33439 , 0x90216b4f , 0x81063cb6 , 0x5f2f7e0f
);
2014-11-15 15:28:10 +00:00
/* two random initial factors xn and gn */
2015-09-21 20:57:54 +02:00
secp256k1_scalar xn = SECP256K1_SCALAR_CONST (
2015-02-23 04:17:37 -08:00
0x84cc5452 , 0xf7fde1ed , 0xb4d38a8c , 0xe9b1b84c ,
0xcef31f14 , 0x6e569be9 , 0x705d357a , 0x42985407
);
2015-09-21 20:57:54 +02:00
secp256k1_scalar gn = SECP256K1_SCALAR_CONST (
2015-02-23 04:17:37 -08:00
0xa1e58d22 , 0x553dcd42 , 0xb2398062 , 0x5d4c57a9 ,
0x6e9323d4 , 0x2b3152e5 , 0xca2c3990 , 0xedc7c9de
);
2014-11-15 15:28:10 +00:00
/* two small multipliers to be applied to xn and gn in every iteration: */
2015-09-21 20:57:54 +02:00
static const secp256k1_scalar xf = SECP256K1_SCALAR_CONST ( 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x1337 );
static const secp256k1_scalar gf = SECP256K1_SCALAR_CONST ( 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x7113 );
2014-11-15 15:28:10 +00:00
/* accumulators with the resulting coefficients to A and G */
2015-09-21 20:57:54 +02:00
secp256k1_scalar ae = SECP256K1_SCALAR_CONST ( 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 );
secp256k1_scalar ge = SECP256K1_SCALAR_CONST ( 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 );
2015-02-23 04:17:37 -08:00
/* actual points */
2015-09-24 08:42:37 +00:00
secp256k1_gej x ;
2015-09-21 20:57:54 +02:00
secp256k1_gej x2 ;
2015-02-23 04:17:37 -08:00
int i ;
2014-11-15 15:28:10 +00:00
/* the point being computed */
2015-01-25 15:47:04 +00:00
x = a ;
for ( i = 0 ; i < 200 * count ; i ++ ) {
2014-11-15 15:28:10 +00:00
/* in each iteration, compute X = xn*X + gn*G; */
2015-02-03 17:27:00 -08:00
secp256k1_ecmult ( & ctx -> ecmult_ctx , & x , & x , & xn , & gn );
2014-11-15 15:28:10 +00:00
/* also compute ae and ge: the actual accumulated factors for A and G */
/* if X was (ae*A+ge*G), xn*X + gn*G results in (xn*ae*A + (xn*ge+gn)*G) */
2014-11-26 17:26:39 +01:00
secp256k1_scalar_mul ( & ae , & ae , & xn );
secp256k1_scalar_mul ( & ge , & ge , & xn );
secp256k1_scalar_add ( & ge , & ge , & gn );
2014-11-15 15:28:10 +00:00
/* modify xn and gn */
2014-11-26 17:26:39 +01:00
secp256k1_scalar_mul ( & xn , & xn , & xf );
secp256k1_scalar_mul ( & gn , & gn , & gf );
2013-04-21 19:07:21 +02:00
2014-11-15 15:28:10 +00:00
/* verify */
2013-04-21 19:07:21 +02:00
if ( i == 19999 ) {
2015-02-23 04:17:37 -08:00
/* expected result after 19999 iterations */
2015-09-21 20:57:54 +02:00
secp256k1_gej rp = SECP256K1_GEJ_CONST (
2015-02-23 04:17:37 -08:00
0xD6E96687 , 0xF9B10D09 , 0x2A6F3543 , 0x9D86CEBE ,
0xA4535D0D , 0x409F5358 , 0x6440BD74 , 0xB933E830 ,
0xB95CBCA2 , 0xC77DA786 , 0x539BE8FD , 0x53354D2D ,
0x3B4F566A , 0xE6580454 , 0x07ED6015 , 0xEE1B2A88
);
secp256k1_gej_neg ( & rp , & rp );
2014-11-04 19:16:55 +07:00
secp256k1_gej_add_var ( & rp , & rp , & x , NULL );
2015-02-23 04:17:37 -08:00
CHECK ( secp256k1_gej_is_infinity ( & rp ));
2013-04-21 19:07:21 +02:00
}
2013-03-24 10:38:35 +01:00
}
2014-11-15 15:28:10 +00:00
/* redo the computation, but directly with the resulting ae and ge coefficients: */
2015-02-03 17:27:00 -08:00
secp256k1_ecmult ( & ctx -> ecmult_ctx , & x2 , & a , & ae , & ge );
2015-02-23 04:17:37 -08:00
secp256k1_gej_neg ( & x2 , & x2 );
2014-11-04 19:16:55 +07:00
secp256k1_gej_add_var ( & x2 , & x2 , & x , NULL );
2015-02-23 04:17:37 -08:00
CHECK ( secp256k1_gej_is_infinity ( & x2 ));
2013-03-10 21:25:19 +01:00
}
2015-09-21 20:57:54 +02:00
void test_point_times_order ( const secp256k1_gej * point ) {
2014-11-26 15:35:06 +01:00
/* X * (point + G) + (order-X) * (pointer + G) = 0 */
2015-09-21 20:57:54 +02:00
secp256k1_scalar x ;
secp256k1_scalar nx ;
secp256k1_scalar zero = SECP256K1_SCALAR_CONST ( 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 );
secp256k1_scalar one = SECP256K1_SCALAR_CONST ( 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 );
secp256k1_gej res1 , res2 ;
secp256k1_ge res3 ;
2015-01-25 15:47:04 +00:00
unsigned char pub [ 65 ];
2015-09-01 04:35:10 +00:00
size_t psize = 65 ;
2015-01-25 15:47:04 +00:00
random_scalar_order_test ( & x );
secp256k1_scalar_negate ( & nx , & x );
2015-02-03 17:27:00 -08:00
secp256k1_ecmult ( & ctx -> ecmult_ctx , & res1 , point , & x , & x ); /* calc res1 = x * point + x * G; */
secp256k1_ecmult ( & ctx -> ecmult_ctx , & res2 , point , & nx , & nx ); /* calc res2 = (order - x) * point + (order - x) * G; */
2014-11-04 19:16:55 +07:00
secp256k1_gej_add_var ( & res1 , & res1 , & res2 , NULL );
2014-11-26 15:35:06 +01:00
CHECK ( secp256k1_gej_is_infinity ( & res1 ));
2014-12-05 03:37:42 +01:00
CHECK ( secp256k1_gej_is_valid_var ( & res1 ) == 0 );
2014-12-04 01:04:00 -08:00
secp256k1_ge_set_gej ( & res3 , & res1 );
CHECK ( secp256k1_ge_is_infinity ( & res3 ));
2014-12-05 03:37:42 +01:00
CHECK ( secp256k1_ge_is_valid_var ( & res3 ) == 0 );
2014-12-08 00:48:53 -08:00
CHECK ( secp256k1_eckey_pubkey_serialize ( & res3 , pub , & psize , 0 ) == 0 );
psize = 65 ;
CHECK ( secp256k1_eckey_pubkey_serialize ( & res3 , pub , & psize , 1 ) == 0 );
2015-05-13 21:16:13 -05:00
/* check zero/one edge cases */
secp256k1_ecmult ( & ctx -> ecmult_ctx , & res1 , point , & zero , & zero );
secp256k1_ge_set_gej ( & res3 , & res1 );
CHECK ( secp256k1_ge_is_infinity ( & res3 ));
secp256k1_ecmult ( & ctx -> ecmult_ctx , & res1 , point , & one , & zero );
secp256k1_ge_set_gej ( & res3 , & res1 );
ge_equals_gej ( & res3 , point );
secp256k1_ecmult ( & ctx -> ecmult_ctx , & res1 , point , & zero , & one );
secp256k1_ge_set_gej ( & res3 , & res1 );
ge_equals_ge ( & res3 , & secp256k1_ge_const_g );
2013-03-11 01:19:24 +01:00
}
2014-11-12 13:24:12 -08:00
void run_point_times_order ( void ) {
2015-01-25 15:47:04 +00:00
int i ;
2015-09-21 20:57:54 +02:00
secp256k1_fe x = SECP256K1_FE_CONST ( 0 , 0 , 0 , 0 , 0 , 0 , 0 , 2 );
static const secp256k1_fe xr = SECP256K1_FE_CONST (
2015-02-23 04:17:37 -08:00
0x7603CB59 , 0xB0EF6C63 , 0xFE608479 , 0x2A0C378C ,
0xDB3233A8 , 0x0F8A9A09 , 0xA877DEAD , 0x31B38C45
);
2015-01-25 15:47:04 +00:00
for ( i = 0 ; i < 500 ; i ++ ) {
2015-09-21 20:57:54 +02:00
secp256k1_ge p ;
2014-12-05 03:37:42 +01:00
if ( secp256k1_ge_set_xo_var ( & p , & x , 1 )) {
2015-09-21 20:57:54 +02:00
secp256k1_gej j ;
2015-01-25 15:47:04 +00:00
CHECK ( secp256k1_ge_is_valid_var ( & p ));
2014-05-21 10:22:14 +07:00
secp256k1_gej_set_ge ( & j , & p );
2014-12-05 03:37:42 +01:00
CHECK ( secp256k1_gej_is_valid_var ( & j ));
2014-05-21 10:22:14 +07:00
test_point_times_order ( & j );
}
2013-03-30 22:32:16 +01:00
secp256k1_fe_sqr ( & x , & x );
2013-03-11 01:19:24 +01:00
}
2015-02-23 04:17:37 -08:00
secp256k1_fe_normalize_var ( & x );
CHECK ( secp256k1_fe_equal_var ( & x , & xr ));
2013-03-11 01:19:24 +01:00
}
2015-05-13 17:31:47 -05:00
void ecmult_const_random_mult ( void ) {
/* random starting point A (on the curve) */
2015-09-21 20:57:54 +02:00
secp256k1_ge a = SECP256K1_GE_CONST (
2015-05-13 17:31:47 -05:00
0x6d986544 , 0x57ff52b8 , 0xcf1b8126 , 0x5b802a5b ,
0xa97f9263 , 0xb1e88044 , 0x93351325 , 0x91bc450a ,
0x535c59f7 , 0x325e5d2b , 0xc391fbe8 , 0x3c12787c ,
0x337e4a98 , 0xe82a9011 , 0x0123ba37 , 0xdd769c7d
);
/* random initial factor xn */
2015-09-21 20:57:54 +02:00
secp256k1_scalar xn = SECP256K1_SCALAR_CONST (
2015-05-13 17:31:47 -05:00
0x649d4f77 , 0xc4242df7 , 0x7f2079c9 , 0x14530327 ,
0xa31b876a , 0xd2d8ce2a , 0x2236d5c6 , 0xd7b2029b
);
/* expected xn * A (from sage) */
2015-09-21 20:57:54 +02:00
secp256k1_ge expected_b = SECP256K1_GE_CONST (
2015-05-13 17:31:47 -05:00
0x23773684 , 0x4d209dc7 , 0x098a786f , 0x20d06fcd ,
0x070a38bf , 0xc11ac651 , 0x03004319 , 0x1e2a8786 ,
0xed8c3b8e , 0xc06dd57b , 0xd06ea66e , 0x45492b0f ,
0xb84e4e1b , 0xfb77e21f , 0x96baae2a , 0x63dec956
);
2015-09-21 20:57:54 +02:00
secp256k1_gej b ;
2015-05-13 17:31:47 -05:00
secp256k1_ecmult_const ( & b , & a , & xn );
CHECK ( secp256k1_ge_is_valid_var ( & a ));
ge_equals_gej ( & expected_b , & b );
}
void ecmult_const_commutativity ( void ) {
2015-09-21 20:57:54 +02:00
secp256k1_scalar a ;
secp256k1_scalar b ;
secp256k1_gej res1 ;
secp256k1_gej res2 ;
secp256k1_ge mid1 ;
secp256k1_ge mid2 ;
2015-05-13 17:31:47 -05:00
random_scalar_order_test ( & a );
random_scalar_order_test ( & b );
secp256k1_ecmult_const ( & res1 , & secp256k1_ge_const_g , & a );
secp256k1_ecmult_const ( & res2 , & secp256k1_ge_const_g , & b );
secp256k1_ge_set_gej ( & mid1 , & res1 );
secp256k1_ge_set_gej ( & mid2 , & res2 );
secp256k1_ecmult_const ( & res1 , & mid1 , & b );
secp256k1_ecmult_const ( & res2 , & mid2 , & a );
secp256k1_ge_set_gej ( & mid1 , & res1 );
secp256k1_ge_set_gej ( & mid2 , & res2 );
ge_equals_ge ( & mid1 , & mid2 );
}
void ecmult_const_mult_zero_one ( void ) {
2015-09-21 20:57:54 +02:00
secp256k1_scalar zero = SECP256K1_SCALAR_CONST ( 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 );
secp256k1_scalar one = SECP256K1_SCALAR_CONST ( 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 );
secp256k1_scalar negone ;
secp256k1_gej res1 ;
secp256k1_ge res2 ;
secp256k1_ge point ;
2015-05-13 17:31:47 -05:00
secp256k1_scalar_negate ( & negone , & one );
random_group_element_test ( & point );
secp256k1_ecmult_const ( & res1 , & point , & zero );
secp256k1_ge_set_gej ( & res2 , & res1 );
CHECK ( secp256k1_ge_is_infinity ( & res2 ));
secp256k1_ecmult_const ( & res1 , & point , & one );
secp256k1_ge_set_gej ( & res2 , & res1 );
ge_equals_ge ( & res2 , & point );
secp256k1_ecmult_const ( & res1 , & point , & negone );
secp256k1_gej_neg ( & res1 , & res1 );
secp256k1_ge_set_gej ( & res2 , & res1 );
ge_equals_ge ( & res2 , & point );
}
void ecmult_const_chain_multiply ( void ) {
/* Check known result (randomly generated test problem from sage) */
2015-09-21 20:57:54 +02:00
const secp256k1_scalar scalar = SECP256K1_SCALAR_CONST (
2015-05-13 17:31:47 -05:00
0x4968d524 , 0x2abf9b7a , 0x466abbcf , 0x34b11b6d ,
0xcd83d307 , 0x827bed62 , 0x05fad0ce , 0x18fae63b
);
2015-09-21 20:57:54 +02:00
const secp256k1_gej expected_point = SECP256K1_GEJ_CONST (
2015-05-13 17:31:47 -05:00
0x5494c15d , 0x32099706 , 0xc2395f94 , 0x348745fd ,
0x757ce30e , 0x4e8c90fb , 0xa2bad184 , 0xf883c69f ,
0x5d195d20 , 0xe191bf7f , 0x1be3e55f , 0x56a80196 ,
0x6071ad01 , 0xf1462f66 , 0xc997fa94 , 0xdb858435
);
2015-09-21 20:57:54 +02:00
secp256k1_gej point ;
secp256k1_ge res ;
2015-05-13 17:31:47 -05:00
int i ;
secp256k1_gej_set_ge ( & point , & secp256k1_ge_const_g );
for ( i = 0 ; i < 100 ; ++ i ) {
2015-09-21 20:57:54 +02:00
secp256k1_ge tmp ;
2015-05-13 17:31:47 -05:00
secp256k1_ge_set_gej ( & tmp , & point );
secp256k1_ecmult_const ( & point , & tmp , & scalar );
}
secp256k1_ge_set_gej ( & res , & point );
ge_equals_gej ( & res , & expected_point );
}
void run_ecmult_const_tests ( void ) {
ecmult_const_mult_zero_one ();
ecmult_const_random_mult ();
ecmult_const_commutativity ();
ecmult_const_chain_multiply ();
}
2015-09-21 20:57:54 +02:00
void test_wnaf ( const secp256k1_scalar * number , int w ) {
secp256k1_scalar x , two , t ;
2015-01-25 15:47:04 +00:00
int wnaf [ 256 ];
int zeroes = - 1 ;
int i ;
int bits ;
2014-11-26 17:26:39 +01:00
secp256k1_scalar_set_int ( & x , 0 );
secp256k1_scalar_set_int ( & two , 2 );
2015-07-12 17:50:59 +10:00
bits = secp256k1_ecmult_wnaf ( wnaf , 256 , number , w );
2014-11-26 14:47:23 +01:00
CHECK ( bits <= 256 );
2015-01-25 15:47:04 +00:00
for ( i = bits - 1 ; i >= 0 ; i -- ) {
2013-04-01 06:29:30 +02:00
int v = wnaf [ i ];
2015-01-25 15:47:04 +00:00
secp256k1_scalar_mul ( & x , & x , & two );
2013-03-11 01:19:24 +01:00
if ( v ) {
2014-11-15 15:28:10 +00:00
CHECK ( zeroes == - 1 || zeroes >= w - 1 ); /* check that distance between non-zero elements is at least w-1 */
2013-03-11 01:19:24 +01:00
zeroes = 0 ;
2014-11-15 15:28:10 +00:00
CHECK (( v & 1 ) == 1 ); /* check non-zero elements are odd */
CHECK ( v <= ( 1 << ( w - 1 )) - 1 ); /* check range below */
CHECK ( v >= - ( 1 << ( w - 1 )) - 1 ); /* check range above */
2013-03-11 01:19:24 +01:00
} else {
2014-11-15 15:28:10 +00:00
CHECK ( zeroes != - 1 ); /* check that no unnecessary zero padding exists */
2013-03-11 01:19:24 +01:00
zeroes ++ ;
}
2014-11-26 17:26:39 +01:00
if ( v >= 0 ) {
secp256k1_scalar_set_int ( & t , v );
} else {
secp256k1_scalar_set_int ( & t , - v );
secp256k1_scalar_negate ( & t , & t );
}
secp256k1_scalar_add ( & x , & x , & t );
2013-03-11 01:19:24 +01:00
}
2014-11-26 17:26:39 +01:00
CHECK ( secp256k1_scalar_eq ( & x , number )); /* check that wnaf represents number */
2013-03-11 01:19:24 +01:00
}
2015-09-21 20:57:54 +02:00
void test_constant_wnaf_negate ( const secp256k1_scalar * number ) {
secp256k1_scalar neg1 = * number ;
secp256k1_scalar neg2 = * number ;
2015-05-13 17:31:47 -05:00
int sign1 = 1 ;
int sign2 = 1 ;
if ( ! secp256k1_scalar_get_bits ( & neg1 , 0 , 1 )) {
secp256k1_scalar_negate ( & neg1 , & neg1 );
sign1 = - 1 ;
}
sign2 = secp256k1_scalar_cond_negate ( & neg2 , secp256k1_scalar_is_even ( & neg2 ));
CHECK ( sign1 == sign2 );
CHECK ( secp256k1_scalar_eq ( & neg1 , & neg2 ));
}
2015-09-21 20:57:54 +02:00
void test_constant_wnaf ( const secp256k1_scalar * number , int w ) {
secp256k1_scalar x , shift ;
2015-05-13 17:31:47 -05:00
int wnaf [ 256 ] = { 0 };
int i ;
2015-05-22 12:09:36 -05:00
#ifdef USE_ENDOMORPHISM
int skew ;
#endif
2015-09-21 20:57:54 +02:00
secp256k1_scalar num = * number ;
2015-05-13 17:31:47 -05:00
secp256k1_scalar_set_int ( & x , 0 );
secp256k1_scalar_set_int ( & shift , 1 << w );
2015-05-22 12:09:36 -05:00
/* With USE_ENDOMORPHISM on we only consider 128-bit numbers */
#ifdef USE_ENDOMORPHISM
2015-09-21 17:21:35 +00:00
for ( i = 0 ; i < 16 ; ++ i ) {
2015-05-22 12:09:36 -05:00
secp256k1_scalar_shr_int ( & num , 8 );
2015-09-21 17:21:35 +00:00
}
2015-05-22 12:09:36 -05:00
skew = secp256k1_wnaf_const ( wnaf , num , w );
#else
secp256k1_wnaf_const ( wnaf , num , w );
#endif
2015-05-13 17:31:47 -05:00
for ( i = WNAF_SIZE ( w ); i >= 0 ; -- i ) {
2015-09-21 20:57:54 +02:00
secp256k1_scalar t ;
2015-05-13 17:31:47 -05:00
int v = wnaf [ i ];
CHECK ( v != 0 ); /* check nonzero */
CHECK ( v & 1 ); /* check parity */
CHECK ( v > - ( 1 << w )); /* check range above */
CHECK ( v < ( 1 << w )); /* check range below */
secp256k1_scalar_mul ( & x , & x , & shift );
if ( v >= 0 ) {
secp256k1_scalar_set_int ( & t , v );
} else {
secp256k1_scalar_set_int ( & t , - v );
secp256k1_scalar_negate ( & t , & t );
}
secp256k1_scalar_add ( & x , & x , & t );
}
2015-05-22 12:09:36 -05:00
#ifdef USE_ENDOMORPHISM
/* Skew num because when encoding 128-bit numbers as odd we use an offset */
secp256k1_scalar_cadd_bit ( & num , skew == 2 , 1 );
#endif
CHECK ( secp256k1_scalar_eq ( & x , & num ));
2015-05-13 17:31:47 -05:00
}
2014-11-12 13:24:12 -08:00
void run_wnaf ( void ) {
2015-01-25 15:47:04 +00:00
int i ;
2015-09-21 20:57:54 +02:00
secp256k1_scalar n = {{ 0 }};
2015-05-13 17:31:47 -05:00
/* Sanity check: 1 and 2 are the smallest odd and even numbers and should
* have easier-to-diagnose failure modes */
n . d [ 0 ] = 1 ;
test_constant_wnaf ( & n , 4 );
n . d [ 0 ] = 2 ;
test_constant_wnaf ( & n , 4 );
/* Random tests */
2015-01-25 15:47:04 +00:00
for ( i = 0 ; i < count ; i ++ ) {
2014-11-26 17:26:39 +01:00
random_scalar_order ( & n );
2013-04-01 07:52:58 +02:00
test_wnaf ( & n , 4 + ( i % 10 ));
2015-05-13 17:31:47 -05:00
test_constant_wnaf_negate ( & n );
test_constant_wnaf ( & n , 4 + ( i % 10 ));
2013-03-11 01:19:24 +01:00
}
}
2013-03-10 21:25:19 +01:00
2015-04-15 21:35:50 +00:00
void test_ecmult_constants ( void ) {
/* Test ecmult_gen() for [0..36) and [order-36..0). */
2015-09-21 20:57:54 +02:00
secp256k1_scalar x ;
secp256k1_gej r ;
secp256k1_ge ng ;
2015-04-15 21:35:50 +00:00
int i ;
int j ;
secp256k1_ge_neg ( & ng , & secp256k1_ge_const_g );
for ( i = 0 ; i < 36 ; i ++ ) {
secp256k1_scalar_set_int ( & x , i );
secp256k1_ecmult_gen ( & ctx -> ecmult_gen_ctx , & r , & x );
for ( j = 0 ; j < i ; j ++ ) {
if ( j == i - 1 ) {
ge_equals_gej ( & secp256k1_ge_const_g , & r );
}
secp256k1_gej_add_ge ( & r , & r , & ng );
}
CHECK ( secp256k1_gej_is_infinity ( & r ));
}
for ( i = 1 ; i <= 36 ; i ++ ) {
secp256k1_scalar_set_int ( & x , i );
secp256k1_scalar_negate ( & x , & x );
secp256k1_ecmult_gen ( & ctx -> ecmult_gen_ctx , & r , & x );
for ( j = 0 ; j < i ; j ++ ) {
if ( j == i - 1 ) {
ge_equals_gej ( & ng , & r );
}
secp256k1_gej_add_ge ( & r , & r , & secp256k1_ge_const_g );
}
CHECK ( secp256k1_gej_is_infinity ( & r ));
}
}
void run_ecmult_constants ( void ) {
test_ecmult_constants ();
}
void test_ecmult_gen_blind ( void ) {
/* Test ecmult_gen() blinding and confirm that the blinding changes, the affline points match, and the z's don't match. */
2015-09-21 20:57:54 +02:00
secp256k1_scalar key ;
secp256k1_scalar b ;
2015-04-15 21:35:50 +00:00
unsigned char seed32 [ 32 ];
2015-09-21 20:57:54 +02:00
secp256k1_gej pgej ;
secp256k1_gej pgej2 ;
secp256k1_gej i ;
secp256k1_ge pge ;
2015-04-15 21:35:50 +00:00
random_scalar_order_test ( & key );
secp256k1_ecmult_gen ( & ctx -> ecmult_gen_ctx , & pgej , & key );
secp256k1_rand256 ( seed32 );
b = ctx -> ecmult_gen_ctx . blind ;
i = ctx -> ecmult_gen_ctx . initial ;
secp256k1_ecmult_gen_blind ( & ctx -> ecmult_gen_ctx , seed32 );
CHECK ( ! secp256k1_scalar_eq ( & b , & ctx -> ecmult_gen_ctx . blind ));
secp256k1_ecmult_gen ( & ctx -> ecmult_gen_ctx , & pgej2 , & key );
CHECK ( ! gej_xyz_equals_gej ( & pgej , & pgej2 ));
CHECK ( ! gej_xyz_equals_gej ( & i , & ctx -> ecmult_gen_ctx . initial ));
secp256k1_ge_set_gej ( & pge , & pgej );
ge_equals_gej ( & pge , & pgej2 );
}
void test_ecmult_gen_blind_reset ( void ) {
/* Test ecmult_gen() blinding reset and confirm that the blinding is consistent. */
2015-09-21 20:57:54 +02:00
secp256k1_scalar b ;
secp256k1_gej initial ;
2015-04-15 21:35:50 +00:00
secp256k1_ecmult_gen_blind ( & ctx -> ecmult_gen_ctx , 0 );
b = ctx -> ecmult_gen_ctx . blind ;
initial = ctx -> ecmult_gen_ctx . initial ;
secp256k1_ecmult_gen_blind ( & ctx -> ecmult_gen_ctx , 0 );
CHECK ( secp256k1_scalar_eq ( & b , & ctx -> ecmult_gen_ctx . blind ));
CHECK ( gej_xyz_equals_gej ( & initial , & ctx -> ecmult_gen_ctx . initial ));
}
void run_ecmult_gen_blind ( void ) {
int i ;
test_ecmult_gen_blind_reset ();
for ( i = 0 ; i < 10 ; i ++ ) {
test_ecmult_gen_blind ();
}
}
2015-05-13 21:16:13 -05:00
#ifdef USE_ENDOMORPHISM
/***** ENDOMORPHISH TESTS *****/
void test_scalar_split ( void ) {
2015-09-21 20:57:54 +02:00
secp256k1_scalar full ;
secp256k1_scalar s1 , slam ;
2015-05-13 21:16:13 -05:00
const unsigned char zero [ 32 ] = { 0 };
unsigned char tmp [ 32 ];
random_scalar_order_test ( & full );
2015-05-22 11:51:51 -05:00
secp256k1_scalar_split_lambda ( & s1 , & slam , & full );
2015-05-13 21:16:13 -05:00
/* check that both are <= 128 bits in size */
2015-09-21 17:21:35 +00:00
if ( secp256k1_scalar_is_high ( & s1 )) {
2015-05-13 21:16:13 -05:00
secp256k1_scalar_negate ( & s1 , & s1 );
2015-09-21 17:21:35 +00:00
}
if ( secp256k1_scalar_is_high ( & slam )) {
2015-05-13 21:16:13 -05:00
secp256k1_scalar_negate ( & slam , & slam );
2015-09-21 17:21:35 +00:00
}
2015-05-13 21:16:13 -05:00
secp256k1_scalar_get_b32 ( tmp , & s1 );
CHECK ( memcmp ( zero , tmp , 16 ) == 0 );
secp256k1_scalar_get_b32 ( tmp , & slam );
CHECK ( memcmp ( zero , tmp , 16 ) == 0 );
}
void run_endomorphism_tests ( void ) {
test_scalar_split ();
}
#endif
2015-04-15 21:35:50 +00:00
2015-09-27 23:47:01 +00:00
static void counting_illegal_callback_fn ( const char * str , void * data ) {
/* Dummy callback function that just counts. */
int32_t * p ;
( void ) str ;
p = data ;
( * p ) ++ ;
}
static void uncounting_illegal_callback_fn ( const char * str , void * data ) {
/* Dummy callback function that just counts (backwards). */
int32_t * p ;
( void ) str ;
p = data ;
( * p ) -- ;
}
void ec_pubkey_parse_pointtest ( const unsigned char * input , int xvalid , int yvalid ) {
unsigned char pubkeyc [ 65 ];
secp256k1_pubkey pubkey ;
secp256k1_ge ge ;
size_t pubkeyclen ;
int32_t ecount ;
ecount = 0 ;
secp256k1_context_set_illegal_callback ( ctx , counting_illegal_callback_fn , & ecount );
for ( pubkeyclen = 3 ; pubkeyclen <= 65 ; pubkeyclen ++ ) {
/* Smaller sizes are tested exhaustively elsewhere. */
int32_t i ;
memcpy ( & pubkeyc [ 1 ], input , 64 );
VG_UNDEF ( & pubkeyc [ pubkeyclen ], 65 - pubkeyclen );
for ( i = 0 ; i < 256 ; i ++ ) {
/* Try all type bytes. */
int xpass ;
int ypass ;
int ysign ;
pubkeyc [ 0 ] = i ;
/* What sign does this point have? */
ysign = ( input [ 63 ] & 1 ) + 2 ;
/* For the current type (i) do we expect parsing to work? Handled all of compressed/uncompressed/hybrid. */
xpass = xvalid && ( pubkeyclen == 33 ) && (( i & 254 ) == 2 );
/* Do we expect a parse and re-serialize as uncompressed to give a matching y? */
ypass = xvalid && yvalid && (( i & 4 ) == (( pubkeyclen == 65 ) << 2 )) &&
(( i == 4 ) || (( i & 251 ) == ysign )) && (( pubkeyclen == 33 ) || ( pubkeyclen == 65 ));
if ( xpass || ypass ) {
/* These cases must parse. */
unsigned char pubkeyo [ 65 ];
size_t outl ;
memset ( & pubkey , 0 , sizeof ( pubkey ));
VG_UNDEF ( & pubkey , sizeof ( pubkey ));
ecount = 0 ;
CHECK ( secp256k1_ec_pubkey_parse ( ctx , & pubkey , pubkeyc , pubkeyclen ) == 1 );
VG_CHECK ( & pubkey , sizeof ( pubkey ));
outl = 65 ;
VG_UNDEF ( pubkeyo , 65 );
CHECK ( secp256k1_ec_pubkey_serialize ( ctx , pubkeyo , & outl , & pubkey , SECP256K1_EC_COMPRESSED ) == 1 );
VG_CHECK ( pubkeyo , outl );
CHECK ( outl == 33 );
CHECK ( memcmp ( & pubkeyo [ 1 ], & pubkeyc [ 1 ], 32 ) == 0 );
CHECK (( pubkeyclen != 33 ) || ( pubkeyo [ 0 ] == pubkeyc [ 0 ]));
if ( ypass ) {
/* This test isn't always done because we decode with alternative signs, so the y won't match. */
CHECK ( pubkeyo [ 0 ] == ysign );
CHECK ( secp256k1_pubkey_load ( ctx , & ge , & pubkey ) == 1 );
memset ( & pubkey , 0 , sizeof ( pubkey ));
VG_UNDEF ( & pubkey , sizeof ( pubkey ));
secp256k1_pubkey_save ( & pubkey , & ge );
VG_CHECK ( & pubkey , sizeof ( pubkey ));
outl = 65 ;
VG_UNDEF ( pubkeyo , 65 );
CHECK ( secp256k1_ec_pubkey_serialize ( ctx , pubkeyo , & outl , & pubkey , 0 ) == 1 );
VG_CHECK ( pubkeyo , outl );
CHECK ( outl == 65 );
CHECK ( pubkeyo [ 0 ] == 4 );
CHECK ( memcmp ( & pubkeyo [ 1 ], input , 64 ) == 0 );
}
CHECK ( ecount == 0 );
} else {
/* These cases must fail to parse. */
memset ( & pubkey , 0xfe , sizeof ( pubkey ));
ecount = 0 ;
VG_UNDEF ( & pubkey , sizeof ( pubkey ));
CHECK ( secp256k1_ec_pubkey_parse ( ctx , & pubkey , pubkeyc , pubkeyclen ) == 0 );
VG_CHECK ( & pubkey , sizeof ( pubkey ));
CHECK ( ecount == 0 );
CHECK ( secp256k1_pubkey_load ( ctx , & ge , & pubkey ) == 0 );
CHECK ( ecount == 1 );
}
}
}
secp256k1_context_set_illegal_callback ( ctx , NULL , NULL );
}
void run_ec_pubkey_parse_test ( void ) {
#define SECP256K1_EC_PARSE_TEST_NVALID (12)
const unsigned char valid [ SECP256K1_EC_PARSE_TEST_NVALID ][ 64 ] = {
{
/* Point with leading and trailing zeros in x and y serialization. */
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x42 , 0x52 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x64 , 0xef , 0xa1 , 0x7b , 0x77 , 0x61 , 0xe1 , 0xe4 , 0x27 , 0x06 , 0x98 , 0x9f , 0xb4 , 0x83 ,
0xb8 , 0xd2 , 0xd4 , 0x9b , 0xf7 , 0x8f , 0xae , 0x98 , 0x03 , 0xf0 , 0x99 , 0xb8 , 0x34 , 0xed , 0xeb , 0x00
},
{
/* Point with x equal to a 3rd root of unity.*/
0x7a , 0xe9 , 0x6a , 0x2b , 0x65 , 0x7c , 0x07 , 0x10 , 0x6e , 0x64 , 0x47 , 0x9e , 0xac , 0x34 , 0x34 , 0xe9 ,
0x9c , 0xf0 , 0x49 , 0x75 , 0x12 , 0xf5 , 0x89 , 0x95 , 0xc1 , 0x39 , 0x6c , 0x28 , 0x71 , 0x95 , 0x01 , 0xee ,
0x42 , 0x18 , 0xf2 , 0x0a , 0xe6 , 0xc6 , 0x46 , 0xb3 , 0x63 , 0xdb , 0x68 , 0x60 , 0x58 , 0x22 , 0xfb , 0x14 ,
0x26 , 0x4c , 0xa8 , 0xd2 , 0x58 , 0x7f , 0xdd , 0x6f , 0xbc , 0x75 , 0x0d , 0x58 , 0x7e , 0x76 , 0xa7 , 0xee ,
},
{
/* Point with largest x. (1/2) */
0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff ,
0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xfe , 0xff , 0xff , 0xfc , 0x2c ,
0x0e , 0x99 , 0x4b , 0x14 , 0xea , 0x72 , 0xf8 , 0xc3 , 0xeb , 0x95 , 0xc7 , 0x1e , 0xf6 , 0x92 , 0x57 , 0x5e ,
0x77 , 0x50 , 0x58 , 0x33 , 0x2d , 0x7e , 0x52 , 0xd0 , 0x99 , 0x5c , 0xf8 , 0x03 , 0x88 , 0x71 , 0xb6 , 0x7d ,
},
{
/* Point with largest x. (2/2) */
0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff ,
0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xfe , 0xff , 0xff , 0xfc , 0x2c ,
0xf1 , 0x66 , 0xb4 , 0xeb , 0x15 , 0x8d , 0x07 , 0x3c , 0x14 , 0x6a , 0x38 , 0xe1 , 0x09 , 0x6d , 0xa8 , 0xa1 ,
0x88 , 0xaf , 0xa7 , 0xcc , 0xd2 , 0x81 , 0xad , 0x2f , 0x66 , 0xa3 , 0x07 , 0xfb , 0x77 , 0x8e , 0x45 , 0xb2 ,
},
{
/* Point with smallest x. (1/2) */
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x01 ,
0x42 , 0x18 , 0xf2 , 0x0a , 0xe6 , 0xc6 , 0x46 , 0xb3 , 0x63 , 0xdb , 0x68 , 0x60 , 0x58 , 0x22 , 0xfb , 0x14 ,
0x26 , 0x4c , 0xa8 , 0xd2 , 0x58 , 0x7f , 0xdd , 0x6f , 0xbc , 0x75 , 0x0d , 0x58 , 0x7e , 0x76 , 0xa7 , 0xee ,
},
{
/* Point with smallest x. (2/2) */
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x01 ,
0xbd , 0xe7 , 0x0d , 0xf5 , 0x19 , 0x39 , 0xb9 , 0x4c , 0x9c , 0x24 , 0x97 , 0x9f , 0xa7 , 0xdd , 0x04 , 0xeb ,
0xd9 , 0xb3 , 0x57 , 0x2d , 0xa7 , 0x80 , 0x22 , 0x90 , 0x43 , 0x8a , 0xf2 , 0xa6 , 0x81 , 0x89 , 0x54 , 0x41 ,
},
{
/* Point with largest y. (1/3) */
0x1f , 0xe1 , 0xe5 , 0xef , 0x3f , 0xce , 0xb5 , 0xc1 , 0x35 , 0xab , 0x77 , 0x41 , 0x33 , 0x3c , 0xe5 , 0xa6 ,
0xe8 , 0x0d , 0x68 , 0x16 , 0x76 , 0x53 , 0xf6 , 0xb2 , 0xb2 , 0x4b , 0xcb , 0xcf , 0xaa , 0xaf , 0xf5 , 0x07 ,
0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff ,
0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xfe , 0xff , 0xff , 0xfc , 0x2e ,
},
{
/* Point with largest y. (2/3) */
0xcb , 0xb0 , 0xde , 0xab , 0x12 , 0x57 , 0x54 , 0xf1 , 0xfd , 0xb2 , 0x03 , 0x8b , 0x04 , 0x34 , 0xed , 0x9c ,
0xb3 , 0xfb , 0x53 , 0xab , 0x73 , 0x53 , 0x91 , 0x12 , 0x99 , 0x94 , 0xa5 , 0x35 , 0xd9 , 0x25 , 0xf6 , 0x73 ,
0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff ,
0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xfe , 0xff , 0xff , 0xfc , 0x2e ,
},
{
/* Point with largest y. (3/3) */
0x14 , 0x6d , 0x3b , 0x65 , 0xad , 0xd9 , 0xf5 , 0x4c , 0xcc , 0xa2 , 0x85 , 0x33 , 0xc8 , 0x8e , 0x2c , 0xbc ,
0x63 , 0xf7 , 0x44 , 0x3e , 0x16 , 0x58 , 0x78 , 0x3a , 0xb4 , 0x1f , 0x8e , 0xf9 , 0x7c , 0x2a , 0x10 , 0xb5 ,
0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff ,
0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xfe , 0xff , 0xff , 0xfc , 0x2e ,
},
{
/* Point with smallest y. (1/3) */
0x1f , 0xe1 , 0xe5 , 0xef , 0x3f , 0xce , 0xb5 , 0xc1 , 0x35 , 0xab , 0x77 , 0x41 , 0x33 , 0x3c , 0xe5 , 0xa6 ,
0xe8 , 0x0d , 0x68 , 0x16 , 0x76 , 0x53 , 0xf6 , 0xb2 , 0xb2 , 0x4b , 0xcb , 0xcf , 0xaa , 0xaf , 0xf5 , 0x07 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x01 ,
},
{
/* Point with smallest y. (2/3) */
0xcb , 0xb0 , 0xde , 0xab , 0x12 , 0x57 , 0x54 , 0xf1 , 0xfd , 0xb2 , 0x03 , 0x8b , 0x04 , 0x34 , 0xed , 0x9c ,
0xb3 , 0xfb , 0x53 , 0xab , 0x73 , 0x53 , 0x91 , 0x12 , 0x99 , 0x94 , 0xa5 , 0x35 , 0xd9 , 0x25 , 0xf6 , 0x73 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x01 ,
},
{
/* Point with smallest y. (3/3) */
0x14 , 0x6d , 0x3b , 0x65 , 0xad , 0xd9 , 0xf5 , 0x4c , 0xcc , 0xa2 , 0x85 , 0x33 , 0xc8 , 0x8e , 0x2c , 0xbc ,
0x63 , 0xf7 , 0x44 , 0x3e , 0x16 , 0x58 , 0x78 , 0x3a , 0xb4 , 0x1f , 0x8e , 0xf9 , 0x7c , 0x2a , 0x10 , 0xb5 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x01
}
};
#define SECP256K1_EC_PARSE_TEST_NXVALID (4)
const unsigned char onlyxvalid [ SECP256K1_EC_PARSE_TEST_NXVALID ][ 64 ] = {
{
/* Valid if y overflow ignored (y = 1 mod p). (1/3) */
0x1f , 0xe1 , 0xe5 , 0xef , 0x3f , 0xce , 0xb5 , 0xc1 , 0x35 , 0xab , 0x77 , 0x41 , 0x33 , 0x3c , 0xe5 , 0xa6 ,
0xe8 , 0x0d , 0x68 , 0x16 , 0x76 , 0x53 , 0xf6 , 0xb2 , 0xb2 , 0x4b , 0xcb , 0xcf , 0xaa , 0xaf , 0xf5 , 0x07 ,
0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff ,
0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xfe , 0xff , 0xff , 0xfc , 0x30 ,
},
{
/* Valid if y overflow ignored (y = 1 mod p). (2/3) */
0xcb , 0xb0 , 0xde , 0xab , 0x12 , 0x57 , 0x54 , 0xf1 , 0xfd , 0xb2 , 0x03 , 0x8b , 0x04 , 0x34 , 0xed , 0x9c ,
0xb3 , 0xfb , 0x53 , 0xab , 0x73 , 0x53 , 0x91 , 0x12 , 0x99 , 0x94 , 0xa5 , 0x35 , 0xd9 , 0x25 , 0xf6 , 0x73 ,
0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff ,
0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xfe , 0xff , 0xff , 0xfc , 0x30 ,
},
{
/* Valid if y overflow ignored (y = 1 mod p). (3/3)*/
0x14 , 0x6d , 0x3b , 0x65 , 0xad , 0xd9 , 0xf5 , 0x4c , 0xcc , 0xa2 , 0x85 , 0x33 , 0xc8 , 0x8e , 0x2c , 0xbc ,
0x63 , 0xf7 , 0x44 , 0x3e , 0x16 , 0x58 , 0x78 , 0x3a , 0xb4 , 0x1f , 0x8e , 0xf9 , 0x7c , 0x2a , 0x10 , 0xb5 ,
0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff ,
0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xfe , 0xff , 0xff , 0xfc , 0x30 ,
},
{
/* x on curve, y is from y^2 = x^3 + 8. */
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x01 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x03
}
};
#define SECP256K1_EC_PARSE_TEST_NINVALID (7)
const unsigned char invalid [ SECP256K1_EC_PARSE_TEST_NINVALID ][ 64 ] = {
{
/* x is third root of -8, y is -1 * (x^3+7); also on the curve for y^2 = x^3 + 9. */
0x0a , 0x2d , 0x2b , 0xa9 , 0x35 , 0x07 , 0xf1 , 0xdf , 0x23 , 0x37 , 0x70 , 0xc2 , 0xa7 , 0x97 , 0x96 , 0x2c ,
0xc6 , 0x1f , 0x6d , 0x15 , 0xda , 0x14 , 0xec , 0xd4 , 0x7d , 0x8d , 0x27 , 0xae , 0x1c , 0xd5 , 0xf8 , 0x53 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x01 ,
},
{
/* Valid if x overflow ignored (x = 1 mod p). */
0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff ,
0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xfe , 0xff , 0xff , 0xfc , 0x30 ,
0x42 , 0x18 , 0xf2 , 0x0a , 0xe6 , 0xc6 , 0x46 , 0xb3 , 0x63 , 0xdb , 0x68 , 0x60 , 0x58 , 0x22 , 0xfb , 0x14 ,
0x26 , 0x4c , 0xa8 , 0xd2 , 0x58 , 0x7f , 0xdd , 0x6f , 0xbc , 0x75 , 0x0d , 0x58 , 0x7e , 0x76 , 0xa7 , 0xee ,
},
{
/* Valid if x overflow ignored (x = 1 mod p). */
0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff ,
0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xfe , 0xff , 0xff , 0xfc , 0x30 ,
0xbd , 0xe7 , 0x0d , 0xf5 , 0x19 , 0x39 , 0xb9 , 0x4c , 0x9c , 0x24 , 0x97 , 0x9f , 0xa7 , 0xdd , 0x04 , 0xeb ,
0xd9 , 0xb3 , 0x57 , 0x2d , 0xa7 , 0x80 , 0x22 , 0x90 , 0x43 , 0x8a , 0xf2 , 0xa6 , 0x81 , 0x89 , 0x54 , 0x41 ,
},
{
/* x is -1, y is the result of the sqrt ladder; also on the curve for y^2 = x^3 - 5. */
0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff ,
0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xfe , 0xff , 0xff , 0xfc , 0x2e ,
0xf4 , 0x84 , 0x14 , 0x5c , 0xb0 , 0x14 , 0x9b , 0x82 , 0x5d , 0xff , 0x41 , 0x2f , 0xa0 , 0x52 , 0xa8 , 0x3f ,
0xcb , 0x72 , 0xdb , 0x61 , 0xd5 , 0x6f , 0x37 , 0x70 , 0xce , 0x06 , 0x6b , 0x73 , 0x49 , 0xa2 , 0xaa , 0x28 ,
},
{
/* x is -1, y is the result of the sqrt ladder; also on the curve for y^2 = x^3 - 5. */
0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff ,
0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xfe , 0xff , 0xff , 0xfc , 0x2e ,
0x0b , 0x7b , 0xeb , 0xa3 , 0x4f , 0xeb , 0x64 , 0x7d , 0xa2 , 0x00 , 0xbe , 0xd0 , 0x5f , 0xad , 0x57 , 0xc0 ,
0x34 , 0x8d , 0x24 , 0x9e , 0x2a , 0x90 , 0xc8 , 0x8f , 0x31 , 0xf9 , 0x94 , 0x8b , 0xb6 , 0x5d , 0x52 , 0x07 ,
},
{
/* x is zero, y is the result of the sqrt ladder; also on the curve for y^2 = x^3 - 7. */
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x8f , 0x53 , 0x7e , 0xef , 0xdf , 0xc1 , 0x60 , 0x6a , 0x07 , 0x27 , 0xcd , 0x69 , 0xb4 , 0xa7 , 0x33 , 0x3d ,
0x38 , 0xed , 0x44 , 0xe3 , 0x93 , 0x2a , 0x71 , 0x79 , 0xee , 0xcb , 0x4b , 0x6f , 0xba , 0x93 , 0x60 , 0xdc ,
},
{
/* x is zero, y is the result of the sqrt ladder; also on the curve for y^2 = x^3 - 7. */
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x70 , 0xac , 0x81 , 0x10 , 0x20 , 0x3e , 0x9f , 0x95 , 0xf8 , 0xd8 , 0x32 , 0x96 , 0x4b , 0x58 , 0xcc , 0xc2 ,
0xc7 , 0x12 , 0xbb , 0x1c , 0x6c , 0xd5 , 0x8e , 0x86 , 0x11 , 0x34 , 0xb4 , 0x8f , 0x45 , 0x6c , 0x9b , 0x53
}
};
const unsigned char pubkeyc [ 66 ] = {
/* Serialization of G. */
0x04 , 0x79 , 0xBE , 0x66 , 0x7E , 0xF9 , 0xDC , 0xBB , 0xAC , 0x55 , 0xA0 , 0x62 , 0x95 , 0xCE , 0x87 , 0x0B ,
0x07 , 0x02 , 0x9B , 0xFC , 0xDB , 0x2D , 0xCE , 0x28 , 0xD9 , 0x59 , 0xF2 , 0x81 , 0x5B , 0x16 , 0xF8 , 0x17 ,
0x98 , 0x48 , 0x3A , 0xDA , 0x77 , 0x26 , 0xA3 , 0xC4 , 0x65 , 0x5D , 0xA4 , 0xFB , 0xFC , 0x0E , 0x11 , 0x08 ,
0xA8 , 0xFD , 0x17 , 0xB4 , 0x48 , 0xA6 , 0x85 , 0x54 , 0x19 , 0x9C , 0x47 , 0xD0 , 0x8F , 0xFB , 0x10 , 0xD4 ,
0xB8 , 0x00
};
unsigned char shortkey [ 2 ];
secp256k1_ge ge ;
secp256k1_pubkey pubkey ;
int32_t i ;
int32_t ecount ;
int32_t ecount2 ;
ecount = 0 ;
/* Nothing should be reading this far into pubkeyc. */
VG_UNDEF ( & pubkeyc [ 65 ], 1 );
secp256k1_context_set_illegal_callback ( ctx , counting_illegal_callback_fn , & ecount );
/* Zero length claimed, fail, zeroize, no illegal arg error. */
memset ( & pubkey , 0xfe , sizeof ( pubkey ));
ecount = 0 ;
VG_UNDEF ( shortkey , 2 );
VG_UNDEF ( & pubkey , sizeof ( pubkey ));
CHECK ( secp256k1_ec_pubkey_parse ( ctx , & pubkey , shortkey , 0 ) == 0 );
VG_CHECK ( & pubkey , sizeof ( pubkey ));
CHECK ( ecount == 0 );
CHECK ( secp256k1_pubkey_load ( ctx , & ge , & pubkey ) == 0 );
CHECK ( ecount == 1 );
/* Length one claimed, fail, zeroize, no illegal arg error. */
for ( i = 0 ; i < 256 ; i ++ ) {
memset ( & pubkey , 0xfe , sizeof ( pubkey ));
ecount = 0 ;
shortkey [ 0 ] = i ;
VG_UNDEF ( & shortkey [ 1 ], 1 );
VG_UNDEF ( & pubkey , sizeof ( pubkey ));
CHECK ( secp256k1_ec_pubkey_parse ( ctx , & pubkey , shortkey , 1 ) == 0 );
VG_CHECK ( & pubkey , sizeof ( pubkey ));
CHECK ( ecount == 0 );
CHECK ( secp256k1_pubkey_load ( ctx , & ge , & pubkey ) == 0 );
CHECK ( ecount == 1 );
}
/* Length two claimed, fail, zeroize, no illegal arg error. */
for ( i = 0 ; i < 65536 ; i ++ ) {
memset ( & pubkey , 0xfe , sizeof ( pubkey ));
ecount = 0 ;
shortkey [ 0 ] = i & 255 ;
shortkey [ 1 ] = i >> 8 ;
VG_UNDEF ( & pubkey , sizeof ( pubkey ));
CHECK ( secp256k1_ec_pubkey_parse ( ctx , & pubkey , shortkey , 2 ) == 0 );
VG_CHECK ( & pubkey , sizeof ( pubkey ));
CHECK ( ecount == 0 );
CHECK ( secp256k1_pubkey_load ( ctx , & ge , & pubkey ) == 0 );
CHECK ( ecount == 1 );
}
memset ( & pubkey , 0xfe , sizeof ( pubkey ));
ecount = 0 ;
VG_UNDEF ( & pubkey , sizeof ( pubkey ));
/* 33 bytes claimed on otherwise valid input starting with 0x04, fail, zeroize output, no illegal arg error. */
CHECK ( secp256k1_ec_pubkey_parse ( ctx , & pubkey , pubkeyc , 33 ) == 0 );
VG_CHECK ( & pubkey , sizeof ( pubkey ));
CHECK ( ecount == 0 );
CHECK ( secp256k1_pubkey_load ( ctx , & ge , & pubkey ) == 0 );
CHECK ( ecount == 1 );
/* NULL pubkey, illegal arg error. Pubkey isn't rewritten before this step, since it's NULL into the parser. */
CHECK ( secp256k1_ec_pubkey_parse ( ctx , NULL , pubkeyc , 65 ) == 0 );
CHECK ( ecount == 2 );
/* NULL input string. Illegal arg and zeroize output. */
memset ( & pubkey , 0xfe , sizeof ( pubkey ));
ecount = 0 ;
VG_UNDEF ( & pubkey , sizeof ( pubkey ));
CHECK ( secp256k1_ec_pubkey_parse ( ctx , & pubkey , NULL , 65 ) == 0 );
VG_CHECK ( & pubkey , sizeof ( pubkey ));
CHECK ( ecount == 1 );
CHECK ( secp256k1_pubkey_load ( ctx , & ge , & pubkey ) == 0 );
CHECK ( ecount == 2 );
/* 64 bytes claimed on input starting with 0x04, fail, zeroize output, no illegal arg error. */
memset ( & pubkey , 0xfe , sizeof ( pubkey ));
ecount = 0 ;
VG_UNDEF ( & pubkey , sizeof ( pubkey ));
CHECK ( secp256k1_ec_pubkey_parse ( ctx , & pubkey , pubkeyc , 64 ) == 0 );
VG_CHECK ( & pubkey , sizeof ( pubkey ));
CHECK ( ecount == 0 );
CHECK ( secp256k1_pubkey_load ( ctx , & ge , & pubkey ) == 0 );
CHECK ( ecount == 1 );
/* 66 bytes claimed, fail, zeroize output, no illegal arg error. */
memset ( & pubkey , 0xfe , sizeof ( pubkey ));
ecount = 0 ;
VG_UNDEF ( & pubkey , sizeof ( pubkey ));
CHECK ( secp256k1_ec_pubkey_parse ( ctx , & pubkey , pubkeyc , 66 ) == 0 );
VG_CHECK ( & pubkey , sizeof ( pubkey ));
CHECK ( ecount == 0 );
CHECK ( secp256k1_pubkey_load ( ctx , & ge , & pubkey ) == 0 );
CHECK ( ecount == 1 );
/* Valid parse. */
memset ( & pubkey , 0 , sizeof ( pubkey ));
ecount = 0 ;
VG_UNDEF ( & pubkey , sizeof ( pubkey ));
CHECK ( secp256k1_ec_pubkey_parse ( ctx , & pubkey , pubkeyc , 65 ) == 1 );
VG_CHECK ( & pubkey , sizeof ( pubkey ));
CHECK ( ecount == 0 );
VG_UNDEF ( & ge , sizeof ( ge ));
CHECK ( secp256k1_pubkey_load ( ctx , & ge , & pubkey ) == 1 );
VG_CHECK ( & ge . x , sizeof ( ge . x ));
VG_CHECK ( & ge . y , sizeof ( ge . y ));
VG_CHECK ( & ge . infinity , sizeof ( ge . infinity ));
ge_equals_ge ( & secp256k1_ge_const_g , & ge );
CHECK ( ecount == 0 );
/* Multiple illegal args. Should still set arg error only once. */
ecount = 0 ;
ecount2 = 11 ;
CHECK ( secp256k1_ec_pubkey_parse ( ctx , NULL , NULL , 65 ) == 0 );
CHECK ( ecount == 1 );
/* Does the illegal arg callback actually change the behavior? */
secp256k1_context_set_illegal_callback ( ctx , uncounting_illegal_callback_fn , & ecount2 );
CHECK ( secp256k1_ec_pubkey_parse ( ctx , NULL , NULL , 65 ) == 0 );
CHECK ( ecount == 1 );
CHECK ( ecount2 == 10 );
secp256k1_context_set_illegal_callback ( ctx , NULL , NULL );
/* Try a bunch of prefabbed points with all possible encodings. */
for ( i = 0 ; i < SECP256K1_EC_PARSE_TEST_NVALID ; i ++ ) {
ec_pubkey_parse_pointtest ( valid [ i ], 1 , 1 );
}
for ( i = 0 ; i < SECP256K1_EC_PARSE_TEST_NXVALID ; i ++ ) {
ec_pubkey_parse_pointtest ( onlyxvalid [ i ], 1 , 0 );
}
for ( i = 0 ; i < SECP256K1_EC_PARSE_TEST_NINVALID ; i ++ ) {
ec_pubkey_parse_pointtest ( invalid [ i ], 0 , 0 );
}
}
2015-09-21 20:57:54 +02:00
void random_sign ( secp256k1_scalar * sigr , secp256k1_scalar * sigs , const secp256k1_scalar * key , const secp256k1_scalar * msg , int * recid ) {
secp256k1_scalar nonce ;
2013-05-05 16:55:05 +02:00
do {
2014-10-28 04:08:15 -07:00
random_scalar_order_test ( & nonce );
2015-07-26 16:51:58 +02:00
} while ( ! secp256k1_ecdsa_sig_sign ( & ctx -> ecmult_gen_ctx , sigr , sigs , key , msg , & nonce , recid ));
2013-05-05 16:55:05 +02:00
}
2014-11-12 13:24:12 -08:00
void test_ecdsa_sign_verify ( void ) {
2015-09-21 20:57:54 +02:00
secp256k1_gej pubj ;
secp256k1_ge pub ;
secp256k1_scalar one ;
secp256k1_scalar msg , key ;
secp256k1_scalar sigr , sigs ;
2014-12-04 01:04:00 -08:00
int recid ;
int getrec ;
2014-10-28 04:08:15 -07:00
random_scalar_order_test ( & msg );
random_scalar_order_test ( & key );
2015-02-03 17:27:00 -08:00
secp256k1_ecmult_gen ( & ctx -> ecmult_gen_ctx , & pubj , & key );
2015-01-25 15:47:04 +00:00
secp256k1_ge_set_gej ( & pub , & pubj );
2015-10-17 21:15:15 +02:00
getrec = secp256k1_rand_bits ( 1 );
2015-07-26 16:51:58 +02:00
random_sign ( & sigr , & sigs , & key , & msg , getrec ?& recid : NULL );
2015-03-27 23:14:17 +00:00
if ( getrec ) {
CHECK ( recid >= 0 && recid < 4 );
}
2015-07-26 16:51:58 +02:00
CHECK ( secp256k1_ecdsa_sig_verify ( & ctx -> ecmult_ctx , & sigr , & sigs , & pub , & msg ));
2014-11-26 17:26:39 +01:00
secp256k1_scalar_set_int ( & one , 1 );
secp256k1_scalar_add ( & msg , & msg , & one );
2015-07-26 16:51:58 +02:00
CHECK ( ! secp256k1_ecdsa_sig_verify ( & ctx -> ecmult_ctx , & sigr , & sigs , & pub , & msg ));
2013-03-18 02:41:01 +01:00
}
2014-11-12 13:24:12 -08:00
void run_ecdsa_sign_verify ( void ) {
2015-01-25 15:47:04 +00:00
int i ;
for ( i = 0 ; i < 10 * count ; i ++ ) {
2013-03-18 02:41:01 +01:00
test_ecdsa_sign_verify ();
}
}
2014-12-12 18:11:39 +01:00
/** Dummy nonce generation function that just uses a precomputed nonce, and fails if it is not accepted. Use only for testing. */
2015-09-01 05:48:58 +00:00
static int precomputed_nonce_function ( unsigned char * nonce32 , const unsigned char * msg32 , const unsigned char * key32 , const unsigned char * algo16 , void * data , unsigned int counter ) {
2014-12-12 18:11:39 +01:00
( void ) msg32 ;
( void ) key32 ;
2015-07-24 15:44:49 +02:00
( void ) algo16 ;
2014-12-12 18:11:39 +01:00
memcpy ( nonce32 , data , 32 );
return ( counter == 0 );
}
2015-09-01 05:48:58 +00:00
static int nonce_function_test_fail ( unsigned char * nonce32 , const unsigned char * msg32 , const unsigned char * key32 , const unsigned char * algo16 , void * data , unsigned int counter ) {
2015-01-04 17:26:51 -08:00
/* Dummy nonce generator that has a fatal error on the first counter value. */
2015-03-27 23:14:17 +00:00
if ( counter == 0 ) {
return 0 ;
}
2015-08-28 01:50:47 +02:00
return nonce_function_rfc6979 ( nonce32 , msg32 , key32 , algo16 , data , counter - 1 );
2015-01-04 17:26:51 -08:00
}
2015-09-01 05:48:58 +00:00
static int nonce_function_test_retry ( unsigned char * nonce32 , const unsigned char * msg32 , const unsigned char * key32 , const unsigned char * algo16 , void * data , unsigned int counter ) {
2015-01-04 17:26:51 -08:00
/* Dummy nonce generator that produces unacceptable nonces for the first several counter values. */
if ( counter < 3 ) {
memset ( nonce32 , counter == 0 ? 0 : 255 , 32 );
2015-03-27 23:14:17 +00:00
if ( counter == 2 ) {
nonce32 [ 31 ] -- ;
}
2015-01-04 17:26:51 -08:00
return 1 ;
}
if ( counter < 5 ) {
static const unsigned char order [] = {
0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFE ,
0xBA , 0xAE , 0xDC , 0xE6 , 0xAF , 0x48 , 0xA0 , 0x3B ,
0xBF , 0xD2 , 0x5E , 0x8C , 0xD0 , 0x36 , 0x41 , 0x41
};
memcpy ( nonce32 , order , 32 );
2015-03-27 23:14:17 +00:00
if ( counter == 4 ) {
nonce32 [ 31 ] ++ ;
}
2015-01-04 17:26:51 -08:00
return 1 ;
}
/* Retry rate of 6979 is negligible esp. as we only call this in determinstic tests. */
/* If someone does fine a case where it retries for secp256k1, we'd like to know. */
2015-03-27 23:14:17 +00:00
if ( counter > 5 ) {
return 0 ;
}
2015-08-28 01:50:47 +02:00
return nonce_function_rfc6979 ( nonce32 , msg32 , key32 , algo16 , data , counter - 5 );
2015-01-04 17:26:51 -08:00
}
2015-09-21 20:57:54 +02:00
int is_empty_signature ( const secp256k1_ecdsa_signature * sig ) {
static const unsigned char res [ sizeof ( secp256k1_ecdsa_signature )] = { 0 };
return memcmp ( sig , res , sizeof ( secp256k1_ecdsa_signature )) == 0 ;
2015-02-12 18:00:50 -08:00
}
2014-11-12 13:24:12 -08:00
void test_ecdsa_end_to_end ( void ) {
2015-03-27 11:55:17 +00:00
unsigned char extra [ 32 ] = { 0x00 };
2014-08-03 19:54:41 +02:00
unsigned char privkey [ 32 ];
unsigned char message [ 32 ];
2015-01-25 15:47:04 +00:00
unsigned char privkey2 [ 32 ];
2015-10-14 18:54:32 +02:00
secp256k1_ecdsa_signature signature [ 6 ];
secp256k1_scalar r , s ;
2015-07-26 16:00:55 +02:00
unsigned char sig [ 74 ];
2015-09-01 04:35:10 +00:00
size_t siglen = 74 ;
2015-07-20 13:36:55 -04:00
unsigned char pubkeyc [ 65 ];
2015-09-01 04:35:10 +00:00
size_t pubkeyclen = 65 ;
2015-09-21 20:57:54 +02:00
secp256k1_pubkey pubkey ;
2015-01-25 15:47:04 +00:00
unsigned char seckey [ 300 ];
2015-09-01 04:35:10 +00:00
size_t seckeylen = 300 ;
2014-08-03 19:54:41 +02:00
2014-11-15 15:28:10 +00:00
/* Generate a random key and message. */
2014-08-03 19:54:41 +02:00
{
2015-09-21 20:57:54 +02:00
secp256k1_scalar msg , key ;
2014-11-27 19:12:13 +01:00
random_scalar_order_test ( & msg );
random_scalar_order_test ( & key );
secp256k1_scalar_get_b32 ( privkey , & key );
secp256k1_scalar_get_b32 ( message , & msg );
2014-08-03 19:54:41 +02:00
}
2014-11-15 15:28:10 +00:00
/* Construct and verify corresponding public key. */
2015-02-03 17:27:00 -08:00
CHECK ( secp256k1_ec_seckey_verify ( ctx , privkey ) == 1 );
2015-07-20 13:36:55 -04:00
CHECK ( secp256k1_ec_pubkey_create ( ctx , & pubkey , privkey ) == 1 );
2015-07-13 13:09:00 +01:00
2015-07-20 13:36:55 -04:00
/* Verify exporting and importing public key. */
2015-10-17 21:15:15 +02:00
CHECK ( secp256k1_ec_pubkey_serialize ( ctx , pubkeyc , & pubkeyclen , & pubkey , secp256k1_rand_bits ( 1 )) == 1 );
2015-07-20 13:36:55 -04:00
memset ( & pubkey , 0 , sizeof ( pubkey ));
CHECK ( secp256k1_ec_pubkey_parse ( ctx , & pubkey , pubkeyc , pubkeyclen ) == 1 );
2014-08-03 19:54:41 +02:00
2014-11-15 15:28:10 +00:00
/* Verify private key import and export. */
2015-10-17 21:15:15 +02:00
CHECK ( secp256k1_ec_privkey_export ( ctx , seckey , & seckeylen , privkey , secp256k1_rand_bits ( 1 ) == 1 ) ? SECP256K1_EC_COMPRESSED : 0 );
2015-02-03 17:27:00 -08:00
CHECK ( secp256k1_ec_privkey_import ( ctx , privkey2 , seckey , seckeylen ) == 1 );
2014-08-03 19:54:41 +02:00
CHECK ( memcmp ( privkey , privkey2 , 32 ) == 0 );
2014-11-15 15:28:10 +00:00
/* Optionally tweak the keys using addition. */
2015-10-17 21:15:15 +02:00
if ( secp256k1_rand_int ( 3 ) == 0 ) {
2015-01-25 15:47:04 +00:00
int ret1 ;
int ret2 ;
2014-08-03 19:54:41 +02:00
unsigned char rnd [ 32 ];
2015-09-21 20:57:54 +02:00
secp256k1_pubkey pubkey2 ;
2014-08-03 19:54:41 +02:00
secp256k1_rand256_test ( rnd );
2015-02-03 17:27:00 -08:00
ret1 = secp256k1_ec_privkey_tweak_add ( ctx , privkey , rnd );
2015-07-20 13:36:55 -04:00
ret2 = secp256k1_ec_pubkey_tweak_add ( ctx , & pubkey , rnd );
2014-08-03 19:54:41 +02:00
CHECK ( ret1 == ret2 );
2015-03-27 23:14:17 +00:00
if ( ret1 == 0 ) {
return ;
}
2015-07-20 13:36:55 -04:00
CHECK ( secp256k1_ec_pubkey_create ( ctx , & pubkey2 , privkey ) == 1 );
CHECK ( memcmp ( & pubkey , & pubkey2 , sizeof ( pubkey )) == 0 );
2014-08-03 19:54:41 +02:00
}
2014-11-15 15:28:10 +00:00
/* Optionally tweak the keys using multiplication. */
2015-10-17 21:15:15 +02:00
if ( secp256k1_rand_int ( 3 ) == 0 ) {
2015-01-25 15:47:04 +00:00
int ret1 ;
int ret2 ;
2014-08-03 19:54:41 +02:00
unsigned char rnd [ 32 ];
2015-09-21 20:57:54 +02:00
secp256k1_pubkey pubkey2 ;
2014-08-03 19:54:41 +02:00
secp256k1_rand256_test ( rnd );
2015-02-03 17:27:00 -08:00
ret1 = secp256k1_ec_privkey_tweak_mul ( ctx , privkey , rnd );
2015-07-20 13:36:55 -04:00
ret2 = secp256k1_ec_pubkey_tweak_mul ( ctx , & pubkey , rnd );
2014-08-03 19:54:41 +02:00
CHECK ( ret1 == ret2 );
2015-03-27 23:14:17 +00:00
if ( ret1 == 0 ) {
return ;
}
2015-07-20 13:36:55 -04:00
CHECK ( secp256k1_ec_pubkey_create ( ctx , & pubkey2 , privkey ) == 1 );
CHECK ( memcmp ( & pubkey , & pubkey2 , sizeof ( pubkey )) == 0 );
2014-08-03 19:54:41 +02:00
}
2014-11-15 15:28:10 +00:00
/* Sign. */
2015-08-28 01:50:47 +02:00
CHECK ( secp256k1_ecdsa_sign ( ctx , & signature [ 0 ], message , privkey , NULL , NULL ) == 1 );
CHECK ( secp256k1_ecdsa_sign ( ctx , & signature [ 4 ], message , privkey , NULL , NULL ) == 1 );
CHECK ( secp256k1_ecdsa_sign ( ctx , & signature [ 1 ], message , privkey , NULL , extra ) == 1 );
2015-03-27 11:55:17 +00:00
extra [ 31 ] = 1 ;
2015-08-28 01:50:47 +02:00
CHECK ( secp256k1_ecdsa_sign ( ctx , & signature [ 2 ], message , privkey , NULL , extra ) == 1 );
2015-03-27 11:55:17 +00:00
extra [ 31 ] = 0 ;
extra [ 0 ] = 1 ;
2015-08-28 01:50:47 +02:00
CHECK ( secp256k1_ecdsa_sign ( ctx , & signature [ 3 ], message , privkey , NULL , extra ) == 1 );
2015-07-26 16:00:55 +02:00
CHECK ( memcmp ( & signature [ 0 ], & signature [ 4 ], sizeof ( signature [ 0 ])) == 0 );
CHECK ( memcmp ( & signature [ 0 ], & signature [ 1 ], sizeof ( signature [ 0 ])) != 0 );
CHECK ( memcmp ( & signature [ 0 ], & signature [ 2 ], sizeof ( signature [ 0 ])) != 0 );
CHECK ( memcmp ( & signature [ 0 ], & signature [ 3 ], sizeof ( signature [ 0 ])) != 0 );
CHECK ( memcmp ( & signature [ 1 ], & signature [ 2 ], sizeof ( signature [ 0 ])) != 0 );
CHECK ( memcmp ( & signature [ 1 ], & signature [ 3 ], sizeof ( signature [ 0 ])) != 0 );
CHECK ( memcmp ( & signature [ 2 ], & signature [ 3 ], sizeof ( signature [ 0 ])) != 0 );
2014-11-15 15:28:10 +00:00
/* Verify. */
2015-08-28 01:50:47 +02:00
CHECK ( secp256k1_ecdsa_verify ( ctx , & signature [ 0 ], message , & pubkey ) == 1 );
CHECK ( secp256k1_ecdsa_verify ( ctx , & signature [ 1 ], message , & pubkey ) == 1 );
CHECK ( secp256k1_ecdsa_verify ( ctx , & signature [ 2 ], message , & pubkey ) == 1 );
CHECK ( secp256k1_ecdsa_verify ( ctx , & signature [ 3 ], message , & pubkey ) == 1 );
2015-10-14 18:54:32 +02:00
/* Test lower-S form, malleate, verify and fail, test again, malleate again */
CHECK ( ! secp256k1_ecdsa_signature_normalize ( ctx , NULL , & signature [ 0 ]));
secp256k1_ecdsa_signature_load ( ctx , & r , & s , & signature [ 0 ]);
secp256k1_scalar_negate ( & s , & s );
secp256k1_ecdsa_signature_save ( & signature [ 5 ], & r , & s );
CHECK ( secp256k1_ecdsa_verify ( ctx , & signature [ 5 ], message , & pubkey ) == 0 );
CHECK ( secp256k1_ecdsa_signature_normalize ( ctx , NULL , & signature [ 5 ]));
CHECK ( secp256k1_ecdsa_signature_normalize ( ctx , & signature [ 5 ], & signature [ 5 ]));
CHECK ( ! secp256k1_ecdsa_signature_normalize ( ctx , NULL , & signature [ 5 ]));
CHECK ( secp256k1_ecdsa_verify ( ctx , & signature [ 5 ], message , & pubkey ) == 1 );
secp256k1_scalar_negate ( & s , & s );
secp256k1_ecdsa_signature_save ( & signature [ 5 ], & r , & s );
CHECK ( ! secp256k1_ecdsa_signature_normalize ( ctx , NULL , & signature [ 5 ]));
CHECK ( secp256k1_ecdsa_verify ( ctx , & signature [ 5 ], message , & pubkey ) == 1 );
CHECK ( memcmp ( & signature [ 5 ], & signature [ 0 ], 64 ) == 0 );
2015-07-26 16:00:55 +02:00
/* Serialize/parse DER and verify again */
CHECK ( secp256k1_ecdsa_signature_serialize_der ( ctx , sig , & siglen , & signature [ 0 ]) == 1 );
memset ( & signature [ 0 ], 0 , sizeof ( signature [ 0 ]));
CHECK ( secp256k1_ecdsa_signature_parse_der ( ctx , & signature [ 0 ], sig , siglen ) == 1 );
2015-08-28 01:50:47 +02:00
CHECK ( secp256k1_ecdsa_verify ( ctx , & signature [ 0 ], message , & pubkey ) == 1 );
2015-07-26 16:00:55 +02:00
/* Serialize/destroy/parse DER and verify again. */
2015-09-01 04:52:35 +00:00
siglen = 74 ;
2015-07-26 16:00:55 +02:00
CHECK ( secp256k1_ecdsa_signature_serialize_der ( ctx , sig , & siglen , & signature [ 0 ]) == 1 );
2015-10-17 21:15:15 +02:00
sig [ secp256k1_rand_int ( siglen )] += 1 + secp256k1_rand_int ( 255 );
2015-07-26 16:00:55 +02:00
CHECK ( secp256k1_ecdsa_signature_parse_der ( ctx , & signature [ 0 ], sig , siglen ) == 0 ||
2015-08-28 01:50:47 +02:00
secp256k1_ecdsa_verify ( ctx , & signature [ 0 ], message , & pubkey ) == 0 );
2015-08-27 03:19:27 +02:00
}
2014-12-08 12:38:16 -08:00
void test_random_pubkeys ( void ) {
2015-09-21 20:57:54 +02:00
secp256k1_ge elem ;
secp256k1_ge elem2 ;
2014-12-08 12:38:16 -08:00
unsigned char in [ 65 ];
/* Generate some randomly sized pubkeys. */
2015-10-17 21:15:15 +02:00
size_t len = secp256k1_rand_bits ( 2 ) == 0 ? 65 : 33 ;
if ( secp256k1_rand_bits ( 2 ) == 0 ) {
len = secp256k1_rand_bits ( 6 );
2015-03-27 23:14:17 +00:00
}
2014-12-08 12:38:16 -08:00
if ( len == 65 ) {
2015-10-17 21:15:15 +02:00
in [ 0 ] = secp256k1_rand_bits ( 1 ) ? 4 : ( secp256k1_rand_bits ( 1 ) ? 6 : 7 );
2014-12-08 12:38:16 -08:00
} else {
2015-10-17 21:15:15 +02:00
in [ 0 ] = secp256k1_rand_bits ( 1 ) ? 2 : 3 ;
2014-12-08 12:38:16 -08:00
}
2015-10-17 21:15:15 +02:00
if ( secp256k1_rand_bits ( 3 ) == 0 ) {
in [ 0 ] = secp256k1_rand_bits ( 8 );
2015-03-27 23:14:17 +00:00
}
if ( len > 1 ) {
secp256k1_rand256 ( & in [ 1 ]);
}
if ( len > 33 ) {
secp256k1_rand256 ( & in [ 33 ]);
}
2014-12-08 12:38:16 -08:00
if ( secp256k1_eckey_pubkey_parse ( & elem , in , len )) {
unsigned char out [ 65 ];
unsigned char firstb ;
int res ;
2015-09-01 04:35:10 +00:00
size_t size = len ;
2014-12-08 12:38:16 -08:00
firstb = in [ 0 ];
/* If the pubkey can be parsed, it should round-trip... */
2015-09-01 06:00:35 +00:00
CHECK ( secp256k1_eckey_pubkey_serialize ( & elem , out , & size , ( len == 33 ) ? SECP256K1_EC_COMPRESSED : 0 ));
2014-12-08 12:38:16 -08:00
CHECK ( size == len );
CHECK ( memcmp ( & in [ 1 ], & out [ 1 ], len - 1 ) == 0 );
/* ... except for the type of hybrid inputs. */
2015-03-27 23:14:17 +00:00
if (( in [ 0 ] != 6 ) && ( in [ 0 ] != 7 )) {
CHECK ( in [ 0 ] == out [ 0 ]);
}
2014-12-08 12:38:16 -08:00
size = 65 ;
CHECK ( secp256k1_eckey_pubkey_serialize ( & elem , in , & size , 0 ));
CHECK ( size == 65 );
CHECK ( secp256k1_eckey_pubkey_parse ( & elem2 , in , size ));
2014-12-29 15:38:17 +01:00
ge_equals_ge ( & elem , & elem2 );
2014-12-08 12:38:16 -08:00
/* Check that the X9.62 hybrid type is checked. */
2015-10-17 21:15:15 +02:00
in [ 0 ] = secp256k1_rand_bits ( 1 ) ? 6 : 7 ;
2014-12-08 12:38:16 -08:00
res = secp256k1_eckey_pubkey_parse ( & elem2 , in , size );
if ( firstb == 2 || firstb == 3 ) {
2015-03-27 23:14:17 +00:00
if ( in [ 0 ] == firstb + 4 ) {
CHECK ( res );
} else {
CHECK ( ! res );
}
2014-12-08 12:38:16 -08:00
}
if ( res ) {
2014-12-29 15:38:17 +01:00
ge_equals_ge ( & elem , & elem2 );
2014-12-08 12:38:16 -08:00
CHECK ( secp256k1_eckey_pubkey_serialize ( & elem , out , & size , 0 ));
CHECK ( memcmp ( & in [ 1 ], & out [ 1 ], 64 ) == 0 );
}
}
}
void run_random_pubkeys ( void ) {
2015-01-25 15:47:04 +00:00
int i ;
for ( i = 0 ; i < 10 * count ; i ++ ) {
2014-12-08 12:38:16 -08:00
test_random_pubkeys ();
}
}
2014-11-12 13:24:12 -08:00
void run_ecdsa_end_to_end ( void ) {
2015-01-25 15:47:04 +00:00
int i ;
for ( i = 0 ; i < 64 * count ; i ++ ) {
2014-08-03 19:54:41 +02:00
test_ecdsa_end_to_end ();
}
}
2015-09-28 17:40:21 +02:00
int test_ecdsa_der_parse ( const unsigned char * sig , size_t siglen , int certainly_der , int certainly_not_der ) {
static const unsigned char zeroes [ 32 ] = { 0 };
static const unsigned char max_scalar [ 32 ] = {
0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff ,
0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xfe ,
0xba , 0xae , 0xdc , 0xe6 , 0xaf , 0x48 , 0xa0 , 0x3b ,
0xbf , 0xd2 , 0x5e , 0x8c , 0xd0 , 0x36 , 0x41 , 0x40
};
int ret = 0 ;
secp256k1_ecdsa_signature sig_der ;
unsigned char roundtrip_der [ 2048 ];
unsigned char compact_der [ 64 ];
size_t len_der = 2048 ;
int parsed_der = 0 , valid_der = 0 , roundtrips_der = 0 ;
2015-10-14 17:43:20 +02:00
secp256k1_ecdsa_signature sig_der_lax ;
unsigned char roundtrip_der_lax [ 2048 ];
unsigned char compact_der_lax [ 64 ];
size_t len_der_lax = 2048 ;
int parsed_der_lax = 0 , valid_der_lax = 0 , roundtrips_der_lax = 0 ;
2015-09-28 17:40:21 +02:00
#ifdef ENABLE_OPENSSL_TESTS
ECDSA_SIG * sig_openssl ;
const unsigned char * sigptr ;
unsigned char roundtrip_openssl [ 2048 ];
int len_openssl = 2048 ;
int parsed_openssl , valid_openssl = 0 , roundtrips_openssl = 0 ;
#endif
parsed_der = secp256k1_ecdsa_signature_parse_der ( ctx , & sig_der , sig , siglen );
if ( parsed_der ) {
ret |= ( ! secp256k1_ecdsa_signature_serialize_compact ( ctx , compact_der , & sig_der )) << 0 ;
valid_der = ( memcmp ( compact_der , zeroes , 32 ) != 0 ) && ( memcmp ( compact_der + 32 , zeroes , 32 ) != 0 );
}
if ( valid_der ) {
ret |= ( ! secp256k1_ecdsa_signature_serialize_der ( ctx , roundtrip_der , & len_der , & sig_der )) << 1 ;
roundtrips_der = ( len_der == siglen ) && memcmp ( roundtrip_der , sig , siglen ) == 0 ;
}
2015-10-14 17:43:20 +02:00
parsed_der_lax = secp256k1_ecdsa_signature_parse_der_lax ( ctx , & sig_der_lax , sig , siglen );
if ( parsed_der_lax ) {
ret |= ( ! secp256k1_ecdsa_signature_serialize_compact ( ctx , compact_der_lax , & sig_der_lax )) << 10 ;
valid_der_lax = ( memcmp ( compact_der_lax , zeroes , 32 ) != 0 ) && ( memcmp ( compact_der_lax + 32 , zeroes , 32 ) != 0 );
}
if ( valid_der_lax ) {
ret |= ( ! secp256k1_ecdsa_signature_serialize_der ( ctx , roundtrip_der_lax , & len_der_lax , & sig_der_lax )) << 11 ;
roundtrips_der_lax = ( len_der_lax == siglen ) && memcmp ( roundtrip_der_lax , sig , siglen ) == 0 ;
}
2015-09-28 17:40:21 +02:00
if ( certainly_der ) {
ret |= ( ! parsed_der ) << 2 ;
}
if ( certainly_not_der ) {
ret |= ( parsed_der ) << 17 ;
}
if ( valid_der ) {
ret |= ( ! roundtrips_der ) << 3 ;
}
2015-10-14 17:43:20 +02:00
if ( valid_der ) {
ret |= ( ! roundtrips_der_lax ) << 12 ;
ret |= ( len_der != len_der_lax ) << 13 ;
ret |= ( memcmp ( roundtrip_der_lax , roundtrip_der , len_der ) != 0 ) << 14 ;
}
ret |= ( roundtrips_der != roundtrips_der_lax ) << 15 ;
if ( parsed_der ) {
ret |= ( ! parsed_der_lax ) << 16 ;
}
2015-09-28 17:40:21 +02:00
#ifdef ENABLE_OPENSSL_TESTS
sig_openssl = ECDSA_SIG_new ();
sigptr = sig ;
parsed_openssl = ( d2i_ECDSA_SIG ( & sig_openssl , & sigptr , siglen ) != NULL );
if ( parsed_openssl ) {
valid_openssl = ! BN_is_negative ( sig_openssl -> r ) && ! BN_is_negative ( sig_openssl -> s ) && BN_num_bits ( sig_openssl -> r ) > 0 && BN_num_bits ( sig_openssl -> r ) <= 256 && BN_num_bits ( sig_openssl -> s ) > 0 && BN_num_bits ( sig_openssl -> s ) <= 256 ;
if ( valid_openssl ) {
unsigned char tmp [ 32 ] = { 0 };
BN_bn2bin ( sig_openssl -> r , tmp + 32 - BN_num_bytes ( sig_openssl -> r ));
valid_openssl = memcmp ( tmp , max_scalar , 32 ) < 0 ;
}
if ( valid_openssl ) {
unsigned char tmp [ 32 ] = { 0 };
BN_bn2bin ( sig_openssl -> s , tmp + 32 - BN_num_bytes ( sig_openssl -> s ));
valid_openssl = memcmp ( tmp , max_scalar , 32 ) < 0 ;
}
}
len_openssl = i2d_ECDSA_SIG ( sig_openssl , NULL );
if ( len_openssl <= 2048 ) {
unsigned char * ptr = roundtrip_openssl ;
CHECK ( i2d_ECDSA_SIG ( sig_openssl , & ptr ) == len_openssl );
roundtrips_openssl = valid_openssl && (( size_t ) len_openssl == siglen ) && ( memcmp ( roundtrip_openssl , sig , siglen ) == 0 );
} else {
len_openssl = 0 ;
}
ECDSA_SIG_free ( sig_openssl );
ret |= ( parsed_der && ! parsed_openssl ) << 4 ;
ret |= ( valid_der && ! valid_openssl ) << 5 ;
ret |= ( roundtrips_openssl && ! parsed_der ) << 6 ;
ret |= ( roundtrips_der != roundtrips_openssl ) << 7 ;
if ( roundtrips_openssl ) {
ret |= ( len_der != ( size_t ) len_openssl ) << 8 ;
ret |= ( memcmp ( roundtrip_der , roundtrip_openssl , len_der ) != 0 ) << 9 ;
}
#endif
return ret ;
}
static void assign_big_endian ( unsigned char * ptr , size_t ptrlen , uint32_t val ) {
size_t i ;
for ( i = 0 ; i < ptrlen ; i ++ ) {
int shift = ptrlen - 1 - i ;
if ( shift >= 4 ) {
ptr [ i ] = 0 ;
} else {
ptr [ i ] = ( val >> shift ) & 0xFF ;
}
}
}
static void damage_array ( unsigned char * sig , size_t * len ) {
int pos ;
int action = secp256k1_rand_bits ( 3 );
if ( action < 1 ) {
/* Delete a byte. */
pos = secp256k1_rand_int ( * len );
memmove ( sig + pos , sig + pos + 1 , * len - pos - 1 );
( * len ) -- ;
return ;
} else if ( action < 2 ) {
/* Insert a byte. */
pos = secp256k1_rand_int ( 1 + * len );
memmove ( sig + pos + 1 , sig + pos , * len - pos );
sig [ pos ] = secp256k1_rand_bits ( 8 );
( * len ) ++ ;
return ;
} else if ( action < 4 ) {
/* Modify a byte. */
sig [ secp256k1_rand_int ( * len )] += 1 + secp256k1_rand_int ( 255 );
return ;
} else { /* action < 8 */
/* Modify a bit. */
sig [ secp256k1_rand_int ( * len )] ^= 1 << secp256k1_rand_bits ( 3 );
return ;
}
}
static void random_ber_signature ( unsigned char * sig , size_t * len , int * certainly_der , int * certainly_not_der ) {
int der ;
int nlow [ 2 ], nlen [ 2 ], nlenlen [ 2 ], nhbit [ 2 ], nhbyte [ 2 ], nzlen [ 2 ];
size_t tlen , elen , glen ;
int indet ;
int n ;
* len = 0 ;
der = secp256k1_rand_bits ( 2 ) == 0 ;
* certainly_der = der ;
* certainly_not_der = 0 ;
indet = der ? 0 : secp256k1_rand_int ( 10 ) == 0 ;
for ( n = 0 ; n < 2 ; n ++ ) {
/* We generate two classes of numbers: nlow==1 "low" ones (up to 32 bytes), nlow==0 "high" ones (32 bytes with 129 top bits set, or larger than 32 bytes) */
nlow [ n ] = der ? 1 : ( secp256k1_rand_bits ( 3 ) != 0 );
/* The length of the number in bytes (the first byte of which will always be nonzero) */
nlen [ n ] = nlow [ n ] ? secp256k1_rand_int ( 33 ) : 32 + secp256k1_rand_int ( 200 ) * secp256k1_rand_int ( 8 ) / 8 ;
CHECK ( nlen [ n ] <= 232 );
/* The top bit of the number. */
nhbit [ n ] = ( nlow [ n ] == 0 && nlen [ n ] == 32 ) ? 1 : ( nlen [ n ] == 0 ? 0 : secp256k1_rand_bits ( 1 ));
/* The top byte of the number (after the potential hardcoded 16 0xFF characters for "high" 32 bytes numbers) */
nhbyte [ n ] = nlen [ n ] == 0 ? 0 : ( nhbit [ n ] ? 128 + secp256k1_rand_bits ( 7 ) : 1 + secp256k1_rand_int ( 127 ));
/* The number of zero bytes in front of the number (which is 0 or 1 in case of DER, otherwise we extend up to 300 bytes) */
nzlen [ n ] = der ? (( nlen [ n ] == 0 || nhbit [ n ]) ? 1 : 0 ) : ( nlow [ n ] ? secp256k1_rand_int ( 3 ) : secp256k1_rand_int ( 300 - nlen [ n ]) * secp256k1_rand_int ( 8 ) / 8 );
if ( nzlen [ n ] > (( nlen [ n ] == 0 || nhbit [ n ]) ? 1 : 0 )) {
* certainly_not_der = 1 ;
}
CHECK ( nlen [ n ] + nzlen [ n ] <= 300 );
/* The length of the length descriptor for the number. 0 means short encoding, anything else is long encoding. */
nlenlen [ n ] = nlen [ n ] + nzlen [ n ] < 128 ? 0 : ( nlen [ n ] + nzlen [ n ] < 256 ? 1 : 2 );
if ( ! der ) {
/* nlenlen[n] max 127 bytes */
int add = secp256k1_rand_int ( 127 - nlenlen [ n ]) * secp256k1_rand_int ( 16 ) * secp256k1_rand_int ( 16 ) / 256 ;
nlenlen [ n ] += add ;
if ( add != 0 ) {
* certainly_not_der = 1 ;
}
}
CHECK ( nlen [ n ] + nzlen [ n ] + nlenlen [ n ] <= 427 );
}
/* The total length of the data to go, so far */
tlen = 2 + nlenlen [ 0 ] + nlen [ 0 ] + nzlen [ 0 ] + 2 + nlenlen [ 1 ] + nlen [ 1 ] + nzlen [ 1 ];
CHECK ( tlen <= 856 );
/* The length of the garbage inside the tuple. */
elen = ( der || indet ) ? 0 : secp256k1_rand_int ( 980 - tlen ) * secp256k1_rand_int ( 8 ) / 8 ;
if ( elen != 0 ) {
* certainly_not_der = 1 ;
}
tlen += elen ;
CHECK ( tlen <= 980 );
/* The length of the garbage after the end of the tuple. */
glen = der ? 0 : secp256k1_rand_int ( 990 - tlen ) * secp256k1_rand_int ( 8 ) / 8 ;
if ( glen != 0 ) {
* certainly_not_der = 1 ;
}
CHECK ( tlen + glen <= 990 );
/* Write the tuple header. */
sig [( * len ) ++ ] = 0x30 ;
if ( indet ) {
/* Indeterminate length */
sig [( * len ) ++ ] = 0x80 ;
* certainly_not_der = 1 ;
} else {
int tlenlen = tlen < 128 ? 0 : ( tlen < 256 ? 1 : 2 );
if ( ! der ) {
int add = secp256k1_rand_int ( 127 - tlenlen ) * secp256k1_rand_int ( 16 ) * secp256k1_rand_int ( 16 ) / 256 ;
tlenlen += add ;
if ( add != 0 ) {
* certainly_not_der = 1 ;
}
}
if ( tlenlen == 0 ) {
/* Short length notation */
sig [( * len ) ++ ] = tlen ;
} else {
/* Long length notation */
sig [( * len ) ++ ] = 128 + tlenlen ;
assign_big_endian ( sig + * len , tlenlen , tlen );
* len += tlenlen ;
}
tlen += tlenlen ;
}
tlen += 2 ;
CHECK ( tlen + glen <= 1119 );
for ( n = 0 ; n < 2 ; n ++ ) {
/* Write the integer header. */
sig [( * len ) ++ ] = 0x02 ;
if ( nlenlen [ n ] == 0 ) {
/* Short length notation */
sig [( * len ) ++ ] = nlen [ n ] + nzlen [ n ];
} else {
/* Long length notation. */
sig [( * len ) ++ ] = 128 + nlenlen [ n ];
assign_big_endian ( sig + * len , nlenlen [ n ], nlen [ n ] + nzlen [ n ]);
* len += nlenlen [ n ];
}
/* Write zero padding */
while ( nzlen [ n ] > 0 ) {
sig [( * len ) ++ ] = 0x00 ;
nzlen [ n ] -- ;
}
if ( nlen [ n ] == 32 && ! nlow [ n ]) {
/* Special extra 16 0xFF bytes in "high" 32-byte numbers */
int i ;
for ( i = 0 ; i < 16 ; i ++ ) {
sig [( * len ) ++ ] = 0xFF ;
}
nlen [ n ] -= 16 ;
}
/* Write first byte of number */
if ( nlen [ n ] > 0 ) {
sig [( * len ) ++ ] = nhbyte [ n ];
nlen [ n ] -- ;
}
/* Generate remaining random bytes of number */
secp256k1_rand_bytes_test ( sig + * len , nlen [ n ]);
* len += nlen [ n ];
nlen [ n ] = 0 ;
}
/* Generate random garbage inside tuple. */
secp256k1_rand_bytes_test ( sig + * len , elen );
* len += elen ;
/* Generate end-of-contents bytes. */
if ( indet ) {
sig [( * len ) ++ ] = 0 ;
sig [( * len ) ++ ] = 0 ;
tlen += 2 ;
}
CHECK ( tlen + glen <= 1121 );
/* Generate random garbage outside tuple. */
secp256k1_rand_bytes_test ( sig + * len , glen );
* len += glen ;
tlen += glen ;
CHECK ( tlen <= 1121 );
CHECK ( tlen == * len );
}
void run_ecdsa_der_parse ( void ) {
int i , j ;
for ( i = 0 ; i < 200 * count ; i ++ ) {
unsigned char buffer [ 2048 ];
size_t buflen = 0 ;
int certainly_der = 0 ;
int certainly_not_der = 0 ;
random_ber_signature ( buffer , & buflen , & certainly_der , & certainly_not_der );
for ( j = 0 ; j < 16 ; j ++ ) {
int ret = 0 ;
if ( j > 0 ) {
damage_array ( buffer , & buflen );
/* We don't know anything anymore about the DERness of the result */
certainly_der = 0 ;
certainly_not_der = 0 ;
}
ret = test_ecdsa_der_parse ( buffer , buflen , certainly_der , certainly_not_der );
if ( ret != 0 ) {
size_t k ;
fprintf ( stderr , "Failure %x on " , ret );
for ( k = 0 ; k < buflen ; k ++ ) {
fprintf ( stderr , "%02x " , buffer [ k ]);
}
fprintf ( stderr , " \n " );
}
CHECK ( ret == 0 );
}
}
}
2014-11-28 23:43:00 +01:00
/* Tests several edge cases. */
void test_ecdsa_edge_cases ( void ) {
2015-08-27 03:19:27 +02:00
int t ;
2015-09-21 20:57:54 +02:00
secp256k1_ecdsa_signature sig ;
2015-08-27 03:19:27 +02:00
/* Test the case where ECDSA recomputes a point that is infinity. */
{
2015-09-21 20:57:54 +02:00
secp256k1_gej keyj ;
secp256k1_ge key ;
secp256k1_scalar msg ;
secp256k1_scalar sr , ss ;
2015-08-27 03:19:27 +02:00
secp256k1_scalar_set_int ( & ss , 1 );
secp256k1_scalar_negate ( & ss , & ss );
secp256k1_scalar_inverse ( & ss , & ss );
secp256k1_scalar_set_int ( & sr , 1 );
secp256k1_ecmult_gen ( & ctx -> ecmult_gen_ctx , & keyj , & sr );
secp256k1_ge_set_gej ( & key , & keyj );
msg = ss ;
CHECK ( secp256k1_ecdsa_sig_verify ( & ctx -> ecmult_ctx , & sr , & ss , & key , & msg ) == 0 );
}
/*Signature where s would be zero.*/
{
unsigned char signature [ 72 ];
2015-09-01 04:35:10 +00:00
size_t siglen ;
2015-08-27 03:19:27 +02:00
const unsigned char nonce [ 32 ] = {
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x01 ,
};
static const unsigned char nonce2 [ 32 ] = {
0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFE ,
0xBA , 0xAE , 0xDC , 0xE6 , 0xAF , 0x48 , 0xA0 , 0x3B ,
0xBF , 0xD2 , 0x5E , 0x8C , 0xD0 , 0x36 , 0x41 , 0x40
};
const unsigned char key [ 32 ] = {
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x01 ,
};
unsigned char msg [ 32 ] = {
0x86 , 0x41 , 0x99 , 0x81 , 0x06 , 0x23 , 0x44 , 0x53 ,
0xaa , 0x5f , 0x9d , 0x6a , 0x31 , 0x78 , 0xf4 , 0xf7 ,
0xb8 , 0x12 , 0xe0 , 0x0b , 0x81 , 0x7a , 0x77 , 0x62 ,
0x65 , 0xdf , 0xdd , 0x31 , 0xb9 , 0x3e , 0x29 , 0xa9 ,
};
2015-08-28 01:50:47 +02:00
CHECK ( secp256k1_ecdsa_sign ( ctx , & sig , msg , key , precomputed_nonce_function , nonce ) == 0 );
CHECK ( secp256k1_ecdsa_sign ( ctx , & sig , msg , key , precomputed_nonce_function , nonce2 ) == 0 );
2015-08-27 03:19:27 +02:00
msg [ 31 ] = 0xaa ;
2015-08-28 01:50:47 +02:00
CHECK ( secp256k1_ecdsa_sign ( ctx , & sig , msg , key , precomputed_nonce_function , nonce ) == 1 );
CHECK ( secp256k1_ecdsa_sign ( ctx , & sig , msg , key , precomputed_nonce_function , nonce2 ) == 1 );
2015-08-27 03:19:27 +02:00
siglen = 72 ;
CHECK ( secp256k1_ecdsa_signature_serialize_der ( ctx , signature , & siglen , & sig ) == 1 );
siglen = 10 ;
CHECK ( secp256k1_ecdsa_signature_serialize_der ( ctx , signature , & siglen , & sig ) == 0 );
}
/* Nonce function corner cases. */
for ( t = 0 ; t < 2 ; t ++ ) {
static const unsigned char zero [ 32 ] = { 0x00 };
int i ;
unsigned char key [ 32 ];
unsigned char msg [ 32 ];
2015-09-21 20:57:54 +02:00
secp256k1_ecdsa_signature sig2 ;
secp256k1_scalar sr [ 512 ], ss ;
2015-08-27 03:19:27 +02:00
const unsigned char * extra ;
extra = t == 0 ? NULL : zero ;
memset ( msg , 0 , 32 );
msg [ 31 ] = 1 ;
/* High key results in signature failure. */
memset ( key , 0xFF , 32 );
2015-08-28 01:50:47 +02:00
CHECK ( secp256k1_ecdsa_sign ( ctx , & sig , msg , key , NULL , extra ) == 0 );
2015-08-27 03:19:27 +02:00
CHECK ( is_empty_signature ( & sig ));
/* Zero key results in signature failure. */
memset ( key , 0 , 32 );
2015-08-28 01:50:47 +02:00
CHECK ( secp256k1_ecdsa_sign ( ctx , & sig , msg , key , NULL , extra ) == 0 );
2015-08-27 03:19:27 +02:00
CHECK ( is_empty_signature ( & sig ));
/* Nonce function failure results in signature failure. */
key [ 31 ] = 1 ;
2015-08-28 01:50:47 +02:00
CHECK ( secp256k1_ecdsa_sign ( ctx , & sig , msg , key , nonce_function_test_fail , extra ) == 0 );
2015-08-27 03:19:27 +02:00
CHECK ( is_empty_signature ( & sig ));
/* The retry loop successfully makes its way to the first good value. */
2015-08-28 01:50:47 +02:00
CHECK ( secp256k1_ecdsa_sign ( ctx , & sig , msg , key , nonce_function_test_retry , extra ) == 1 );
2015-08-27 03:19:27 +02:00
CHECK ( ! is_empty_signature ( & sig ));
2015-08-28 01:50:47 +02:00
CHECK ( secp256k1_ecdsa_sign ( ctx , & sig2 , msg , key , nonce_function_rfc6979 , extra ) == 1 );
2015-08-27 03:19:27 +02:00
CHECK ( ! is_empty_signature ( & sig2 ));
CHECK ( memcmp ( & sig , & sig2 , sizeof ( sig )) == 0 );
/* The default nonce function is determinstic. */
2015-08-28 01:50:47 +02:00
CHECK ( secp256k1_ecdsa_sign ( ctx , & sig2 , msg , key , NULL , extra ) == 1 );
2015-08-27 03:19:27 +02:00
CHECK ( ! is_empty_signature ( & sig2 ));
CHECK ( memcmp ( & sig , & sig2 , sizeof ( sig )) == 0 );
/* The default nonce function changes output with different messages. */
for ( i = 0 ; i < 256 ; i ++ ) {
int j ;
msg [ 0 ] = i ;
2015-08-28 01:50:47 +02:00
CHECK ( secp256k1_ecdsa_sign ( ctx , & sig2 , msg , key , NULL , extra ) == 1 );
2015-08-27 03:19:27 +02:00
CHECK ( ! is_empty_signature ( & sig2 ));
secp256k1_ecdsa_signature_load ( ctx , & sr [ i ], & ss , & sig2 );
for ( j = 0 ; j < i ; j ++ ) {
CHECK ( ! secp256k1_scalar_eq ( & sr [ i ], & sr [ j ]));
}
}
msg [ 0 ] = 0 ;
msg [ 31 ] = 2 ;
/* The default nonce function changes output with different keys. */
for ( i = 256 ; i < 512 ; i ++ ) {
int j ;
key [ 0 ] = i - 256 ;
2015-08-28 01:50:47 +02:00
CHECK ( secp256k1_ecdsa_sign ( ctx , & sig2 , msg , key , NULL , extra ) == 1 );
2015-08-27 03:19:27 +02:00
CHECK ( ! is_empty_signature ( & sig2 ));
secp256k1_ecdsa_signature_load ( ctx , & sr [ i ], & ss , & sig2 );
for ( j = 0 ; j < i ; j ++ ) {
CHECK ( ! secp256k1_scalar_eq ( & sr [ i ], & sr [ j ]));
}
}
key [ 0 ] = 0 ;
}
/* Privkey export where pubkey is the point at infinity. */
{
unsigned char privkey [ 300 ];
unsigned char seckey [ 32 ] = {
0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff ,
0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xfe ,
0xba , 0xae , 0xdc , 0xe6 , 0xaf , 0x48 , 0xa0 , 0x3b ,
0xbf , 0xd2 , 0x5e , 0x8c , 0xd0 , 0x36 , 0x41 , 0x41 ,
};
2015-09-01 04:35:10 +00:00
size_t outlen = 300 ;
2015-08-28 01:50:47 +02:00
CHECK ( ! secp256k1_ec_privkey_export ( ctx , privkey , & outlen , seckey , 0 ));
2015-09-01 04:52:35 +00:00
outlen = 300 ;
2015-09-01 06:00:35 +00:00
CHECK ( ! secp256k1_ec_privkey_export ( ctx , privkey , & outlen , seckey , SECP256K1_EC_COMPRESSED ));
2015-08-27 03:19:27 +02:00
}
}
2014-11-28 23:43:00 +01:00
void run_ecdsa_edge_cases ( void ) {
test_ecdsa_edge_cases ();
2014-11-18 13:13:17 +01:00
}
2014-08-03 19:54:41 +02:00
2013-05-05 16:55:05 +02:00
#ifdef ENABLE_OPENSSL_TESTS
2015-09-21 20:57:54 +02:00
EC_KEY * get_openssl_key ( const secp256k1_scalar * key ) {
2013-05-10 00:53:47 +02:00
unsigned char privkey [ 300 ];
2015-09-01 04:35:10 +00:00
size_t privkeylen ;
2013-05-10 00:53:47 +02:00
const unsigned char * pbegin = privkey ;
2015-10-17 21:15:15 +02:00
int compr = secp256k1_rand_bits ( 1 );
2013-05-05 16:55:05 +02:00
EC_KEY * ec_key = EC_KEY_new_by_curve_name ( NID_secp256k1 );
2015-09-01 06:00:35 +00:00
CHECK ( secp256k1_eckey_privkey_serialize ( & ctx -> ecmult_gen_ctx , privkey , & privkeylen , key , compr ? SECP256K1_EC_COMPRESSED : 0 ));
2014-06-16 01:30:17 +02:00
CHECK ( d2i_ECPrivateKey ( & ec_key , & pbegin , privkeylen ));
CHECK ( EC_KEY_check_key ( ec_key ));
2013-05-05 16:55:05 +02:00
return ec_key ;
}
2014-11-12 13:24:12 -08:00
void test_ecdsa_openssl ( void ) {
2015-09-21 20:57:54 +02:00
secp256k1_gej qj ;
secp256k1_ge q ;
secp256k1_scalar sigr , sigs ;
secp256k1_scalar one ;
secp256k1_scalar msg2 ;
secp256k1_scalar key , msg ;
2015-01-25 15:47:04 +00:00
EC_KEY * ec_key ;
unsigned int sigsize = 80 ;
2015-09-01 04:35:10 +00:00
size_t secp_sigsize = 80 ;
2013-05-05 16:55:05 +02:00
unsigned char message [ 32 ];
2015-01-25 15:47:04 +00:00
unsigned char signature [ 80 ];
2013-05-05 16:55:05 +02:00
secp256k1_rand256_test ( message );
2014-10-29 00:35:09 -07:00
secp256k1_scalar_set_b32 ( & msg , message , NULL );
2014-10-28 04:08:15 -07:00
random_scalar_order_test ( & key );
2015-02-03 17:27:00 -08:00
secp256k1_ecmult_gen ( & ctx -> ecmult_gen_ctx , & qj , & key );
2013-05-05 16:55:05 +02:00
secp256k1_ge_set_gej ( & q , & qj );
2015-01-25 15:47:04 +00:00
ec_key = get_openssl_key ( & key );
2015-09-23 21:56:04 +00:00
CHECK ( ec_key != NULL );
2014-06-16 01:30:17 +02:00
CHECK ( ECDSA_sign ( 0 , message , sizeof ( message ), signature , & sigsize , ec_key ));
2015-07-26 16:51:58 +02:00
CHECK ( secp256k1_ecdsa_sig_parse ( & sigr , & sigs , signature , sigsize ));
CHECK ( secp256k1_ecdsa_sig_verify ( & ctx -> ecmult_ctx , & sigr , & sigs , & q , & msg ));
2014-11-26 17:26:39 +01:00
secp256k1_scalar_set_int ( & one , 1 );
secp256k1_scalar_add ( & msg2 , & msg , & one );
2015-07-26 16:51:58 +02:00
CHECK ( ! secp256k1_ecdsa_sig_verify ( & ctx -> ecmult_ctx , & sigr , & sigs , & q , & msg2 ));
2013-05-05 16:55:05 +02:00
2015-07-26 16:51:58 +02:00
random_sign ( & sigr , & sigs , & key , & msg , NULL );
CHECK ( secp256k1_ecdsa_sig_serialize ( signature , & secp_sigsize , & sigr , & sigs ));
2014-11-04 13:14:47 -08:00
CHECK ( ECDSA_verify ( 0 , message , sizeof ( message ), signature , secp_sigsize , ec_key ) == 1 );
2013-05-05 16:55:05 +02:00
EC_KEY_free ( ec_key );
}
2014-11-12 13:24:12 -08:00
void run_ecdsa_openssl ( void ) {
2015-01-25 15:47:04 +00:00
int i ;
for ( i = 0 ; i < 10 * count ; i ++ ) {
2013-05-05 16:55:05 +02:00
test_ecdsa_openssl ();
}
}
#endif
2015-06-29 15:06:28 -05:00
#ifdef ENABLE_MODULE_ECDH
# include "modules/ecdh/tests_impl.h"
#endif
2015-07-24 15:44:49 +02:00
#ifdef ENABLE_MODULE_SCHNORR
# include "modules/schnorr/tests_impl.h"
#endif
2015-08-27 03:42:57 +02:00
#ifdef ENABLE_MODULE_RECOVERY
# include "modules/recovery/tests_impl.h"
#endif
2013-04-21 19:07:21 +02:00
int main ( int argc , char ** argv ) {
2015-02-14 15:30:58 -08:00
unsigned char seed16 [ 16 ] = { 0 };
unsigned char run32 [ 32 ] = { 0 };
2014-11-15 15:28:10 +00:00
/* find iteration count */
2014-10-17 16:04:00 -07:00
if ( argc > 1 ) {
count = strtol ( argv [ 1 ], NULL , 0 );
}
2014-11-15 15:28:10 +00:00
/* find random seed */
2014-10-17 16:04:00 -07:00
if ( argc > 2 ) {
2015-02-14 15:30:58 -08:00
int pos = 0 ;
const char * ch = argv [ 2 ];
while ( pos < 16 && ch [ 0 ] != 0 && ch [ 1 ] != 0 ) {
unsigned short sh ;
if ( sscanf ( ch , "%2hx" , & sh )) {
seed16 [ pos ] = sh ;
} else {
break ;
}
ch += 2 ;
pos ++ ;
}
2014-10-17 16:04:00 -07:00
} else {
FILE * frand = fopen ( "/dev/urandom" , "r" );
2015-09-23 21:56:04 +00:00
if (( frand == NULL ) || ! fread ( & seed16 , sizeof ( seed16 ), 1 , frand )) {
2015-02-14 15:30:58 -08:00
uint64_t t = time ( NULL ) * ( uint64_t ) 1337 ;
seed16 [ 0 ] ^= t ;
seed16 [ 1 ] ^= t >> 8 ;
seed16 [ 2 ] ^= t >> 16 ;
seed16 [ 3 ] ^= t >> 24 ;
seed16 [ 4 ] ^= t >> 32 ;
seed16 [ 5 ] ^= t >> 40 ;
seed16 [ 6 ] ^= t >> 48 ;
seed16 [ 7 ] ^= t >> 56 ;
2014-10-17 16:04:00 -07:00
}
fclose ( frand );
}
2015-02-14 15:30:58 -08:00
secp256k1_rand_seed ( seed16 );
2013-04-21 19:07:21 +02:00
2013-05-05 16:55:05 +02:00
printf ( "test count = %i \n " , count );
2015-02-14 15:30:58 -08:00
printf ( "random seed = %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x \n " , seed16 [ 0 ], seed16 [ 1 ], seed16 [ 2 ], seed16 [ 3 ], seed16 [ 4 ], seed16 [ 5 ], seed16 [ 6 ], seed16 [ 7 ], seed16 [ 8 ], seed16 [ 9 ], seed16 [ 10 ], seed16 [ 11 ], seed16 [ 12 ], seed16 [ 13 ], seed16 [ 14 ], seed16 [ 15 ]);
2013-05-05 16:55:05 +02:00
2014-11-15 15:28:10 +00:00
/* initialize */
2015-04-11 14:06:54 -05:00
run_context_tests ();
2015-02-03 17:27:00 -08:00
ctx = secp256k1_context_create ( SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY );
2015-10-17 21:15:15 +02:00
if ( secp256k1_rand_bits ( 1 )) {
2015-04-15 21:35:50 +00:00
secp256k1_rand256 ( run32 );
2015-10-17 21:15:15 +02:00
CHECK ( secp256k1_context_randomize ( ctx , secp256k1_rand_bits ( 1 ) ? run32 : NULL ));
2015-04-15 21:35:50 +00:00
}
2015-10-17 17:46:01 +02:00
run_rand_bits ();
run_rand_int ();
2014-12-13 17:02:30 +01:00
run_sha256_tests ();
run_hmac_sha256_tests ();
run_rfc6979_hmac_sha256_tests ();
2014-11-28 01:23:55 +01:00
#ifndef USE_NUM_NONE
2014-11-15 15:28:10 +00:00
/* num tests */
2013-04-22 01:52:56 +02:00
run_num_smalltests ();
2014-11-28 01:23:55 +01:00
#endif
2013-04-21 19:07:21 +02:00
2014-11-15 15:28:10 +00:00
/* scalar tests */
2014-10-29 00:35:38 -07:00
run_scalar_tests ();
2014-11-15 15:28:10 +00:00
/* field tests */
2014-07-02 16:01:26 +07:00
run_field_inv ();
run_field_inv_var ();
run_field_inv_all_var ();
2014-12-08 00:48:53 -08:00
run_field_misc ();
2015-01-24 23:04:48 -04:00
run_field_convert ();
2014-06-22 15:03:29 +07:00
run_sqr ();
2014-05-21 10:22:14 +07:00
run_sqrt ();
2014-11-15 15:28:10 +00:00
/* group tests */
2014-11-11 10:32:50 -08:00
run_ge ();
2014-11-15 15:28:10 +00:00
/* ecmult tests */
2013-04-21 19:07:21 +02:00
run_wnaf ();
run_point_times_order ();
run_ecmult_chain ();
2015-04-15 21:35:50 +00:00
run_ecmult_constants ();
run_ecmult_gen_blind ();
2015-05-13 17:31:47 -05:00
run_ecmult_const_tests ();
2015-07-24 15:44:49 +02:00
run_ec_combine ();
2013-04-21 19:07:21 +02:00
2015-05-13 21:16:13 -05:00
/* endomorphism tests */
#ifdef USE_ENDOMORPHISM
run_endomorphism_tests ();
#endif
2015-09-27 23:47:01 +00:00
/* EC point parser test*/
run_ec_pubkey_parse_test ();
2015-06-29 15:06:28 -05:00
#ifdef ENABLE_MODULE_ECDH
/* ecdh tests */
run_ecdh_tests ();
#endif
2014-11-15 15:28:10 +00:00
/* ecdsa tests */
2014-12-08 12:38:16 -08:00
run_random_pubkeys ();
2015-09-28 17:40:21 +02:00
run_ecdsa_der_parse ();
2013-04-21 19:07:21 +02:00
run_ecdsa_sign_verify ();
2014-08-03 19:54:41 +02:00
run_ecdsa_end_to_end ();
2014-11-28 23:43:00 +01:00
run_ecdsa_edge_cases ();
2013-05-05 16:55:05 +02:00
#ifdef ENABLE_OPENSSL_TESTS
run_ecdsa_openssl ();
#endif
2013-03-30 22:32:16 +01:00
2015-07-24 15:44:49 +02:00
#ifdef ENABLE_MODULE_SCHNORR
/* Schnorr tests */
run_schnorr_tests ();
#endif
2015-08-27 03:42:57 +02:00
#ifdef ENABLE_MODULE_RECOVERY
/* ECDSA pubkey recovery tests */
run_recovery_tests ();
#endif
2015-02-14 15:30:58 -08:00
secp256k1_rand256 ( run32 );
printf ( "random run = %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x \n " , run32 [ 0 ], run32 [ 1 ], run32 [ 2 ], run32 [ 3 ], run32 [ 4 ], run32 [ 5 ], run32 [ 6 ], run32 [ 7 ], run32 [ 8 ], run32 [ 9 ], run32 [ 10 ], run32 [ 11 ], run32 [ 12 ], run32 [ 13 ], run32 [ 14 ], run32 [ 15 ]);
2014-10-26 05:38:54 -07:00
2014-11-15 15:28:10 +00:00
/* shutdown */
2015-02-03 17:27:00 -08:00
secp256k1_context_destroy ( ctx );
2015-08-28 02:29:08 +02:00
printf ( "no problems found \n " );
2013-03-10 21:25:19 +01:00
return 0 ;
}