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>
2015-07-26 16:00:55 +02:00
# include "include/secp256k1.h"
2014-08-03 19:54:41 +02:00
# include "secp256k1.c"
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
2014-10-27 02:25:48 -07:00
static int count = 64 ;
2015-02-03 17:27:00 -08:00
static secp256k1_context_t * ctx = NULL ;
2013-03-24 10:38:35 +01:00
2014-11-11 10:32:50 -08:00
void random_field_element_test ( secp256k1_fe_t * fe ) {
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 ) ;
}
void random_field_element_magnitude ( secp256k1_fe_t * fe ) {
2015-01-25 15:47:04 +00:00
secp256k1_fe_t zero ;
2014-12-29 15:38:17 +01:00
int n = secp256k1_rand32 ( ) % 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
}
void random_group_element_test ( secp256k1_ge_t * ge ) {
secp256k1_fe_t fe ;
do {
random_field_element_test ( & fe ) ;
2015-03-27 23:14:17 +00:00
if ( secp256k1_ge_set_xo_var ( ge , & fe , secp256k1_rand32 ( ) & 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 ) ;
}
void random_group_element_jacobian_test ( secp256k1_gej_t * gej , const secp256k1_ge_t * ge ) {
2015-01-25 15:47:04 +00:00
secp256k1_fe_t 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 ;
}
2014-10-28 04:08:15 -07:00
void random_scalar_order_test ( secp256k1_scalar_t * num ) {
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 ) ;
}
2014-11-26 17:26:39 +01:00
void random_scalar_order ( secp256k1_scalar_t * num ) {
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 ) {
secp256k1_context_t * none = secp256k1_context_create ( 0 ) ;
secp256k1_context_t * sign = secp256k1_context_create ( SECP256K1_CONTEXT_SIGN ) ;
secp256k1_context_t * vrfy = secp256k1_context_create ( SECP256K1_CONTEXT_VERIFY ) ;
secp256k1_context_t * both = secp256k1_context_create ( SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY ) ;
secp256k1_gej_t pubj ;
secp256k1_ge_t pub ;
secp256k1_scalar_t msg , key , nonce ;
2015-07-26 16:51:58 +02:00
secp256k1_scalar_t sigr , sigs ;
2015-04-11 14:06:54 -05:00
/*** clone and destroy all of them to make sure cloning was complete ***/
{
secp256k1_context_t * ctx_tmp ;
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 ) {
int split = secp256k1_rand32 ( ) % 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 ) {
int split = secp256k1_rand32 ( ) % 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 ) ;
}
2014-11-27 19:12:13 +01:00
/***** NUM TESTS *****/
2014-11-28 01:23:55 +01:00
# ifndef USE_NUM_NONE
2014-11-27 19:12:13 +01:00
void random_num_negate ( secp256k1_num_t * num ) {
2015-03-27 23:14:17 +00:00
if ( secp256k1_rand32 ( ) & 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
}
void random_num_order_test ( secp256k1_num_t * num ) {
secp256k1_scalar_t sc ;
random_scalar_order_test ( & sc ) ;
secp256k1_scalar_get_num ( num , & sc ) ;
}
2013-04-21 19:07:21 +02:00
void random_num_order ( secp256k1_num_t * num ) {
2014-11-27 19:12:13 +01:00
secp256k1_scalar_t sc ;
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 ) {
2013-04-22 01:52:56 +02:00
secp256k1_num_t n1 ;
secp256k1_num_t 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 ) {
2013-04-22 01:52:56 +02:00
secp256k1_num_t n1 ;
secp256k1_num_t n2 ;
2015-01-25 15:47:04 +00:00
secp256k1_num_t n1p2 , n2p1 , n1m2 , n2m1 ;
int r = secp256k1_rand32 ( ) ;
2014-11-15 15:28:10 +00:00
random_num_order_test ( & n1 ) ; /* n1 = R1 */
2014-08-09 19:22:42 +02:00
if ( r & 1 ) {
random_num_negate ( & n1 ) ;
}
2014-11-15 15:28:10 +00:00
random_num_order_test ( & n2 ) ; /* n2 = R2 */
2014-08-09 19:22:42 +02:00
if ( r & 2 ) {
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-01-25 15:47:04 +00:00
secp256k1_scalar_t s ;
secp256k1_scalar_t s1 ;
secp256k1_scalar_t s2 ;
# ifndef USE_NUM_NONE
secp256k1_num_t snum , s1num , s2num ;
secp256k1_num_t order , half_order ;
# 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. */
2014-11-25 15:55:21 +01:00
secp256k1_scalar_t n ;
secp256k1_scalar_set_int ( & n , 0 ) ;
2015-01-25 15:47:04 +00:00
for ( i = 0 ; i < 256 ; i + = 4 ) {
2014-11-25 15:55:21 +01:00
secp256k1_scalar_t 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. */
secp256k1_scalar_t n ;
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-01-25 15:47:04 +00:00
secp256k1_scalar_t t ;
int j ;
2014-11-25 15:55:21 +01:00
int now = ( secp256k1_rand32 ( ) % 15 ) + 1 ;
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. */
2014-10-29 00:35:38 -07:00
secp256k1_num_t rnum ;
2015-01-25 15:47:04 +00:00
secp256k1_num_t r2num ;
secp256k1_scalar_t 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-01-25 15:47:04 +00:00
secp256k1_scalar_t r ;
secp256k1_num_t r2num ;
2014-10-29 00:35:38 -07:00
secp256k1_num_t rnum ;
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-01-25 15:47:04 +00:00
secp256k1_scalar_t neg ;
secp256k1_num_t negnum ;
secp256k1_num_t 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. */
secp256k1_scalar_t r ;
2015-01-25 15:47:04 +00:00
secp256k1_num_t one ;
secp256k1_num_t rnum ;
secp256k1_num_t rnum2 ;
unsigned char cone [ 1 ] = { 0x01 } ;
2014-12-01 17:11:59 +01:00
unsigned int shift = 256 + ( secp256k1_rand32 ( ) % 257 ) ;
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 */
secp256k1_scalar_t r ;
int i ;
int low ;
random_scalar_order_test ( & r ) ;
for ( i = 0 ; i < 100 ; + + i ) {
int shift = 1 + ( secp256k1_rand32 ( ) % 15 ) ;
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 ) ) {
secp256k1_scalar_t inv ;
2014-11-28 01:23:55 +01:00
# ifndef USE_NUM_NONE
2014-10-29 00:35:38 -07:00
secp256k1_num_t invnum ;
secp256k1_num_t 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. */
2014-10-29 00:35:38 -07:00
secp256k1_scalar_t r1 , r2 ;
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-01-25 15:47:04 +00:00
secp256k1_scalar_t r1 , r2 ;
secp256k1_scalar_t b ;
int i ;
2014-11-25 15:20:44 +01:00
/* Test add_bit. */
int bit = secp256k1_rand32 ( ) % 256 ;
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. */
2014-10-29 00:35:38 -07:00
secp256k1_scalar_t r1 , r2 ;
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. */
2014-10-29 00:35:38 -07:00
secp256k1_scalar_t r1 , r2 ;
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. */
2014-10-29 00:35:38 -07:00
secp256k1_scalar_t r1 , r2 ;
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. */
2014-10-29 00:35:38 -07:00
secp256k1_scalar_t r1 , r2 , t ;
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. */
2014-10-29 00:35:49 -07:00
secp256k1_scalar_t r1 , r2 ;
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. */
secp256k1_scalar_t r1 , v1 ;
secp256k1_scalar_set_int ( & v1 , 1 ) ;
secp256k1_scalar_mul ( & r1 , & s1 , & v1 ) ;
CHECK ( secp256k1_scalar_eq ( & r1 , & s1 ) ) ;
}
{
/* Test additive identity. */
secp256k1_scalar_t r1 , v0 ;
secp256k1_scalar_set_int ( & v0 , 0 ) ;
secp256k1_scalar_add ( & r1 , & s1 , & v0 ) ;
CHECK ( secp256k1_scalar_eq ( & r1 , & s1 ) ) ;
}
{
/* Test zero product property. */
secp256k1_scalar_t r1 , v0 ;
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. */
2014-11-27 19:12:13 +01:00
secp256k1_scalar_t s , o ;
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. */
2014-11-27 19:12:13 +01:00
secp256k1_num_t order ;
secp256k1_scalar_t 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 *****/
void random_fe ( secp256k1_fe_t * x ) {
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
}
2014-06-03 17:50:27 +07:00
void random_fe_non_zero ( secp256k1_fe_t * nz ) {
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
}
2014-06-03 17:50:27 +07:00
void random_fe_non_square ( secp256k1_fe_t * ns ) {
secp256k1_fe_t 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 ) ;
}
}
2014-07-02 16:01:26 +07:00
int check_fe_equal ( const secp256k1_fe_t * a , const secp256k1_fe_t * b ) {
2015-01-25 15:47:04 +00:00
secp256k1_fe_t an = * a ;
secp256k1_fe_t bn = * b ;
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
}
int check_fe_inverse ( const secp256k1_fe_t * a , const secp256k1_fe_t * ai ) {
2015-01-25 15:47:04 +00:00
secp256k1_fe_t x ;
2015-02-23 04:17:37 -08:00
secp256k1_fe_t 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
} ;
static const secp256k1_fe_storage_t fes = SECP256K1_FE_STORAGE_CONST (
0x00010203UL , 0x04050607UL , 0x11121314UL , 0x15161718UL ,
0x22232425UL , 0x26272829UL , 0x33343536UL , 0x37383940UL
) ;
static const secp256k1_fe_t fe = SECP256K1_FE_CONST (
0x00010203UL , 0x04050607UL , 0x11121314UL , 0x15161718UL ,
0x22232425UL , 0x26272829UL , 0x33343536UL , 0x37383940UL
) ;
secp256k1_fe_t fe2 ;
unsigned char b322 [ 32 ] ;
secp256k1_fe_storage_t fes2 ;
/* 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-07-04 13:50:15 +09:30
int fe_memcmp ( const secp256k1_fe_t * a , const secp256k1_fe_t * b ) {
secp256k1_fe_t t = * b ;
# ifdef VERIFY
t . magnitude = a - > magnitude ;
t . normalized = a - > normalized ;
# endif
return memcmp ( a , & t , sizeof ( secp256k1_fe_t ) ) ;
}
2014-12-08 00:48:53 -08:00
void run_field_misc ( void ) {
secp256k1_fe_t x ;
secp256k1_fe_t y ;
secp256k1_fe_t z ;
secp256k1_fe_t q ;
2015-02-23 04:17:37 -08:00
secp256k1_fe_t 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 + + ) {
secp256k1_fe_storage_t 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 ) {
2014-07-02 16:01:26 +07:00
secp256k1_fe_t 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 ) {
2014-07-02 16:01:26 +07:00
secp256k1_fe_t 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 ) {
2014-07-02 16:01:26 +07:00
secp256k1_fe_t 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 ;
2014-07-02 16:01:26 +07:00
size_t len = ( secp256k1_rand32 ( ) & 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 ) {
2014-06-22 15:03:29 +07:00
secp256k1_fe_t x , s ;
{
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 ) ;
}
}
}
2014-05-21 10:22:14 +07:00
void test_sqrt ( const secp256k1_fe_t * a , const secp256k1_fe_t * k ) {
secp256k1_fe_t 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 ) {
2014-05-21 10:22:14 +07:00
secp256k1_fe_t 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 *****/
2014-12-29 15:38:17 +01:00
void ge_equals_ge ( const secp256k1_ge_t * a , const secp256k1_ge_t * b ) {
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. */
int gej_xyz_equals_gej ( const secp256k1_gej_t * a , const secp256k1_gej_t * b ) {
secp256k1_gej_t a2 ;
secp256k1_gej_t b2 ;
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 ;
}
2014-11-11 10:32:50 -08:00
void ge_equals_gej ( const secp256k1_ge_t * a , const secp256k1_gej_t * b ) {
2015-01-25 15:47:04 +00:00
secp256k1_fe_t z2s ;
secp256k1_fe_t 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-03-28 02:20:36 +00:00
secp256k1_ge_t * ge = ( secp256k1_ge_t * ) malloc ( sizeof ( secp256k1_ge_t ) * ( 1 + 4 * runs ) ) ;
secp256k1_gej_t * gej = ( secp256k1_gej_t * ) malloc ( sizeof ( secp256k1_gej_t ) * ( 1 + 4 * runs ) ) ;
2014-11-04 19:16:55 +07:00
secp256k1_fe_t * zinv = ( secp256k1_fe_t * ) malloc ( sizeof ( secp256k1_fe_t ) * ( 1 + 4 * runs ) ) ;
secp256k1_fe_t zf ;
secp256k1_fe_t zfi2 , zfi3 ;
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 ;
2014-12-29 15:38:17 +01:00
secp256k1_ge_t g ;
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. */
{
secp256k1_fe_t * zs = malloc ( sizeof ( secp256k1_fe_t ) * ( 1 + 4 * runs ) ) ;
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). */
secp256k1_gej_t refj , resj ;
secp256k1_ge_t ref ;
2014-11-04 19:16:55 +07:00
secp256k1_fe_t zr ;
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 ) ) {
secp256k1_fe_t zrz ; secp256k1_fe_mul ( & zrz , & zr , & gej [ i1 ] . z ) ;
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 ) ) {
secp256k1_fe_t zrz ; secp256k1_fe_mul ( & zrz , & zr , & gej [ i1 ] . z ) ;
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). */
{
secp256k1_ge_t ge2_zfi = ge [ i2 ] ; /* the second term with x and y rescaled for z = 1/zf */
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 ) ) {
2014-11-04 19:16:55 +07:00
secp256k1_fe_t zr2 ;
/* 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-02-23 04:17:37 -08:00
secp256k1_gej_t sum = SECP256K1_GEJ_CONST_INFINITY ;
2015-03-28 02:20:36 +00:00
secp256k1_gej_t * gej_shuffled = ( secp256k1_gej_t * ) malloc ( ( 4 * runs + 1 ) * sizeof ( secp256k1_gej_t ) ) ;
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 + + ) {
2014-12-29 17:21:39 +01:00
int swap = i + secp256k1_rand32 ( ) % ( 4 * runs + 1 - i ) ;
if ( swap ! = i ) {
secp256k1_gej_t t = gej_shuffled [ i ] ;
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
{
2014-11-04 19:16:55 +07:00
secp256k1_fe_t * zr = ( secp256k1_fe_t * ) malloc ( ( 4 * runs + 1 ) * sizeof ( secp256k1_fe_t ) ) ;
secp256k1_ge_t * ge_set_table = ( secp256k1_ge_t * ) malloc ( ( 4 * runs + 1 ) * sizeof ( secp256k1_ge_t ) ) ;
2015-03-28 02:20:36 +00:00
secp256k1_ge_t * ge_set_all = ( secp256k1_ge_t * ) malloc ( ( 4 * runs + 1 ) * sizeof ( secp256k1_ge_t ) ) ;
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-04-15 21:35:50 +00:00
secp256k1_fe_t s ;
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 ( )
*/
secp256k1_gej_t aj = SECP256K1_GEJ_CONST (
0x8d24cd95 , 0x0a355af1 , 0x3c543505 , 0x44238d30 ,
0x0643d79f , 0x05a59614 , 0x2f8ec030 , 0xd58977cb ,
0x001e337a , 0x38093dcd , 0x6c0f386d , 0x0b1293a8 ,
0x4d72c879 , 0xd7681924 , 0x44e6d2f3 , 0x9190117d
) ;
secp256k1_gej_t bj = SECP256K1_GEJ_CONST (
0xc7b74206 , 0x1f788cd9 , 0xabd0937d , 0x164a0d86 ,
0x95f6ff75 , 0xf19a4ce9 , 0xd013bd7b , 0xbf92d2a7 ,
0xffe1cc85 , 0xc7f6c232 , 0x93f0c792 , 0xf4ed6c57 ,
0xb28d3786 , 0x2897e6db , 0xbb192d0b , 0x6e6feab2
) ;
secp256k1_gej_t sumj = SECP256K1_GEJ_CONST (
0x671a63c0 , 0x3efdad4c , 0x389a7798 , 0x24356027 ,
0xb3d69010 , 0x278625c3 , 0x5c86d390 , 0x184a8f7a ,
0x5f6409c2 , 0x2ce01f2b , 0x511fd375 , 0x25071d08 ,
0xda651801 , 0x70e95caf , 0x8f0d893c , 0xbed8fbbe
) ;
secp256k1_ge_t b ;
secp256k1_gej_t resj ;
secp256k1_ge_t res ;
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 ) {
secp256k1_scalar_t sum = SECP256K1_SCALAR_CONST ( 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ) ;
secp256k1_pubkey_t data [ 6 ] ;
const secp256k1_pubkey_t * d [ 6 ] ;
secp256k1_pubkey_t sd ;
secp256k1_pubkey_t sd2 ;
secp256k1_gej_t Qj ;
secp256k1_ge_t Q ;
int i ;
for ( i = 1 ; i < = 6 ; i + + ) {
secp256k1_scalar_t s ;
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 ) ;
CHECK ( secp256k1_ec_pubkey_combine ( ctx , & sd2 , i , d ) = = 1 ) ;
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) */
secp256k1_gej_t a = SECP256K1_GEJ_CONST (
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-02-23 04:17:37 -08:00
secp256k1_scalar_t xn = SECP256K1_SCALAR_CONST (
0x84cc5452 , 0xf7fde1ed , 0xb4d38a8c , 0xe9b1b84c ,
0xcef31f14 , 0x6e569be9 , 0x705d357a , 0x42985407
) ;
secp256k1_scalar_t gn = SECP256K1_SCALAR_CONST (
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-02-23 04:17:37 -08:00
static const secp256k1_scalar_t xf = SECP256K1_SCALAR_CONST ( 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x1337 ) ;
static const secp256k1_scalar_t 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-02-23 04:17:37 -08:00
secp256k1_scalar_t ae = SECP256K1_SCALAR_CONST ( 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 ) ;
secp256k1_scalar_t ge = SECP256K1_SCALAR_CONST ( 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ) ;
/* actual points */
secp256k1_gej_t x = a ;
secp256k1_gej_t x2 ;
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 */
secp256k1_gej_t rp = SECP256K1_GEJ_CONST (
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
}
2013-04-01 07:52:58 +02:00
void test_point_times_order ( const secp256k1_gej_t * point ) {
2014-11-26 15:35:06 +01:00
/* X * (point + G) + (order-X) * (pointer + G) = 0 */
2014-11-26 17:26:39 +01:00
secp256k1_scalar_t x ;
secp256k1_scalar_t nx ;
2015-05-13 21:16:13 -05:00
secp256k1_scalar_t zero = SECP256K1_SCALAR_CONST ( 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ) ;
secp256k1_scalar_t one = SECP256K1_SCALAR_CONST ( 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 ) ;
2014-11-26 15:35:06 +01:00
secp256k1_gej_t res1 , res2 ;
2015-01-25 15:47:04 +00:00
secp256k1_ge_t res3 ;
unsigned char pub [ 65 ] ;
int psize = 65 ;
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-02-23 04:17:37 -08:00
secp256k1_fe_t x = SECP256K1_FE_CONST ( 0 , 0 , 0 , 0 , 0 , 0 , 0 , 2 ) ;
static const secp256k1_fe_t xr = SECP256K1_FE_CONST (
0x7603CB59 , 0xB0EF6C63 , 0xFE608479 , 0x2A0C378C ,
0xDB3233A8 , 0x0F8A9A09 , 0xA877DEAD , 0x31B38C45
) ;
2015-01-25 15:47:04 +00:00
for ( i = 0 ; i < 500 ; i + + ) {
2014-05-21 10:22:14 +07:00
secp256k1_ge_t p ;
2014-12-05 03:37:42 +01:00
if ( secp256k1_ge_set_xo_var ( & p , & x , 1 ) ) {
2014-05-21 10:22:14 +07:00
secp256k1_gej_t 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) */
secp256k1_ge_t a = SECP256K1_GE_CONST (
0x6d986544 , 0x57ff52b8 , 0xcf1b8126 , 0x5b802a5b ,
0xa97f9263 , 0xb1e88044 , 0x93351325 , 0x91bc450a ,
0x535c59f7 , 0x325e5d2b , 0xc391fbe8 , 0x3c12787c ,
0x337e4a98 , 0xe82a9011 , 0x0123ba37 , 0xdd769c7d
) ;
/* random initial factor xn */
secp256k1_scalar_t xn = SECP256K1_SCALAR_CONST (
0x649d4f77 , 0xc4242df7 , 0x7f2079c9 , 0x14530327 ,
0xa31b876a , 0xd2d8ce2a , 0x2236d5c6 , 0xd7b2029b
) ;
/* expected xn * A (from sage) */
secp256k1_ge_t expected_b = SECP256K1_GE_CONST (
0x23773684 , 0x4d209dc7 , 0x098a786f , 0x20d06fcd ,
0x070a38bf , 0xc11ac651 , 0x03004319 , 0x1e2a8786 ,
0xed8c3b8e , 0xc06dd57b , 0xd06ea66e , 0x45492b0f ,
0xb84e4e1b , 0xfb77e21f , 0x96baae2a , 0x63dec956
) ;
secp256k1_gej_t b ;
secp256k1_ecmult_const ( & b , & a , & xn ) ;
CHECK ( secp256k1_ge_is_valid_var ( & a ) ) ;
ge_equals_gej ( & expected_b , & b ) ;
}
void ecmult_const_commutativity ( void ) {
secp256k1_scalar_t a ;
secp256k1_scalar_t b ;
secp256k1_gej_t res1 ;
secp256k1_gej_t res2 ;
secp256k1_ge_t mid1 ;
secp256k1_ge_t mid2 ;
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 ) {
secp256k1_scalar_t zero = SECP256K1_SCALAR_CONST ( 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ) ;
secp256k1_scalar_t one = SECP256K1_SCALAR_CONST ( 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 ) ;
secp256k1_scalar_t negone ;
secp256k1_gej_t res1 ;
secp256k1_ge_t res2 ;
secp256k1_ge_t point ;
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) */
const secp256k1_scalar_t scalar = SECP256K1_SCALAR_CONST (
0x4968d524 , 0x2abf9b7a , 0x466abbcf , 0x34b11b6d ,
0xcd83d307 , 0x827bed62 , 0x05fad0ce , 0x18fae63b
) ;
const secp256k1_gej_t expected_point = SECP256K1_GEJ_CONST (
0x5494c15d , 0x32099706 , 0xc2395f94 , 0x348745fd ,
0x757ce30e , 0x4e8c90fb , 0xa2bad184 , 0xf883c69f ,
0x5d195d20 , 0xe191bf7f , 0x1be3e55f , 0x56a80196 ,
0x6071ad01 , 0xf1462f66 , 0xc997fa94 , 0xdb858435
) ;
secp256k1_gej_t point ;
secp256k1_ge_t res ;
int i ;
secp256k1_gej_set_ge ( & point , & secp256k1_ge_const_g ) ;
for ( i = 0 ; i < 100 ; + + i ) {
secp256k1_ge_t tmp ;
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 ( ) ;
}
2014-11-26 17:26:39 +01:00
void test_wnaf ( const secp256k1_scalar_t * number , int w ) {
secp256k1_scalar_t 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-05-13 17:31:47 -05:00
void test_constant_wnaf_negate ( const secp256k1_scalar_t * number ) {
secp256k1_scalar_t neg1 = * number ;
secp256k1_scalar_t neg2 = * number ;
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 ) ) ;
}
void test_constant_wnaf ( const secp256k1_scalar_t * number , int w ) {
secp256k1_scalar_t x , shift ;
int wnaf [ 256 ] = { 0 } ;
int i ;
2015-05-22 12:09:36 -05:00
# ifdef USE_ENDOMORPHISM
int skew ;
# endif
secp256k1_scalar_t 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
for ( i = 0 ; i < 16 ; + + i )
secp256k1_scalar_shr_int ( & num , 8 ) ;
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 ) {
secp256k1_scalar_t t ;
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-05-13 17:31:47 -05:00
secp256k1_scalar_t n = { { 0 } } ;
/* 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). */
secp256k1_scalar_t x ;
secp256k1_gej_t r ;
secp256k1_ge_t ng ;
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. */
secp256k1_scalar_t key ;
secp256k1_scalar_t b ;
unsigned char seed32 [ 32 ] ;
secp256k1_gej_t pgej ;
secp256k1_gej_t pgej2 ;
secp256k1_gej_t i ;
secp256k1_ge_t pge ;
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. */
secp256k1_scalar_t b ;
secp256k1_gej_t initial ;
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 ) {
secp256k1_scalar_t full ;
secp256k1_scalar_t s1 , slam ;
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 */
if ( secp256k1_scalar_is_high ( & s1 ) )
secp256k1_scalar_negate ( & s1 , & s1 ) ;
if ( secp256k1_scalar_is_high ( & slam ) )
secp256k1_scalar_negate ( & slam , & slam ) ;
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-07-26 16:51:58 +02:00
void random_sign ( secp256k1_scalar_t * sigr , secp256k1_scalar_t * sigs , const secp256k1_scalar_t * key , const secp256k1_scalar_t * msg , int * recid ) {
2014-10-28 04:08:15 -07:00
secp256k1_scalar_t 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-01-25 15:47:04 +00:00
secp256k1_gej_t pubj ;
secp256k1_ge_t pub ;
secp256k1_scalar_t one ;
secp256k1_scalar_t msg , key ;
2015-07-26 16:51:58 +02:00
secp256k1_scalar_t 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 ) ;
2014-12-04 01:04:00 -08:00
getrec = secp256k1_rand32 ( ) & 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-07-24 15:44:49 +02:00
static int precomputed_nonce_function ( unsigned char * nonce32 , const unsigned char * msg32 , const unsigned char * key32 , const unsigned char * algo16 , unsigned int counter , const void * data ) {
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-07-24 15:44:49 +02:00
static int nonce_function_test_fail ( unsigned char * nonce32 , const unsigned char * msg32 , const unsigned char * key32 , const unsigned char * algo16 , unsigned int counter , const void * data ) {
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-07-24 15:44:49 +02:00
return nonce_function_rfc6979 ( nonce32 , msg32 , key32 , algo16 , counter - 1 , data ) ;
2015-01-04 17:26:51 -08:00
}
2015-07-24 15:44:49 +02:00
static int nonce_function_test_retry ( unsigned char * nonce32 , const unsigned char * msg32 , const unsigned char * key32 , const unsigned char * algo16 , unsigned int counter , const void * data ) {
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-07-24 15:44:49 +02:00
return nonce_function_rfc6979 ( nonce32 , msg32 , key32 , algo16 , counter - 5 , data ) ;
2015-01-04 17:26:51 -08:00
}
2015-07-26 16:00:55 +02:00
int is_empty_signature ( const secp256k1_ecdsa_signature_t * sig ) {
static const unsigned char res [ sizeof ( secp256k1_ecdsa_signature_t ) ] = { 0 } ;
return memcmp ( sig , res , sizeof ( secp256k1_ecdsa_signature_t ) ) = = 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-07-26 16:00:55 +02:00
secp256k1_ecdsa_signature_t signature [ 5 ] ;
unsigned char sig [ 74 ] ;
int siglen = 74 ;
2015-07-20 13:36:55 -04:00
unsigned char pubkeyc [ 65 ] ;
int pubkeyclen = 65 ;
secp256k1_pubkey_t pubkey ;
2015-01-25 15:47:04 +00:00
unsigned char seckey [ 300 ] ;
int 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
{
2014-11-27 19:12:13 +01:00
secp256k1_scalar_t msg , key ;
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. */
CHECK ( secp256k1_ec_pubkey_serialize ( ctx , pubkeyc , & pubkeyclen , & pubkey , secp256k1_rand32 ( ) % 2 ) = = 1 ) ;
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-02-03 17:27:00 -08:00
CHECK ( secp256k1_ec_privkey_export ( ctx , privkey , seckey , & seckeylen , secp256k1_rand32 ( ) % 2 ) = = 1 ) ;
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. */
2014-08-03 19:54:41 +02:00
if ( secp256k1_rand32 ( ) % 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-07-20 13:36:55 -04:00
secp256k1_pubkey_t 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. */
2014-08-03 19:54:41 +02:00
if ( secp256k1_rand32 ( ) % 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-07-20 13:36:55 -04:00
secp256k1_pubkey_t 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-07-26 16:00:55 +02:00
CHECK ( secp256k1_ecdsa_sign ( ctx , message , & signature [ 0 ] , privkey , NULL , NULL ) = = 1 ) ;
CHECK ( secp256k1_ecdsa_sign ( ctx , message , & signature [ 4 ] , privkey , NULL , NULL ) = = 1 ) ;
CHECK ( secp256k1_ecdsa_sign ( ctx , message , & signature [ 1 ] , privkey , NULL , extra ) = = 1 ) ;
2015-03-27 11:55:17 +00:00
extra [ 31 ] = 1 ;
2015-07-26 16:00:55 +02:00
CHECK ( secp256k1_ecdsa_sign ( ctx , message , & signature [ 2 ] , privkey , NULL , extra ) = = 1 ) ;
2015-03-27 11:55:17 +00:00
extra [ 31 ] = 0 ;
extra [ 0 ] = 1 ;
2015-07-26 16:00:55 +02:00
CHECK ( secp256k1_ecdsa_sign ( ctx , message , & signature [ 3 ] , privkey , NULL , extra ) = = 1 ) ;
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-07-26 16:00:55 +02:00
CHECK ( secp256k1_ecdsa_verify ( ctx , message , & signature [ 0 ] , & pubkey ) = = 1 ) ;
CHECK ( secp256k1_ecdsa_verify ( ctx , message , & signature [ 1 ] , & pubkey ) = = 1 ) ;
CHECK ( secp256k1_ecdsa_verify ( ctx , message , & signature [ 2 ] , & pubkey ) = = 1 ) ;
CHECK ( secp256k1_ecdsa_verify ( ctx , message , & signature [ 3 ] , & pubkey ) = = 1 ) ;
/* 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 ) ;
CHECK ( secp256k1_ecdsa_verify ( ctx , message , & signature [ 0 ] , & pubkey ) = = 1 ) ;
/* Serialize/destroy/parse DER and verify again. */
CHECK ( secp256k1_ecdsa_signature_serialize_der ( ctx , sig , & siglen , & signature [ 0 ] ) = = 1 ) ;
sig [ secp256k1_rand32 ( ) % siglen ] + = 1 + ( secp256k1_rand32 ( ) % 255 ) ;
CHECK ( secp256k1_ecdsa_signature_parse_der ( ctx , & signature [ 0 ] , sig , siglen ) = = 0 | |
secp256k1_ecdsa_verify ( ctx , message , & signature [ 0 ] , & pubkey ) = = 0 ) ;
2015-08-27 03:19:27 +02:00
}
2014-12-08 12:38:16 -08:00
void test_random_pubkeys ( void ) {
2015-01-25 15:47:04 +00:00
secp256k1_ge_t elem ;
secp256k1_ge_t elem2 ;
2014-12-08 12:38:16 -08:00
unsigned char in [ 65 ] ;
/* Generate some randomly sized pubkeys. */
uint32_t r = secp256k1_rand32 ( ) ;
int len = ( r & 3 ) = = 0 ? 65 : 33 ;
r > > = 2 ;
2015-03-27 23:14:17 +00:00
if ( ( r & 3 ) = = 0 ) {
len = ( r & 252 ) > > 3 ;
}
2014-12-08 12:38:16 -08:00
r > > = 8 ;
if ( len = = 65 ) {
in [ 0 ] = ( r & 2 ) ? 4 : ( r & 1 ? 6 : 7 ) ;
} else {
in [ 0 ] = ( r & 1 ) ? 2 : 3 ;
}
r > > = 2 ;
2015-03-27 23:14:17 +00:00
if ( ( r & 7 ) = = 0 ) {
in [ 0 ] = ( r & 2040 ) > > 3 ;
}
2014-12-08 12:38:16 -08:00
r > > = 11 ;
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 ;
int size = len ;
firstb = in [ 0 ] ;
/* If the pubkey can be parsed, it should round-trip... */
CHECK ( secp256k1_eckey_pubkey_serialize ( & elem , out , & size , len = = 33 ) ) ;
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. */
in [ 0 ] = ( r & 1 ) ? 6 : 7 ;
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 ( ) ;
}
}
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 ;
secp256k1_ecdsa_signature_t sig ;
/* Test the case where ECDSA recomputes a point that is infinity. */
{
secp256k1_gej_t keyj ;
secp256k1_ge_t key ;
secp256k1_scalar_t msg ;
secp256k1_scalar_t sr , ss ;
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 ] ;
int siglen ;
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 ,
} ;
CHECK ( secp256k1_ecdsa_sign ( ctx , msg , & sig , key , precomputed_nonce_function , nonce ) = = 0 ) ;
CHECK ( secp256k1_ecdsa_sign ( ctx , msg , & sig , key , precomputed_nonce_function , nonce2 ) = = 0 ) ;
msg [ 31 ] = 0xaa ;
CHECK ( secp256k1_ecdsa_sign ( ctx , msg , & sig , key , precomputed_nonce_function , nonce ) = = 1 ) ;
CHECK ( secp256k1_ecdsa_sign ( ctx , msg , & sig , key , precomputed_nonce_function , nonce2 ) = = 1 ) ;
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 ] ;
secp256k1_ecdsa_signature_t sig2 ;
secp256k1_scalar_t sr [ 512 ] , ss ;
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 ) ;
CHECK ( secp256k1_ecdsa_sign ( ctx , msg , & sig , key , NULL , extra ) = = 0 ) ;
CHECK ( is_empty_signature ( & sig ) ) ;
/* Zero key results in signature failure. */
memset ( key , 0 , 32 ) ;
CHECK ( secp256k1_ecdsa_sign ( ctx , msg , & sig , key , NULL , extra ) = = 0 ) ;
CHECK ( is_empty_signature ( & sig ) ) ;
/* Nonce function failure results in signature failure. */
key [ 31 ] = 1 ;
CHECK ( secp256k1_ecdsa_sign ( ctx , msg , & sig , key , nonce_function_test_fail , extra ) = = 0 ) ;
CHECK ( is_empty_signature ( & sig ) ) ;
/* The retry loop successfully makes its way to the first good value. */
CHECK ( secp256k1_ecdsa_sign ( ctx , msg , & sig , key , nonce_function_test_retry , extra ) = = 1 ) ;
CHECK ( ! is_empty_signature ( & sig ) ) ;
CHECK ( secp256k1_ecdsa_sign ( ctx , msg , & sig2 , key , nonce_function_rfc6979 , extra ) = = 1 ) ;
CHECK ( ! is_empty_signature ( & sig2 ) ) ;
CHECK ( memcmp ( & sig , & sig2 , sizeof ( sig ) ) = = 0 ) ;
/* The default nonce function is determinstic. */
CHECK ( secp256k1_ecdsa_sign ( ctx , msg , & sig2 , key , NULL , extra ) = = 1 ) ;
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 ;
CHECK ( secp256k1_ecdsa_sign ( ctx , msg , & sig2 , key , NULL , extra ) = = 1 ) ;
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 ;
CHECK ( secp256k1_ecdsa_sign ( ctx , msg , & sig2 , key , NULL , extra ) = = 1 ) ;
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 ,
} ;
int outlen = 300 ;
CHECK ( ! secp256k1_ec_privkey_export ( ctx , seckey , privkey , & outlen , 0 ) ) ;
CHECK ( ! secp256k1_ec_privkey_export ( ctx , seckey , privkey , & outlen , 1 ) ) ;
}
}
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
2014-10-28 04:08:15 -07:00
EC_KEY * get_openssl_key ( const secp256k1_scalar_t * key ) {
2013-05-10 00:53:47 +02:00
unsigned char privkey [ 300 ] ;
int privkeylen ;
const unsigned char * pbegin = privkey ;
2015-01-25 15:47:04 +00:00
int compr = secp256k1_rand32 ( ) & 1 ;
2013-05-05 16:55:05 +02:00
EC_KEY * ec_key = EC_KEY_new_by_curve_name ( NID_secp256k1 ) ;
2015-02-03 17:27:00 -08:00
CHECK ( secp256k1_eckey_privkey_serialize ( & ctx - > ecmult_gen_ctx , privkey , & privkeylen , key , compr ) ) ;
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-01-25 15:47:04 +00:00
secp256k1_gej_t qj ;
secp256k1_ge_t q ;
2015-07-26 16:51:58 +02:00
secp256k1_scalar_t sigr , sigs ;
2015-01-25 15:47:04 +00:00
secp256k1_scalar_t one ;
secp256k1_scalar_t msg2 ;
2014-10-28 04:08:15 -07:00
secp256k1_scalar_t key , msg ;
2015-01-25 15:47:04 +00:00
EC_KEY * ec_key ;
unsigned int sigsize = 80 ;
int 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 ) ;
2014-06-16 01:30:17 +02:00
CHECK ( ec_key ) ;
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-02-14 15:30:58 -08:00
if ( ! frand | | ! fread ( & seed16 , sizeof ( seed16 ) , 1 , frand ) ) {
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 ) ;
2014-12-04 01:04:00 -08:00
2015-04-15 21:35:50 +00:00
if ( secp256k1_rand32 ( ) & 1 ) {
secp256k1_rand256 ( run32 ) ;
CHECK ( secp256k1_context_randomize ( ctx , secp256k1_rand32 ( ) & 1 ? run32 : NULL ) ) ;
}
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-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 ( ) ;
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 ) ;
2013-03-10 21:25:19 +01:00
return 0 ;
}