Merge pull request #271
55399c2 Further performance improvements to _ecmult_wnaf (Peter Dettman) 145cc6e Improve performance of _ecmult_wnaf (Peter Dettman)
This commit is contained in:
		
						commit
						bdf0e0c268
					
				| @ -229,7 +229,7 @@ void bench_ecmult_wnaf(void* arg) { | |||||||
|     bench_inv_t *data = (bench_inv_t*)arg; |     bench_inv_t *data = (bench_inv_t*)arg; | ||||||
| 
 | 
 | ||||||
|     for (i = 0; i < 20000; i++) { |     for (i = 0; i < 20000; i++) { | ||||||
|         secp256k1_ecmult_wnaf(data->wnaf, &data->scalar_x, WINDOW_A); |         secp256k1_ecmult_wnaf(data->wnaf, 256, &data->scalar_x, WINDOW_A); | ||||||
|         secp256k1_scalar_add(&data->scalar_x, &data->scalar_x, &data->scalar_y); |         secp256k1_scalar_add(&data->scalar_x, &data->scalar_x, &data->scalar_y); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -213,43 +213,57 @@ static void secp256k1_ecmult_context_clear(secp256k1_ecmult_context_t *ctx) { | |||||||
|  *  - each wnaf[i] is either 0, or an odd integer between -(1<<(w-1) - 1) and (1<<(w-1) - 1) |  *  - each wnaf[i] is either 0, or an odd integer between -(1<<(w-1) - 1) and (1<<(w-1) - 1) | ||||||
|  *  - two non-zero entries in wnaf are separated by at least w-1 zeroes. |  *  - two non-zero entries in wnaf are separated by at least w-1 zeroes. | ||||||
|  *  - the number of set values in wnaf is returned. This number is at most 256, and at most one more |  *  - the number of set values in wnaf is returned. This number is at most 256, and at most one more | ||||||
|  *  - than the number of bits in the (absolute value) of the input. |  *    than the number of bits in the (absolute value) of the input. | ||||||
|  */ |  */ | ||||||
| static int secp256k1_ecmult_wnaf(int *wnaf, const secp256k1_scalar_t *a, int w) { | static int secp256k1_ecmult_wnaf(int *wnaf, int len, const secp256k1_scalar_t *a, int w) { | ||||||
|     secp256k1_scalar_t s = *a; |     secp256k1_scalar_t s = *a; | ||||||
|     int set_bits = 0; |     int last_set_bit = -1; | ||||||
|     int bit = 0; |     int bit = 0; | ||||||
|     int sign = 1; |     int sign = 1; | ||||||
|  |     int carry = 0; | ||||||
|  | 
 | ||||||
|  |     VERIFY_CHECK(wnaf != NULL); | ||||||
|  |     VERIFY_CHECK(0 <= len && len <= 256); | ||||||
|  |     VERIFY_CHECK(a != NULL); | ||||||
|  |     VERIFY_CHECK(2 <= w && w <= 31); | ||||||
|  | 
 | ||||||
|  |     memset(wnaf, 0, len * sizeof(wnaf[0])); | ||||||
| 
 | 
 | ||||||
|     if (secp256k1_scalar_get_bits(&s, 255, 1)) { |     if (secp256k1_scalar_get_bits(&s, 255, 1)) { | ||||||
|         secp256k1_scalar_negate(&s, &s); |         secp256k1_scalar_negate(&s, &s); | ||||||
|         sign = -1; |         sign = -1; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     while (bit < 256) { |     while (bit < len) { | ||||||
|         int now; |         int now; | ||||||
|         int word; |         int word; | ||||||
|         if (secp256k1_scalar_get_bits(&s, bit, 1) == 0) { |         if (secp256k1_scalar_get_bits(&s, bit, 1) == (unsigned int)carry) { | ||||||
|             bit++; |             bit++; | ||||||
|             continue; |             continue; | ||||||
|         } |         } | ||||||
|         while (set_bits < bit) { | 
 | ||||||
|             wnaf[set_bits++] = 0; |  | ||||||
|         } |  | ||||||
|         now = w; |         now = w; | ||||||
|         if (bit + now > 256) { |         if (now > len - bit) { | ||||||
|             now = 256 - bit; |             now = len - bit; | ||||||
|         } |  | ||||||
|         word = secp256k1_scalar_get_bits_var(&s, bit, now); |  | ||||||
|         if (word & (1 << (w-1))) { |  | ||||||
|             secp256k1_scalar_add_bit(&s, bit + w); |  | ||||||
|             wnaf[set_bits++] = sign * (word - (1 << w)); |  | ||||||
|         } else { |  | ||||||
|             wnaf[set_bits++] = sign * word; |  | ||||||
|         } |         } | ||||||
|  | 
 | ||||||
|  |         word = secp256k1_scalar_get_bits_var(&s, bit, now) + carry; | ||||||
|  | 
 | ||||||
|  |         carry = (word >> (w-1)) & 1; | ||||||
|  |         word -= carry << w; | ||||||
|  | 
 | ||||||
|  |         wnaf[bit] = sign * word; | ||||||
|  |         last_set_bit = bit; | ||||||
|  | 
 | ||||||
|         bit += now; |         bit += now; | ||||||
|     } |     } | ||||||
|     return set_bits; | #ifdef VERIFY | ||||||
|  |     CHECK(carry == 0); | ||||||
|  |     while (bit < 256) { | ||||||
|  |         CHECK(secp256k1_scalar_get_bits(&s, bit++, 1) == 0); | ||||||
|  |     }  | ||||||
|  | #endif | ||||||
|  |     return last_set_bit + 1; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void secp256k1_ecmult(const secp256k1_ecmult_context_t *ctx, secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_scalar_t *na, const secp256k1_scalar_t *ng) { | static void secp256k1_ecmult(const secp256k1_ecmult_context_t *ctx, secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_scalar_t *na, const secp256k1_scalar_t *ng) { | ||||||
| @ -272,7 +286,7 @@ static void secp256k1_ecmult(const secp256k1_ecmult_context_t *ctx, secp256k1_ge | |||||||
| #else | #else | ||||||
|     int wnaf_na[256]; |     int wnaf_na[256]; | ||||||
|     int bits_na; |     int bits_na; | ||||||
|     int wnaf_ng[257]; |     int wnaf_ng[256]; | ||||||
|     int bits_ng; |     int bits_ng; | ||||||
| #endif | #endif | ||||||
|     int i; |     int i; | ||||||
| @ -283,8 +297,8 @@ static void secp256k1_ecmult(const secp256k1_ecmult_context_t *ctx, secp256k1_ge | |||||||
|     secp256k1_scalar_split_lambda_var(&na_1, &na_lam, na); |     secp256k1_scalar_split_lambda_var(&na_1, &na_lam, na); | ||||||
| 
 | 
 | ||||||
|     /* build wnaf representation for na_1 and na_lam. */ |     /* build wnaf representation for na_1 and na_lam. */ | ||||||
|     bits_na_1   = secp256k1_ecmult_wnaf(wnaf_na_1,   &na_1,   WINDOW_A); |     bits_na_1   = secp256k1_ecmult_wnaf(wnaf_na_1,   130, &na_1,   WINDOW_A); | ||||||
|     bits_na_lam = secp256k1_ecmult_wnaf(wnaf_na_lam, &na_lam, WINDOW_A); |     bits_na_lam = secp256k1_ecmult_wnaf(wnaf_na_lam, 130, &na_lam, WINDOW_A); | ||||||
|     VERIFY_CHECK(bits_na_1 <= 130); |     VERIFY_CHECK(bits_na_1 <= 130); | ||||||
|     VERIFY_CHECK(bits_na_lam <= 130); |     VERIFY_CHECK(bits_na_lam <= 130); | ||||||
|     bits = bits_na_1; |     bits = bits_na_1; | ||||||
| @ -293,7 +307,7 @@ static void secp256k1_ecmult(const secp256k1_ecmult_context_t *ctx, secp256k1_ge | |||||||
|     } |     } | ||||||
| #else | #else | ||||||
|     /* build wnaf representation for na. */ |     /* build wnaf representation for na. */ | ||||||
|     bits_na     = secp256k1_ecmult_wnaf(wnaf_na,     na,      WINDOW_A); |     bits_na     = secp256k1_ecmult_wnaf(wnaf_na,     256, na,      WINDOW_A); | ||||||
|     bits = bits_na; |     bits = bits_na; | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| @ -318,8 +332,8 @@ static void secp256k1_ecmult(const secp256k1_ecmult_context_t *ctx, secp256k1_ge | |||||||
|     secp256k1_scalar_split_128(&ng_1, &ng_128, ng); |     secp256k1_scalar_split_128(&ng_1, &ng_128, ng); | ||||||
| 
 | 
 | ||||||
|     /* Build wnaf representation for ng_1 and ng_128 */ |     /* Build wnaf representation for ng_1 and ng_128 */ | ||||||
|     bits_ng_1   = secp256k1_ecmult_wnaf(wnaf_ng_1,   &ng_1,   WINDOW_G); |     bits_ng_1   = secp256k1_ecmult_wnaf(wnaf_ng_1,   129, &ng_1,   WINDOW_G); | ||||||
|     bits_ng_128 = secp256k1_ecmult_wnaf(wnaf_ng_128, &ng_128, WINDOW_G); |     bits_ng_128 = secp256k1_ecmult_wnaf(wnaf_ng_128, 129, &ng_128, WINDOW_G); | ||||||
|     if (bits_ng_1 > bits) { |     if (bits_ng_1 > bits) { | ||||||
|         bits = bits_ng_1; |         bits = bits_ng_1; | ||||||
|     } |     } | ||||||
| @ -327,7 +341,7 @@ static void secp256k1_ecmult(const secp256k1_ecmult_context_t *ctx, secp256k1_ge | |||||||
|         bits = bits_ng_128; |         bits = bits_ng_128; | ||||||
|     } |     } | ||||||
| #else | #else | ||||||
|     bits_ng     = secp256k1_ecmult_wnaf(wnaf_ng,     ng,      WINDOW_G); |     bits_ng     = secp256k1_ecmult_wnaf(wnaf_ng,     256, ng,      WINDOW_G); | ||||||
|     if (bits_ng > bits) { |     if (bits_ng > bits) { | ||||||
|         bits = bits_ng; |         bits = bits_ng; | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -1374,7 +1374,7 @@ void test_wnaf(const secp256k1_scalar_t *number, int w) { | |||||||
|     int bits; |     int bits; | ||||||
|     secp256k1_scalar_set_int(&x, 0); |     secp256k1_scalar_set_int(&x, 0); | ||||||
|     secp256k1_scalar_set_int(&two, 2); |     secp256k1_scalar_set_int(&two, 2); | ||||||
|     bits = secp256k1_ecmult_wnaf(wnaf, number, w); |     bits = secp256k1_ecmult_wnaf(wnaf, 256, number, w); | ||||||
|     CHECK(bits <= 256); |     CHECK(bits <= 256); | ||||||
|     for (i = bits-1; i >= 0; i--) { |     for (i = bits-1; i >= 0; i--) { | ||||||
|         int v = wnaf[i]; |         int v = wnaf[i]; | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user