@@ -1420,6 +1420,16 @@ void random_fe(secp256k1_fe *x) {
14201420 } while (1 );
14211421}
14221422
1423+ void random_fe_test (secp256k1_fe * x ) {
1424+ unsigned char bin [32 ];
1425+ do {
1426+ secp256k1_rand256_test (bin );
1427+ if (secp256k1_fe_set_b32 (x , bin )) {
1428+ return ;
1429+ }
1430+ } while (1 );
1431+ }
1432+
14231433void random_fe_non_zero (secp256k1_fe * nz ) {
14241434 int tries = 10 ;
14251435 while (-- tries >= 0 ) {
@@ -2038,6 +2048,62 @@ void run_ec_combine(void) {
20382048 }
20392049}
20402050
2051+ void test_group_decompress (const secp256k1_fe * x ) {
2052+ /* The input itself, normalized. */
2053+ secp256k1_fe fex = * x ;
2054+ secp256k1_fe tmp ;
2055+ /* Results of set_xquad_var, set_xo_var(..., 0), set_xo_var(..., 1). */
2056+ secp256k1_ge ge_quad , ge_even , ge_odd ;
2057+ /* Return values of the above calls. */
2058+ int res_quad , res_even , res_odd ;
2059+
2060+ secp256k1_fe_normalize_var (& fex );
2061+
2062+ res_quad = secp256k1_ge_set_xquad_var (& ge_quad , & fex );
2063+ res_even = secp256k1_ge_set_xo_var (& ge_even , & fex , 0 );
2064+ res_odd = secp256k1_ge_set_xo_var (& ge_odd , & fex , 1 );
2065+
2066+ CHECK (res_quad == res_even );
2067+ CHECK (res_quad == res_odd );
2068+
2069+ if (res_quad ) {
2070+ secp256k1_fe_normalize_var (& ge_quad .x );
2071+ secp256k1_fe_normalize_var (& ge_odd .x );
2072+ secp256k1_fe_normalize_var (& ge_even .x );
2073+ secp256k1_fe_normalize_var (& ge_quad .y );
2074+ secp256k1_fe_normalize_var (& ge_odd .y );
2075+ secp256k1_fe_normalize_var (& ge_even .y );
2076+
2077+ /* No infinity allowed. */
2078+ CHECK (!ge_quad .infinity );
2079+ CHECK (!ge_even .infinity );
2080+ CHECK (!ge_odd .infinity );
2081+
2082+ /* Check that the x coordinates check out. */
2083+ CHECK (secp256k1_fe_equal_var (& ge_quad .x , x ));
2084+ CHECK (secp256k1_fe_equal_var (& ge_even .x , x ));
2085+ CHECK (secp256k1_fe_equal_var (& ge_odd .x , x ));
2086+
2087+ /* Check that the Y coordinate result in ge_quad is a square. */
2088+ CHECK (secp256k1_fe_sqrt_var (& tmp , & ge_quad .y ));
2089+ secp256k1_fe_sqr (& tmp , & tmp );
2090+ CHECK (secp256k1_fe_equal_var (& tmp , & ge_quad .y ));
2091+
2092+ /* Check odd/even Y in ge_odd, ge_even. */
2093+ CHECK (secp256k1_fe_is_odd (& ge_odd .y ));
2094+ CHECK (!secp256k1_fe_is_odd (& ge_even .y ));
2095+ }
2096+ }
2097+
2098+ void run_group_decompress (void ) {
2099+ int i ;
2100+ for (i = 0 ; i < count * 4 ; i ++ ) {
2101+ secp256k1_fe fe ;
2102+ random_fe_test (& fe );
2103+ test_group_decompress (& fe );
2104+ }
2105+ }
2106+
20412107/***** ECMULT TESTS *****/
20422108
20432109void run_ecmult_chain (void ) {
@@ -4259,6 +4325,7 @@ int main(int argc, char **argv) {
42594325
42604326 /* group tests */
42614327 run_ge ();
4328+ run_group_decompress ();
42624329
42634330 /* ecmult tests */
42644331 run_wnaf ();
0 commit comments