@ -23,23 +23,13 @@
static int count = 64 ;
static int count = 64 ;
/***** NUM TESTS *****/
void random_num_negate ( secp256k1_num_t * num ) {
if ( secp256k1_rand32 ( ) & 1 )
secp256k1_num_negate ( num ) ;
}
void random_field_element_test ( secp256k1_fe_t * fe ) {
void random_field_element_test ( secp256k1_fe_t * fe ) {
do {
do {
unsigned char b32 [ 32 ] ;
unsigned char b32 [ 32 ] ;
secp256k1_rand256_test ( b32 ) ;
secp256k1_rand256_test ( b32 ) ;
secp256k1_num_t num ;
if ( secp256k1_fe_set_b32 ( fe , b32 ) ) {
secp256k1_num_set_bin ( & num , b32 , 32 ) ;
if ( secp256k1_num_cmp ( & num , & secp256k1_fe_consts - > p ) > = 0 )
continue ;
secp256k1_fe_set_b32 ( fe , b32 ) ;
break ;
break ;
}
} while ( 1 ) ;
} while ( 1 ) ;
}
}
@ -75,19 +65,6 @@ void random_group_element_jacobian_test(secp256k1_gej_t *gej, const secp256k1_ge
gej - > infinity = ge - > infinity ;
gej - > infinity = ge - > infinity ;
}
}
void random_num_order_test ( secp256k1_num_t * num ) {
do {
unsigned char b32 [ 32 ] ;
secp256k1_rand256_test ( b32 ) ;
secp256k1_num_set_bin ( num , b32 , 32 ) ;
if ( secp256k1_num_is_zero ( num ) )
continue ;
if ( secp256k1_num_cmp ( num , & secp256k1_ge_consts - > order ) > = 0 )
continue ;
break ;
} while ( 1 ) ;
}
void random_scalar_order_test ( secp256k1_scalar_t * num ) {
void random_scalar_order_test ( secp256k1_scalar_t * num ) {
do {
do {
unsigned char b32 [ 32 ] ;
unsigned char b32 [ 32 ] ;
@ -100,82 +77,36 @@ void random_scalar_order_test(secp256k1_scalar_t *num) {
} while ( 1 ) ;
} while ( 1 ) ;
}
}
void random_num_order ( secp256k1_num _t * num ) {
void random_scalar_order ( secp256k1_scalar _t * num ) {
do {
do {
unsigned char b32 [ 32 ] ;
unsigned char b32 [ 32 ] ;
secp256k1_rand256 ( b32 ) ;
secp256k1_rand256 ( b32 ) ;
secp256k1_num_set_bin ( num , b32 , 32 ) ;
int overflow = 0 ;
if ( secp256k1_num_is_zero ( num ) )
secp256k1_scalar_set_b32 ( num , b32 , & overflow ) ;
continue ;
if ( overflow | | secp256k1_scalar_is_zero ( num ) )
if ( secp256k1_num_cmp ( num , & secp256k1_ge_consts - > order ) > = 0 )
continue ;
continue ;
break ;
break ;
} while ( 1 ) ;
} while ( 1 ) ;
}
}
void test_num_copy_inc_cmp ( void ) {
/***** NUM TESTS *****/
secp256k1_num_t n1 , n2 ;
random_num_order ( & n1 ) ;
secp256k1_num_copy ( & n2 , & n1 ) ;
CHECK ( secp256k1_num_eq ( & n1 , & n2 ) ) ;
CHECK ( secp256k1_num_eq ( & n2 , & n1 ) ) ;
secp256k1_num_inc ( & n2 ) ;
CHECK ( ! secp256k1_num_eq ( & n1 , & n2 ) ) ;
CHECK ( ! secp256k1_num_eq ( & n2 , & n1 ) ) ;
}
void test_num_get_set_hex ( void ) {
# ifndef USE_NUM_NONE
secp256k1_num_t n1 , n2 ;
void random_num_negate ( secp256k1_num_t * num ) {
random_num_order_test ( & n1 ) ;
if ( secp256k1_rand32 ( ) & 1 )
char c [ 64 ] ;
secp256k1_num_negate ( num ) ;
secp256k1_num_get_hex ( c , 64 , & n1 ) ;
secp256k1_num_set_hex ( & n2 , c , 64 ) ;
CHECK ( secp256k1_num_eq ( & n1 , & n2 ) ) ;
for ( int i = 0 ; i < 64 ; i + + ) {
/* check whether the lower 4 bits correspond to the last hex character */
int low1 = secp256k1_num_shift ( & n1 , 4 ) ;
int lowh = c [ 63 ] ;
int low2 = ( ( lowh > > 6 ) * 9 + ( lowh - ' 0 ' ) ) & 15 ;
CHECK ( low1 = = low2 ) ;
/* shift bits off the hex representation, and compare */
memmove ( c + 1 , c , 63 ) ;
c [ 0 ] = ' 0 ' ;
secp256k1_num_set_hex ( & n2 , c , 64 ) ;
CHECK ( secp256k1_num_eq ( & n1 , & n2 ) ) ;
}
}
}
void test_num_get_set_bin ( void ) {
void random_num_order_test ( secp256k1_num_t * num ) {
secp256k1_num_t n1 , n2 ;
secp256k1_scalar_t sc ;
random_num_order_test ( & n1 ) ;
random_scalar_order_test ( & sc ) ;
unsigned char c [ 32 ] ;
secp256k1_scalar_get_num ( num , & sc ) ;
secp256k1_num_get_bin ( c , 32 , & n1 ) ;
secp256k1_num_set_bin ( & n2 , c , 32 ) ;
CHECK ( secp256k1_num_eq ( & n1 , & n2 ) ) ;
for ( int i = 0 ; i < 32 ; i + + ) {
/* check whether the lower 8 bits correspond to the last byte */
int low1 = secp256k1_num_shift ( & n1 , 8 ) ;
int low2 = c [ 31 ] ;
CHECK ( low1 = = low2 ) ;
/* shift bits off the byte representation, and compare */
memmove ( c + 1 , c , 31 ) ;
c [ 0 ] = 0 ;
secp256k1_num_set_bin ( & n2 , c , 32 ) ;
CHECK ( secp256k1_num_eq ( & n1 , & n2 ) ) ;
}
}
}
void run_num_int ( void ) {
void random_num_order ( secp256k1_num_t * num ) {
secp256k1_num_t n1 ;
secp256k1_scalar_t sc ;
for ( int i = - 255 ; i < 256 ; i + + ) {
random_scalar_order ( & sc ) ;
unsigned char c1 [ 3 ] = { } ;
secp256k1_scalar_get_num ( num , & sc ) ;
c1 [ 2 ] = abs ( i ) ;
unsigned char c2 [ 3 ] = { 0x11 , 0x22 , 0x33 } ;
secp256k1_num_set_int ( & n1 , i ) ;
secp256k1_num_get_bin ( c2 , 3 , & n1 ) ;
CHECK ( memcmp ( c1 , c2 , 3 ) = = 0 ) ;
}
}
}
void test_num_negate ( void ) {
void test_num_negate ( void ) {
@ -229,82 +160,84 @@ void test_num_add_sub(void) {
void run_num_smalltests ( void ) {
void run_num_smalltests ( void ) {
for ( int i = 0 ; i < 100 * count ; i + + ) {
for ( int i = 0 ; i < 100 * count ; i + + ) {
test_num_copy_inc_cmp ( ) ;
test_num_get_set_hex ( ) ;
test_num_get_set_bin ( ) ;
test_num_negate ( ) ;
test_num_negate ( ) ;
test_num_add_sub ( ) ;
test_num_add_sub ( ) ;
}
}
run_num_int ( ) ;
}
}
# endif
/***** SCALAR TESTS *****/
/***** SCALAR TESTS *****/
int secp256k1_scalar_eq ( const secp256k1_scalar_t * s1 , const secp256k1_scalar_t * s2 ) {
secp256k1_scalar_t t ;
secp256k1_scalar_negate ( & t , s2 ) ;
secp256k1_scalar_add ( & t , & t , s1 ) ;
int ret = secp256k1_scalar_is_zero ( & t ) ;
return ret ;
}
void scalar_test ( void ) {
void scalar_test ( void ) {
unsigned char c [ 32 ] ;
unsigned char c [ 32 ] ;
/* Set 's' to a random scalar, with value 'snum'. */
/* Set 's' to a random scalar, with value 'snum'. */
secp256k1_rand256_test ( c ) ;
secp256k1_scalar_t s ;
secp256k1_scalar_t s ;
secp256k1_scalar_set_b32 ( & s , c , NULL ) ;
random_scalar_order_test ( & s ) ;
secp256k1_num_t snum ;
secp256k1_num_set_bin ( & snum , c , 32 ) ;
secp256k1_num_mod ( & snum , & secp256k1_ge_consts - > order ) ;
/* Set 's1' to a random scalar, with value 's1num'. */
/* Set 's1' to a random scalar, with value 's1num'. */
secp256k1_rand256_test ( c ) ;
secp256k1_scalar_t s1 ;
secp256k1_scalar_t s1 ;
secp256k1_scalar_set_b32 ( & s1 , c , NULL ) ;
random_scalar_order_test ( & s1 ) ;
secp256k1_num_t s1num ;
secp256k1_num_set_bin ( & s1num , c , 32 ) ;
secp256k1_num_mod ( & s1num , & secp256k1_ge_consts - > order ) ;
/* Set 's2' to a random scalar, with value 'snum2', and byte array representation 'c'. */
/* Set 's2' to a random scalar, with value 'snum2', and byte array representation 'c'. */
secp256k1_rand256_test ( c ) ;
secp256k1_scalar_t s2 ;
secp256k1_scalar_t s2 ;
int overflow = 0 ;
random_scalar_order_test ( & s2 ) ;
secp256k1_scalar_set_b32 ( & s2 , c , & overflow ) ;
secp256k1_scalar_get_b32 ( c , & s2 ) ;
secp256k1_num_t s2num ;
secp256k1_num_set_bin ( & s2num , c , 32 ) ;
# ifndef USE_NUM_NONE
secp256k1_num_mod ( & s2num , & secp256k1_ge_consts - > order ) ;
secp256k1_num_t snum , s1num , s2num ;
secp256k1_scalar_get_num ( & snum , & s ) ;
secp256k1_scalar_get_num ( & s1num , & s1 ) ;
secp256k1_scalar_get_num ( & s2num , & s2 ) ;
secp256k1_num_t order ;
secp256k1_scalar_order_get_num ( & order ) ;
secp256k1_num_t half_order = order ;
secp256k1_num_shift ( & half_order , 1 ) ;
# endif
{
{
/* Test that fetching groups of 4 bits from a scalar and recursing n(i)=16*n(i-1)+p(i) reconstructs it. */
/* Test that fetching groups of 4 bits from a scalar and recursing n(i)=16*n(i-1)+p(i) reconstructs it. */
secp256k1_num_t n , t , m ;
secp256k1_scalar_t n ;
secp256k1_num_set_int ( & n , 0 ) ;
secp256k1_scalar_set_int ( & n , 0 ) ;
secp256k1_num_set_int ( & m , 16 ) ;
for ( int i = 0 ; i < 256 ; i + = 4 ) {
for ( int i = 0 ; i < 256 ; i + = 4 ) {
secp256k1_num_set_int ( & t , secp256k1_scalar_get_bits ( & s , 256 - 4 - i , 4 ) ) ;
secp256k1_scalar_t t ;
secp256k1_num_mul ( & n , & n , & m ) ;
secp256k1_scalar_set_int ( & t , secp256k1_scalar_get_bits ( & s , 256 - 4 - i , 4 ) ) ;
secp256k1_num_add ( & n , & n , & t ) ;
for ( int j = 0 ; j < 4 ; j + + ) {
secp256k1_scalar_add ( & n , & n , & n ) ;
}
secp256k1_scalar_add ( & n , & n , & t ) ;
}
}
CHECK ( secp256k1_num_eq ( & n , & snum ) ) ;
CHECK ( secp256k1_scalar _eq ( & n , & s ) ) ;
}
}
{
{
/* Test that get_b32 returns the same as get_bin on the number. */
/* Test that fetching groups of randomly-sized bits from a scalar and recursing n(i)=b*n(i-1)+p(i) reconstructs it. */
unsigned char r1 [ 32 ] ;
secp256k1_scalar_t n ;
secp256k1_scalar_get_b32 ( r1 , & s2 ) ;
secp256k1_scalar_set_int ( & n , 0 ) ;
unsigned char r2 [ 32 ] ;
int i = 0 ;
secp256k1_num_get_bin ( r2 , 32 , & s2num ) ;
while ( i < 256 ) {
CHECK ( memcmp ( r1 , r2 , 32 ) = = 0 ) ;
int now = ( secp256k1_rand32 ( ) % 15 ) + 1 ;
/* If no overflow occurred when assigning, it should also be equal to the original byte array. */
if ( now + i > 256 ) {
CHECK ( ( memcmp ( r1 , c , 32 ) = = 0 ) = = ( overflow = = 0 ) ) ;
now = 256 - i ;
}
secp256k1_scalar_t t ;
secp256k1_scalar_set_int ( & t , secp256k1_scalar_get_bits_var ( & s , 256 - now - i , now ) ) ;
for ( int j = 0 ; j < now ; j + + ) {
secp256k1_scalar_add ( & n , & n , & n ) ;
}
secp256k1_scalar_add ( & n , & n , & t ) ;
i + = now ;
}
CHECK ( secp256k1_scalar_eq ( & n , & s ) ) ;
}
}
# ifndef USE_NUM_NONE
{
{
/* Test that adding the scalars together is equal to adding their numbers together modulo the order. */
/* Test that adding the scalars together is equal to adding their numbers together modulo the order. */
secp256k1_num_t rnum ;
secp256k1_num_t rnum ;
secp256k1_num_add ( & rnum , & snum , & s2num ) ;
secp256k1_num_add ( & rnum , & snum , & s2num ) ;
secp256k1_num_mod ( & rnum , & secp256k1_ge_consts - > order ) ;
secp256k1_num_mod ( & rnum , & order ) ;
secp256k1_scalar_t r ;
secp256k1_scalar_t r ;
secp256k1_scalar_add ( & r , & s , & s2 ) ;
secp256k1_scalar_add ( & r , & s , & s2 ) ;
secp256k1_num_t r2num ;
secp256k1_num_t r2num ;
@ -316,7 +249,7 @@ void scalar_test(void) {
/* Test that multipying the scalars is equal to multiplying their numbers modulo the order. */
/* Test that multipying the scalars is equal to multiplying their numbers modulo the order. */
secp256k1_num_t rnum ;
secp256k1_num_t rnum ;
secp256k1_num_mul ( & rnum , & snum , & s2num ) ;
secp256k1_num_mul ( & rnum , & snum , & s2num ) ;
secp256k1_num_mod ( & rnum , & secp256k1_ge_consts - > order ) ;
secp256k1_num_mod ( & rnum , & order ) ;
secp256k1_scalar_t r ;
secp256k1_scalar_t r ;
secp256k1_scalar_mul ( & r , & s , & s2 ) ;
secp256k1_scalar_mul ( & r , & s , & s2 ) ;
secp256k1_num_t r2num ;
secp256k1_num_t r2num ;
@ -333,14 +266,14 @@ void scalar_test(void) {
/* Check that comparison with zero matches comparison with zero on the number. */
/* Check that comparison with zero matches comparison with zero on the number. */
CHECK ( secp256k1_num_is_zero ( & snum ) = = secp256k1_scalar_is_zero ( & s ) ) ;
CHECK ( secp256k1_num_is_zero ( & snum ) = = secp256k1_scalar_is_zero ( & s ) ) ;
/* Check that comparison with the half order is equal to testing for high scalar. */
/* Check that comparison with the half order is equal to testing for high scalar. */
CHECK ( secp256k1_scalar_is_high ( & s ) = = ( secp256k1_num_cmp ( & snum , & secp256k1_ge_consts - > half_order ) > 0 ) ) ;
CHECK ( secp256k1_scalar_is_high ( & s ) = = ( secp256k1_num_cmp ( & snum , & half_order ) > 0 ) ) ;
secp256k1_scalar_t neg ;
secp256k1_scalar_t neg ;
secp256k1_scalar_negate ( & neg , & s ) ;
secp256k1_scalar_negate ( & neg , & s ) ;
secp256k1_num_t negnum ;
secp256k1_num_t negnum ;
secp256k1_num_sub ( & negnum , & secp256k1_ge_consts - > order , & snum ) ;
secp256k1_num_sub ( & negnum , & order , & snum ) ;
secp256k1_num_mod ( & negnum , & secp256k1_ge_consts - > order ) ;
secp256k1_num_mod ( & negnum , & order ) ;
/* Check that comparison with the half order is equal to testing for high scalar after negation. */
/* Check that comparison with the half order is equal to testing for high scalar after negation. */
CHECK ( secp256k1_scalar_is_high ( & neg ) = = ( secp256k1_num_cmp ( & negnum , & secp256k1_ge_consts - > half_order ) > 0 ) ) ;
CHECK ( secp256k1_scalar_is_high ( & neg ) = = ( secp256k1_num_cmp ( & negnum , & half_order ) > 0 ) ) ;
/* Negating should change the high property, unless the value was already zero. */
/* Negating should change the high property, unless the value was already zero. */
CHECK ( ( secp256k1_scalar_is_high ( & s ) = = secp256k1_scalar_is_high ( & neg ) ) = = secp256k1_scalar_is_zero ( & s ) ) ;
CHECK ( ( secp256k1_scalar_is_high ( & s ) = = secp256k1_scalar_is_high ( & neg ) ) = = secp256k1_scalar_is_zero ( & s ) ) ;
secp256k1_num_t negnum2 ;
secp256k1_num_t negnum2 ;
@ -355,16 +288,37 @@ void scalar_test(void) {
CHECK ( secp256k1_scalar_is_zero ( & neg ) ) ;
CHECK ( secp256k1_scalar_is_zero ( & neg ) ) ;
}
}
{
/* Test secp256k1_scalar_mul_shift_var. */
secp256k1_scalar_t r ;
unsigned int shift = 256 + ( secp256k1_rand32 ( ) % 257 ) ;
secp256k1_scalar_mul_shift_var ( & r , & s1 , & s2 , shift ) ;
secp256k1_num_t rnum ;
secp256k1_num_mul ( & rnum , & s1num , & s2num ) ;
secp256k1_num_shift ( & rnum , shift - 1 ) ;
secp256k1_num_t one ;
unsigned char cone [ 1 ] = { 0x01 } ;
secp256k1_num_set_bin ( & one , cone , 1 ) ;
secp256k1_num_add ( & rnum , & rnum , & one ) ;
secp256k1_num_shift ( & rnum , 1 ) ;
secp256k1_num_t rnum2 ;
secp256k1_scalar_get_num ( & rnum2 , & r ) ;
CHECK ( secp256k1_num_eq ( & rnum , & rnum2 ) ) ;
}
# endif
{
{
/* Test that scalar inverses are equal to the inverse of their number modulo the order. */
/* Test that scalar inverses are equal to the inverse of their number modulo the order. */
if ( ! secp256k1_scalar_is_zero ( & s ) ) {
if ( ! secp256k1_scalar_is_zero ( & s ) ) {
secp256k1_scalar_t inv ;
secp256k1_scalar_t inv ;
secp256k1_scalar_inverse ( & inv , & s ) ;
secp256k1_scalar_inverse ( & inv , & s ) ;
# ifndef USE_NUM_NONE
secp256k1_num_t invnum ;
secp256k1_num_t invnum ;
secp256k1_num_mod_inverse ( & invnum , & snum , & secp256k1_ge_consts - > order ) ;
secp256k1_num_mod_inverse ( & invnum , & snum , & order ) ;
secp256k1_num_t invnum2 ;
secp256k1_num_t invnum2 ;
secp256k1_scalar_get_num ( & invnum2 , & inv ) ;
secp256k1_scalar_get_num ( & invnum2 , & inv ) ;
CHECK ( secp256k1_num_eq ( & invnum , & invnum2 ) ) ;
CHECK ( secp256k1_num_eq ( & invnum , & invnum2 ) ) ;
# endif
secp256k1_scalar_mul ( & inv , & inv , & s ) ;
secp256k1_scalar_mul ( & inv , & inv , & s ) ;
/* Multiplying a scalar with its inverse must result in one. */
/* Multiplying a scalar with its inverse must result in one. */
CHECK ( secp256k1_scalar_is_one ( & inv ) ) ;
CHECK ( secp256k1_scalar_is_one ( & inv ) ) ;
@ -382,6 +336,23 @@ void scalar_test(void) {
CHECK ( secp256k1_scalar_eq ( & r1 , & r2 ) ) ;
CHECK ( secp256k1_scalar_eq ( & r1 , & r2 ) ) ;
}
}
{
/* Test add_bit. */
int bit = secp256k1_rand32 ( ) % 256 ;
secp256k1_scalar_t b ;
secp256k1_scalar_set_int ( & b , 1 ) ;
CHECK ( secp256k1_scalar_is_one ( & b ) ) ;
for ( int i = 0 ; i < bit ; i + + ) {
secp256k1_scalar_add ( & b , & b , & b ) ;
}
secp256k1_scalar_t r1 = s1 , r2 = s1 ;
if ( ! secp256k1_scalar_add ( & r1 , & r1 , & b ) ) {
/* No overflow happened. */
secp256k1_scalar_add_bit ( & r2 , bit ) ;
CHECK ( secp256k1_scalar_eq ( & r1 , & r2 ) ) ;
}
}
{
{
/* Test commutativity of mul. */
/* Test commutativity of mul. */
secp256k1_scalar_t r1 , r2 ;
secp256k1_scalar_t r1 , r2 ;
@ -428,20 +399,49 @@ void scalar_test(void) {
secp256k1_scalar_mul ( & r2 , & s1 , & s1 ) ;
secp256k1_scalar_mul ( & r2 , & s1 , & s1 ) ;
CHECK ( secp256k1_scalar_eq ( & r1 , & r2 ) ) ;
CHECK ( secp256k1_scalar_eq ( & r1 , & r2 ) ) ;
}
}
}
}
void run_scalar_tests ( void ) {
void run_scalar_tests ( void ) {
for ( int i = 0 ; i < 128 * count ; i + + ) {
for ( int i = 0 ; i < 128 * count ; i + + ) {
scalar_test ( ) ;
scalar_test ( ) ;
}
}
{
/* (-1)+1 should be zero. */
secp256k1_scalar_t s , o ;
secp256k1_scalar_set_int ( & s , 1 ) ;
secp256k1_scalar_negate ( & o , & s ) ;
secp256k1_scalar_add ( & o , & o , & s ) ;
CHECK ( secp256k1_scalar_is_zero ( & o ) ) ;
}
# ifndef USE_NUM_NONE
{
/* A scalar with value of the curve order should be 0. */
secp256k1_num_t order ;
secp256k1_scalar_order_get_num ( & order ) ;
unsigned char bin [ 32 ] ;
secp256k1_num_get_bin ( bin , 32 , & order ) ;
secp256k1_scalar_t zero ;
int overflow = 0 ;
secp256k1_scalar_set_b32 ( & zero , bin , & overflow ) ;
CHECK ( overflow = = 1 ) ;
CHECK ( secp256k1_scalar_is_zero ( & zero ) ) ;
}
# endif
}
}
/***** FIELD TESTS *****/
/***** FIELD TESTS *****/
void random_fe ( secp256k1_fe_t * x ) {
void random_fe ( secp256k1_fe_t * x ) {
unsigned char bin [ 32 ] ;
unsigned char bin [ 32 ] ;
do {
secp256k1_rand256 ( bin ) ;
secp256k1_rand256 ( bin ) ;
secp256k1_fe_set_b32 ( x , bin ) ;
if ( secp256k1_fe_set_b32 ( x , bin ) ) {
return ;
}
} while ( 1 ) ;
}
}
void random_fe_non_zero ( secp256k1_fe_t * nz ) {
void random_fe_non_zero ( secp256k1_fe_t * nz ) {
@ -617,9 +617,17 @@ void gej_equals_gej(const secp256k1_gej_t *a, const secp256k1_gej_t *b) {
}
}
void test_ge ( void ) {
void test_ge ( void ) {
char ca [ 135 ] ;
char cb [ 68 ] ;
int rlen ;
secp256k1_ge_t a , b , i , n ;
secp256k1_ge_t a , b , i , n ;
random_group_element_test ( & a ) ;
random_group_element_test ( & a ) ;
random_group_element_test ( & b ) ;
random_group_element_test ( & b ) ;
rlen = sizeof ( ca ) ;
secp256k1_ge_get_hex ( ca , & rlen , & a ) ;
CHECK ( rlen > 4 & & rlen < = ( int ) sizeof ( ca ) ) ;
rlen = sizeof ( cb ) ;
secp256k1_ge_get_hex ( cb , & rlen , & b ) ; /* Intentionally undersized buffer. */
n = a ;
n = a ;
secp256k1_fe_normalize ( & a . y ) ;
secp256k1_fe_normalize ( & a . y ) ;
secp256k1_fe_negate ( & n . y , & a . y , 1 ) ;
secp256k1_fe_negate ( & n . y , & a . y , 1 ) ;
@ -697,39 +705,51 @@ void run_ge(void) {
void run_ecmult_chain ( void ) {
void run_ecmult_chain ( void ) {
/* random starting point A (on the curve) */
/* random starting point A (on the curve) */
secp256k1_fe_t ax ; secp256k1_fe_set_hex ( & ax , " 8b30bbe9ae2a990696b22f670709dff3727fd8bc04d3362c6c7bf458e2846004 " , 64 ) ;
secp256k1_fe_t ax ; VERIFY_CHECK ( secp256k1_fe_set_hex ( & ax , " 8b30bbe9ae2a990696b22f670709dff3727fd8bc04d3362c6c7bf458e2846004 " , 64 ) ) ;
secp256k1_fe_t ay ; secp256k1_fe_set_hex ( & ay , " a357ae915c4a65281309edf20504740f0eb3343990216b4f81063cb65f2f7e0f " , 64 ) ;
secp256k1_fe_t ay ; VERIFY_CHECK ( secp256k1_fe_set_hex ( & ay , " a357ae915c4a65281309edf20504740f0eb3343990216b4f81063cb65f2f7e0f " , 64 ) ) ;
secp256k1_gej_t a ; secp256k1_gej_set_xy ( & a , & ax , & ay ) ;
secp256k1_gej_t a ; secp256k1_gej_set_xy ( & a , & ax , & ay ) ;
/* two random initial factors xn and gn */
/* two random initial factors xn and gn */
secp256k1_num_t xn ;
static const unsigned char xni [ 32 ] = {
secp256k1_num_set_hex ( & xn , " 84cc5452f7fde1edb4d38a8ce9b1b84ccef31f146e569be9705d357a42985407 " , 64 ) ;
0x84 , 0xcc , 0x54 , 0x52 , 0xf7 , 0xfd , 0xe1 , 0xed ,
secp256k1_num_t gn ;
0xb4 , 0xd3 , 0x8a , 0x8c , 0xe9 , 0xb1 , 0xb8 , 0x4c ,
secp256k1_num_set_hex ( & gn , " a1e58d22553dcd42b23980625d4c57a96e9323d42b3152e5ca2c3990edc7c9de " , 64 ) ;
0xce , 0xf3 , 0x1f , 0x14 , 0x6e , 0x56 , 0x9b , 0xe9 ,
0x70 , 0x5d , 0x35 , 0x7a , 0x42 , 0x98 , 0x54 , 0x07
} ;
secp256k1_scalar_t xn ;
secp256k1_scalar_set_b32 ( & xn , xni , NULL ) ;
static const unsigned char gni [ 32 ] = {
0xa1 , 0xe5 , 0x8d , 0x22 , 0x55 , 0x3d , 0xcd , 0x42 ,
0xb2 , 0x39 , 0x80 , 0x62 , 0x5d , 0x4c , 0x57 , 0xa9 ,
0x6e , 0x93 , 0x23 , 0xd4 , 0x2b , 0x31 , 0x52 , 0xe5 ,
0xca , 0x2c , 0x39 , 0x90 , 0xed , 0xc7 , 0xc9 , 0xde
} ;
secp256k1_scalar_t gn ;
secp256k1_scalar_set_b32 ( & gn , gni , NULL ) ;
/* two small multipliers to be applied to xn and gn in every iteration: */
/* two small multipliers to be applied to xn and gn in every iteration: */
secp256k1_num_t xf ;
static const unsigned char xfi [ 32 ] = { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x13 , 0x37 } ;
secp256k1_num_set_hex ( & xf , " 1337 " , 4 ) ;
secp256k1_scalar_t xf ;
secp256k1_num_t gf ;
secp256k1_scalar_set_b32 ( & xf , xfi , NULL ) ;
secp256k1_num_set_hex ( & gf , " 7113 " , 4 ) ;
static const unsigned char gfi [ 32 ] = { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0x71 , 0x13 } ;
secp256k1_scalar_t gf ;
secp256k1_scalar_set_b32 ( & gf , gfi , NULL ) ;
/* accumulators with the resulting coefficients to A and G */
/* accumulators with the resulting coefficients to A and G */
secp256k1_num_t ae ;
secp256k1_scalar _t ae ;
secp256k1_num_set_int ( & ae , 1 ) ;
secp256k1_scalar _set_int ( & ae , 1 ) ;
secp256k1_num_t ge ;
secp256k1_scalar _t ge ;
secp256k1_num_set_int ( & ge , 0 ) ;
secp256k1_scalar _set_int ( & ge , 0 ) ;
/* the point being computed */
/* the point being computed */
secp256k1_gej_t x = a ;
secp256k1_gej_t x = a ;
const secp256k1_num_t * order = & secp256k1_ge_consts - > order ;
for ( int i = 0 ; i < 200 * count ; i + + ) {
for ( int i = 0 ; i < 200 * count ; i + + ) {
/* in each iteration, compute X = xn*X + gn*G; */
/* in each iteration, compute X = xn*X + gn*G; */
secp256k1_ecmult ( & x , & x , & xn , & gn ) ;
secp256k1_ecmult ( & x , & x , & xn , & gn ) ;
/* also compute ae and ge: the actual accumulated factors for A and G */
/* 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) */
/* if X was (ae*A+ge*G), xn*X + gn*G results in (xn*ae*A + (xn*ge+gn)*G) */
secp256k1_num_mod_mul ( & ae , & ae , & xn , order ) ;
secp256k1_scalar_mul ( & ae , & ae , & xn ) ;
secp256k1_num_mod_mul ( & ge , & ge , & xn , order ) ;
secp256k1_scalar_mul ( & ge , & ge , & xn ) ;
secp256k1_num_add ( & ge , & ge , & gn ) ;
secp256k1_scalar_add ( & ge , & ge , & gn ) ;
secp256k1_num_mod ( & ge , order ) ;
/* modify xn and gn */
/* modify xn and gn */
secp256k1_num_mod _mul ( & xn , & xn , & xf , order ) ;
secp256k1_scalar _mul ( & xn , & xn , & xf ) ;
secp256k1_num_mod _mul ( & gn , & gn , & gf , order ) ;
secp256k1_scalar _mul ( & gn , & gn , & gf ) ;
/* verify */
/* verify */
if ( i = = 19999 ) {
if ( i = = 19999 ) {
@ -749,17 +769,25 @@ void run_ecmult_chain(void) {
}
}
void test_point_times_order ( const secp256k1_gej_t * point ) {
void test_point_times_order ( const secp256k1_gej_t * point ) {
/* multiplying a point by the order results in O */
/* X * (point + G) + (order-X) * (pointer + G) = 0 */
const secp256k1_num_t * order = & secp256k1_ge_consts - > order ;
secp256k1_scalar_t x ;
secp256k1_num_t zero ;
random_scalar_order_test ( & x ) ;
secp256k1_num_set_int ( & zero , 0 ) ;
secp256k1_scalar_t nx ;
secp256k1_gej_t res ;
secp256k1_scalar_negate ( & nx , & x ) ;
secp256k1_ecmult ( & res , point , order , order ) ; /* calc res = order * point + order * G; */
secp256k1_gej_t res1 , res2 ;
CHECK ( secp256k1_gej_is_infinity ( & res ) ) ;
secp256k1_ecmult ( & res1 , point , & x , & x ) ; /* calc res1 = x * point + x * G; */
secp256k1_ecmult ( & res2 , point , & nx , & nx ) ; /* calc res2 = (order - x) * point + (order - x) * G; */
secp256k1_gej_add_var ( & res1 , & res1 , & res2 ) ;
CHECK ( secp256k1_gej_is_infinity ( & res1 ) ) ;
CHECK ( secp256k1_gej_is_valid ( & res1 ) = = 0 ) ;
secp256k1_ge_t res3 ;
secp256k1_ge_set_gej ( & res3 , & res1 ) ;
CHECK ( secp256k1_ge_is_infinity ( & res3 ) ) ;
CHECK ( secp256k1_ge_is_valid ( & res3 ) = = 0 ) ;
}
}
void run_point_times_order ( void ) {
void run_point_times_order ( void ) {
secp256k1_fe_t x ; secp256k1_fe_set_hex ( & x , " 02 " , 2 ) ;
secp256k1_fe_t x ; VERIFY_CHECK ( secp256k1_fe_set_hex ( & x , " 02 " , 2 ) ) ;
for ( int i = 0 ; i < 500 ; i + + ) {
for ( int i = 0 ; i < 500 ; i + + ) {
secp256k1_ge_t p ;
secp256k1_ge_t p ;
if ( secp256k1_ge_set_xo ( & p , & x , 1 ) ) {
if ( secp256k1_ge_set_xo ( & p , & x , 1 ) ) {
@ -776,15 +804,16 @@ void run_point_times_order(void) {
CHECK ( strcmp ( c , " 7603CB59B0EF6C63FE6084792A0C378CDB3233A80F8A9A09A877DEAD31B38C45 " ) = = 0 ) ;
CHECK ( strcmp ( c , " 7603CB59B0EF6C63FE6084792A0C378CDB3233A80F8A9A09A877DEAD31B38C45 " ) = = 0 ) ;
}
}
void test_wnaf ( const secp256k1_num _t * number , int w ) {
void test_wnaf ( const secp256k1_scalar _t * number , int w ) {
secp256k1_num _t x , two , t ;
secp256k1_scalar _t x , two , t ;
secp256k1_num _set_int ( & x , 0 ) ;
secp256k1_scalar _set_int ( & x , 0 ) ;
secp256k1_num _set_int ( & two , 2 ) ;
secp256k1_scalar _set_int ( & two , 2 ) ;
int wnaf [ 257 ] ;
int wnaf [ 256 ] ;
int bits = secp256k1_ecmult_wnaf ( wnaf , number , w ) ;
int bits = secp256k1_ecmult_wnaf ( wnaf , number , w ) ;
CHECK ( bits < = 256 ) ;
int zeroes = - 1 ;
int zeroes = - 1 ;
for ( int i = bits - 1 ; i > = 0 ; i - - ) {
for ( int i = bits - 1 ; i > = 0 ; i - - ) {
secp256k1_num _mul ( & x , & x , & two ) ;
secp256k1_scalar _mul ( & x , & x , & two ) ;
int v = wnaf [ i ] ;
int v = wnaf [ i ] ;
if ( v ) {
if ( v ) {
CHECK ( zeroes = = - 1 | | zeroes > = w - 1 ) ; /* check that distance between non-zero elements is at least w-1 */
CHECK ( zeroes = = - 1 | | zeroes > = w - 1 ) ; /* check that distance between non-zero elements is at least w-1 */
@ -796,18 +825,23 @@ void test_wnaf(const secp256k1_num_t *number, int w) {
CHECK ( zeroes ! = - 1 ) ; /* check that no unnecessary zero padding exists */
CHECK ( zeroes ! = - 1 ) ; /* check that no unnecessary zero padding exists */
zeroes + + ;
zeroes + + ;
}
}
secp256k1_num_set_int ( & t , v ) ;
if ( v > = 0 ) {
secp256k1_num_add ( & x , & x , & t ) ;
secp256k1_scalar_set_int ( & t , v ) ;
} else {
secp256k1_scalar_set_int ( & t , - v ) ;
secp256k1_scalar_negate ( & t , & t ) ;
}
secp256k1_scalar_add ( & x , & x , & t ) ;
}
}
CHECK ( secp256k1_num_eq ( & x , number ) ) ; /* check that wnaf represents number */
CHECK ( secp256k1_scalar _eq ( & x , number ) ) ; /* check that wnaf represents number */
}
}
void run_wnaf ( void ) {
void run_wnaf ( void ) {
secp256k1_num _t n ;
secp256k1_scalar _t n ;
for ( int i = 0 ; i < count ; i + + ) {
for ( int i = 0 ; i < count ; i + + ) {
random_num _order ( & n ) ;
random_scalar _order ( & n ) ;
if ( i % 1 )
if ( i % 1 )
secp256k1_num_negate ( & n ) ;
secp256k1_scalar_negate ( & n , & n ) ;
test_wnaf ( & n , 4 + ( i % 10 ) ) ;
test_wnaf ( & n , 4 + ( i % 10 ) ) ;
}
}
}
}
@ -820,18 +854,22 @@ void random_sign(secp256k1_ecdsa_sig_t *sig, const secp256k1_scalar_t *key, cons
}
}
void test_ecdsa_sign_verify ( void ) {
void test_ecdsa_sign_verify ( void ) {
int recid ;
int getrec ;
secp256k1_scalar_t msg , key ;
secp256k1_scalar_t msg , key ;
random_scalar_order_test ( & msg ) ;
random_scalar_order_test ( & msg ) ;
random_scalar_order_test ( & key ) ;
random_scalar_order_test ( & key ) ;
secp256k1_gej_t pubj ; secp256k1_ecmult_gen ( & pubj , & key ) ;
secp256k1_gej_t pubj ; secp256k1_ecmult_gen ( & pubj , & key ) ;
secp256k1_ge_t pub ; secp256k1_ge_set_gej ( & pub , & pubj ) ;
secp256k1_ge_t pub ; secp256k1_ge_set_gej ( & pub , & pubj ) ;
secp256k1_ecdsa_sig_t sig ;
secp256k1_ecdsa_sig_t sig ;
random_sign ( & sig , & key , & msg , NULL ) ;
getrec = secp256k1_rand32 ( ) & 1 ;
secp256k1_num_t msg_num ;
random_sign ( & sig , & key , & msg , getrec ? & recid : NULL ) ;
secp256k1_scalar_get_num ( & msg_num , & msg ) ;
if ( getrec ) CHECK ( recid > = 0 & & recid < 4 ) ;
CHECK ( secp256k1_ecdsa_sig_verify ( & sig , & pub , & msg_num ) ) ;
CHECK ( secp256k1_ecdsa_sig_verify ( & sig , & pub , & msg ) ) ;
secp256k1_num_inc ( & msg_num ) ;
secp256k1_scalar_t one ;
CHECK ( ! secp256k1_ecdsa_sig_verify ( & sig , & pub , & msg_num ) ) ;
secp256k1_scalar_set_int ( & one , 1 ) ;
secp256k1_scalar_add ( & msg , & msg , & one ) ;
CHECK ( ! secp256k1_ecdsa_sig_verify ( & sig , & pub , & msg ) ) ;
}
}
void run_ecdsa_sign_verify ( void ) {
void run_ecdsa_sign_verify ( void ) {
@ -846,11 +884,11 @@ void test_ecdsa_end_to_end(void) {
/* Generate a random key and message. */
/* Generate a random key and message. */
{
{
secp256k1_num _t msg , key ;
secp256k1_scalar _t msg , key ;
random_num _order_test ( & msg ) ;
random_scalar _order_test ( & msg ) ;
random_num _order_test ( & key ) ;
random_scalar _order_test ( & key ) ;
secp256k1_num_get_bin ( privkey , 32 , & key ) ;
secp256k1_scalar_get_b32 ( privkey , & key ) ;
secp256k1_num_get_bin ( message , 32 , & msg ) ;
secp256k1_scalar_get_b32 ( message , & msg ) ;
}
}
/* Construct and verify corresponding public key. */
/* Construct and verify corresponding public key. */
@ -935,7 +973,8 @@ void run_ecdsa_end_to_end(void) {
}
}
}
}
void test_ecdsa_infinity ( void ) {
/* Tests several edge cases. */
void test_ecdsa_edge_cases ( void ) {
const unsigned char msg32 [ 32 ] = {
const unsigned char msg32 [ 32 ] = {
' T ' , ' h ' , ' i ' , ' s ' , ' ' , ' i ' , ' s ' , ' ' ,
' T ' , ' h ' , ' i ' , ' s ' , ' ' , ' i ' , ' s ' , ' ' ,
' a ' , ' ' , ' v ' , ' e ' , ' r ' , ' y ' , ' ' , ' s ' ,
' a ' , ' ' , ' v ' , ' e ' , ' r ' , ' y ' , ' ' , ' s ' ,
@ -943,8 +982,8 @@ void test_ecdsa_infinity(void) {
' s ' , ' s ' , ' a ' , ' g ' , ' e ' , ' . ' , ' . ' , ' . '
' s ' , ' s ' , ' a ' , ' g ' , ' e ' , ' . ' , ' . ' , ' . '
} ;
} ;
const unsigned char sig64 [ 64 ] = {
const unsigned char sig64 [ 64 ] = {
// Generated by signing the above message with nonce 'This is the nonce we will use...'
/* Generated by signing the above message with nonce 'This is the nonce we will use...'
// and secret key 0 (which is not valid), resulting in recid 0.
* and secret key 0 ( which is not valid ) , resulting in recid 0. */
0x67 , 0xCB , 0x28 , 0x5F , 0x9C , 0xD1 , 0x94 , 0xE8 ,
0x67 , 0xCB , 0x28 , 0x5F , 0x9C , 0xD1 , 0x94 , 0xE8 ,
0x40 , 0xD6 , 0x29 , 0x39 , 0x7A , 0xF5 , 0x56 , 0x96 ,
0x40 , 0xD6 , 0x29 , 0x39 , 0x7A , 0xF5 , 0x56 , 0x96 ,
0x62 , 0xFD , 0xE4 , 0x46 , 0x49 , 0x99 , 0x59 , 0x63 ,
0x62 , 0xFD , 0xE4 , 0x46 , 0x49 , 0x99 , 0x59 , 0x63 ,
@ -960,10 +999,93 @@ void test_ecdsa_infinity(void) {
CHECK ( secp256k1_ecdsa_recover_compact ( msg32 , 32 , sig64 , pubkey , & pubkeylen , 0 , 1 ) ) ;
CHECK ( secp256k1_ecdsa_recover_compact ( msg32 , 32 , sig64 , pubkey , & pubkeylen , 0 , 1 ) ) ;
CHECK ( ! secp256k1_ecdsa_recover_compact ( msg32 , 32 , sig64 , pubkey , & pubkeylen , 0 , 2 ) ) ;
CHECK ( ! secp256k1_ecdsa_recover_compact ( msg32 , 32 , sig64 , pubkey , & pubkeylen , 0 , 2 ) ) ;
CHECK ( ! secp256k1_ecdsa_recover_compact ( msg32 , 32 , sig64 , pubkey , & pubkeylen , 0 , 3 ) ) ;
CHECK ( ! secp256k1_ecdsa_recover_compact ( msg32 , 32 , sig64 , pubkey , & pubkeylen , 0 , 3 ) ) ;
/* signature (r,s) = (4,4), which can be recovered with all 4 recids. */
const unsigned char sigb64 [ 64 ] = {
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 , 0x04 ,
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 , 0x04 ,
} ;
unsigned char pubkeyb [ 33 ] ;
int pubkeyblen = 33 ;
for ( int recid = 0 ; recid < 4 ; recid + + ) {
/* (4,4) encoded in DER. */
unsigned char sigbder [ 8 ] = { 0x30 , 0x06 , 0x02 , 0x01 , 0x04 , 0x02 , 0x01 , 0x04 } ;
/* (order + r,4) encoded in DER. */
unsigned char sigbderlong [ 40 ] = {
0x30 , 0x26 , 0x02 , 0x21 , 0x00 , 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 , 0x45 , 0x02 , 0x01 , 0x04
} ;
CHECK ( secp256k1_ecdsa_recover_compact ( msg32 , 32 , sigb64 , pubkeyb , & pubkeyblen , 1 , recid ) ) ;
CHECK ( secp256k1_ecdsa_verify ( msg32 , 32 , sigbder , sizeof ( sigbder ) , pubkeyb , pubkeyblen ) = = 1 ) ;
for ( int recid2 = 0 ; recid2 < 4 ; recid2 + + ) {
unsigned char pubkey2b [ 33 ] ;
int pubkey2blen = 33 ;
CHECK ( secp256k1_ecdsa_recover_compact ( msg32 , 32 , sigb64 , pubkey2b , & pubkey2blen , 1 , recid2 ) ) ;
/* Verifying with (order + r,4) should always fail. */
CHECK ( secp256k1_ecdsa_verify ( msg32 , 32 , sigbderlong , sizeof ( sigbderlong ) , pubkey2b , pubkey2blen ) ! = 1 ) ;
}
/* Damage signature. */
sigbder [ 7 ] + + ;
CHECK ( secp256k1_ecdsa_verify ( msg32 , 32 , sigbder , sizeof ( sigbder ) , pubkeyb , pubkeyblen ) = = 0 ) ;
}
/* Test the case where ECDSA recomputes a point that is infinity. */
{
secp256k1_ecdsa_sig_t sig ;
secp256k1_scalar_set_int ( & sig . s , 1 ) ;
secp256k1_scalar_negate ( & sig . s , & sig . s ) ;
secp256k1_scalar_inverse ( & sig . s , & sig . s ) ;
secp256k1_scalar_set_int ( & sig . r , 1 ) ;
secp256k1_gej_t keyj ;
secp256k1_ecmult_gen ( & keyj , & sig . r ) ;
secp256k1_ge_t key ;
secp256k1_ge_set_gej ( & key , & keyj ) ;
secp256k1_scalar_t msg = sig . s ;
CHECK ( secp256k1_ecdsa_sig_verify ( & sig , & key , & msg ) = = 0 ) ;
}
/* Test r/s equal to zero */
{
/* (1,1) encoded in DER. */
unsigned char sigcder [ 8 ] = { 0x30 , 0x06 , 0x02 , 0x01 , 0x01 , 0x02 , 0x01 , 0x01 } ;
unsigned char sigc64 [ 64 ] = {
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x01 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x01 ,
} ;
unsigned char pubkeyc [ 65 ] ;
int pubkeyclen = 65 ;
CHECK ( secp256k1_ecdsa_recover_compact ( msg32 , 32 , sigc64 , pubkeyc , & pubkeyclen , 0 , 0 ) = = 1 ) ;
CHECK ( secp256k1_ecdsa_verify ( msg32 , 32 , sigcder , sizeof ( sigcder ) , pubkeyc , pubkeyclen ) = = 1 ) ;
sigcder [ 4 ] = 0 ;
sigc64 [ 31 ] = 0 ;
CHECK ( secp256k1_ecdsa_recover_compact ( msg32 , 32 , sigc64 , pubkeyb , & pubkeyblen , 1 , 0 ) = = 0 ) ;
CHECK ( secp256k1_ecdsa_verify ( msg32 , 32 , sigcder , sizeof ( sigcder ) , pubkeyc , pubkeyclen ) = = 0 ) ;
sigcder [ 4 ] = 1 ;
sigcder [ 7 ] = 0 ;
sigc64 [ 31 ] = 1 ;
sigc64 [ 63 ] = 0 ;
CHECK ( secp256k1_ecdsa_recover_compact ( msg32 , 32 , sigc64 , pubkeyb , & pubkeyblen , 1 , 0 ) = = 0 ) ;
CHECK ( secp256k1_ecdsa_verify ( msg32 , 32 , sigcder , sizeof ( sigcder ) , pubkeyc , pubkeyclen ) = = 0 ) ;
}
}
}
void run_ecdsa_infinity ( void ) {
void run_ecdsa_edge_cases ( void ) {
test_ecdsa_infinity ( ) ;
test_ecdsa_edge_cases ( ) ;
}
}
# ifdef ENABLE_OPENSSL_TESTS
# ifdef ENABLE_OPENSSL_TESTS
@ -996,11 +1118,12 @@ void test_ecdsa_openssl(void) {
CHECK ( ECDSA_sign ( 0 , message , sizeof ( message ) , signature , & sigsize , ec_key ) ) ;
CHECK ( ECDSA_sign ( 0 , message , sizeof ( message ) , signature , & sigsize , ec_key ) ) ;
secp256k1_ecdsa_sig_t sig ;
secp256k1_ecdsa_sig_t sig ;
CHECK ( secp256k1_ecdsa_sig_parse ( & sig , signature , sigsize ) ) ;
CHECK ( secp256k1_ecdsa_sig_parse ( & sig , signature , sigsize ) ) ;
secp256k1_num_t msg_num ;
CHECK ( secp256k1_ecdsa_sig_verify ( & sig , & q , & msg ) ) ;
secp256k1_scalar_get_num ( & msg_num , & msg ) ;
secp256k1_scalar_t one ;
CHECK ( secp256k1_ecdsa_sig_verify ( & sig , & q , & msg_num ) ) ;
secp256k1_scalar_set_int ( & one , 1 ) ;
secp256k1_num_inc ( & sig . r ) ;
secp256k1_scalar_t msg2 ;
CHECK ( ! secp256k1_ecdsa_sig_verify ( & sig , & q , & msg_num ) ) ;
secp256k1_scalar_add ( & msg2 , & msg , & one ) ;
CHECK ( ! secp256k1_ecdsa_sig_verify ( & sig , & q , & msg2 ) ) ;
random_sign ( & sig , & key , & msg , NULL ) ;
random_sign ( & sig , & key , & msg , NULL ) ;
int secp_sigsize = 80 ;
int secp_sigsize = 80 ;
@ -1042,8 +1165,19 @@ int main(int argc, char **argv) {
/* initialize */
/* initialize */
secp256k1_start ( SECP256K1_START_SIGN | SECP256K1_START_VERIFY ) ;
secp256k1_start ( SECP256K1_START_SIGN | SECP256K1_START_VERIFY ) ;
/* initializing a second time shouldn't cause any harm or memory leaks. */
secp256k1_start ( SECP256K1_START_SIGN | SECP256K1_START_VERIFY ) ;
/* Likewise, re-running the internal init functions should be harmless. */
secp256k1_fe_start ( ) ;
secp256k1_ge_start ( ) ;
secp256k1_scalar_start ( ) ;
secp256k1_ecdsa_start ( ) ;
# ifndef USE_NUM_NONE
/* num tests */
/* num tests */
run_num_smalltests ( ) ;
run_num_smalltests ( ) ;
# endif
/* scalar tests */
/* scalar tests */
run_scalar_tests ( ) ;
run_scalar_tests ( ) ;
@ -1067,7 +1201,7 @@ int main(int argc, char **argv) {
/* ecdsa tests */
/* ecdsa tests */
run_ecdsa_sign_verify ( ) ;
run_ecdsa_sign_verify ( ) ;
run_ecdsa_end_to_end ( ) ;
run_ecdsa_end_to_end ( ) ;
run_ecdsa_infinity ( ) ;
run_ecdsa_edge_cases ( ) ;
# ifdef ENABLE_OPENSSL_TESTS
# ifdef ENABLE_OPENSSL_TESTS
run_ecdsa_openssl ( ) ;
run_ecdsa_openssl ( ) ;
# endif
# endif
@ -1076,5 +1210,14 @@ int main(int argc, char **argv) {
/* shutdown */
/* shutdown */
secp256k1_stop ( ) ;
secp256k1_stop ( ) ;
/* shutting down twice shouldn't cause any double frees. */
secp256k1_stop ( ) ;
/* Same for the internal shutdown functions. */
secp256k1_fe_stop ( ) ;
secp256k1_ge_stop ( ) ;
secp256k1_scalar_stop ( ) ;
secp256k1_ecdsa_stop ( ) ;
return 0 ;
return 0 ;
}
}