You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

field.h 6.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. #ifndef _SECP256K1_FIELD_IMPL_H_
  2. #define _SECP256K1_FIELD_IMPL_H_
  3. #if defined(USE_FIELD_GMP)
  4. #include "field_gmp.h"
  5. #elif defined(USE_FIELD_10X26)
  6. #include "field_10x26.h"
  7. #elif defined(USE_FIELD_5X52)
  8. #include "field_5x52.h"
  9. #else
  10. #error "Please select field implementation"
  11. #endif
  12. void static secp256k1_fe_get_hex(char *r, int *rlen, const secp256k1_fe_t *a) {
  13. if (*rlen < 65) {
  14. *rlen = 65;
  15. return;
  16. }
  17. *rlen = 65;
  18. unsigned char tmp[32];
  19. secp256k1_fe_t b = *a;
  20. secp256k1_fe_normalize(&b);
  21. secp256k1_fe_get_b32(tmp, &b);
  22. for (int i=0; i<32; i++) {
  23. static const char *c = "0123456789ABCDEF";
  24. r[2*i] = c[(tmp[i] >> 4) & 0xF];
  25. r[2*i+1] = c[(tmp[i]) & 0xF];
  26. }
  27. r[64] = 0x00;
  28. }
  29. void static secp256k1_fe_set_hex(secp256k1_fe_t *r, const char *a, int alen) {
  30. unsigned char tmp[32] = {};
  31. static const int cvt[256] = {0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,
  32. 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,
  33. 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,
  34. 0, 1, 2, 3, 4, 5, 6,7,8,9,0,0,0,0,0,0,
  35. 0,10,11,12,13,14,15,0,0,0,0,0,0,0,0,0,
  36. 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,
  37. 0,10,11,12,13,14,15,0,0,0,0,0,0,0,0,0,
  38. 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,
  39. 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,
  40. 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,
  41. 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,
  42. 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,
  43. 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,
  44. 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,
  45. 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,
  46. 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0};
  47. for (int i=0; i<32; i++) {
  48. if (alen > i*2)
  49. tmp[32 - alen/2 + i] = (cvt[(unsigned char)a[2*i]] << 4) + cvt[(unsigned char)a[2*i+1]];
  50. }
  51. secp256k1_fe_set_b32(r, tmp);
  52. }
  53. void static secp256k1_fe_sqrt(secp256k1_fe_t *r, const secp256k1_fe_t *a) {
  54. // calculate a^p, with p={15,780,1022,1023}
  55. secp256k1_fe_t a2; secp256k1_fe_sqr(&a2, a);
  56. secp256k1_fe_t a3; secp256k1_fe_mul(&a3, &a2, a);
  57. secp256k1_fe_t a6; secp256k1_fe_sqr(&a6, &a3);
  58. secp256k1_fe_t a12; secp256k1_fe_sqr(&a12, &a6);
  59. secp256k1_fe_t a15; secp256k1_fe_mul(&a15, &a12, &a3);
  60. secp256k1_fe_t a30; secp256k1_fe_sqr(&a30, &a15);
  61. secp256k1_fe_t a60; secp256k1_fe_sqr(&a60, &a30);
  62. secp256k1_fe_t a120; secp256k1_fe_sqr(&a120, &a60);
  63. secp256k1_fe_t a240; secp256k1_fe_sqr(&a240, &a120);
  64. secp256k1_fe_t a255; secp256k1_fe_mul(&a255, &a240, &a15);
  65. secp256k1_fe_t a510; secp256k1_fe_sqr(&a510, &a255);
  66. secp256k1_fe_t a750; secp256k1_fe_mul(&a750, &a510, &a240);
  67. secp256k1_fe_t a780; secp256k1_fe_mul(&a780, &a750, &a30);
  68. secp256k1_fe_t a1020; secp256k1_fe_sqr(&a1020, &a510);
  69. secp256k1_fe_t a1022; secp256k1_fe_mul(&a1022, &a1020, &a2);
  70. secp256k1_fe_t a1023; secp256k1_fe_mul(&a1023, &a1022, a);
  71. secp256k1_fe_t x = a15;
  72. for (int i=0; i<21; i++) {
  73. for (int j=0; j<10; j++) secp256k1_fe_sqr(&x, &x);
  74. secp256k1_fe_mul(&x, &x, &a1023);
  75. }
  76. for (int j=0; j<10; j++) secp256k1_fe_sqr(&x, &x);
  77. secp256k1_fe_mul(&x, &x, &a1022);
  78. for (int i=0; i<2; i++) {
  79. for (int j=0; j<10; j++) secp256k1_fe_sqr(&x, &x);
  80. secp256k1_fe_mul(&x, &x, &a1023);
  81. }
  82. for (int j=0; j<10; j++) secp256k1_fe_sqr(&x, &x);
  83. secp256k1_fe_mul(r, &x, &a780);
  84. }
  85. void static secp256k1_fe_inv(secp256k1_fe_t *r, const secp256k1_fe_t *a) {
  86. // calculate a^p, with p={45,63,1019,1023}
  87. secp256k1_fe_t a2; secp256k1_fe_sqr(&a2, a);
  88. secp256k1_fe_t a3; secp256k1_fe_mul(&a3, &a2, a);
  89. secp256k1_fe_t a4; secp256k1_fe_sqr(&a4, &a2);
  90. secp256k1_fe_t a5; secp256k1_fe_mul(&a5, &a4, a);
  91. secp256k1_fe_t a10; secp256k1_fe_sqr(&a10, &a5);
  92. secp256k1_fe_t a11; secp256k1_fe_mul(&a11, &a10, a);
  93. secp256k1_fe_t a21; secp256k1_fe_mul(&a21, &a11, &a10);
  94. secp256k1_fe_t a42; secp256k1_fe_sqr(&a42, &a21);
  95. secp256k1_fe_t a45; secp256k1_fe_mul(&a45, &a42, &a3);
  96. secp256k1_fe_t a63; secp256k1_fe_mul(&a63, &a42, &a21);
  97. secp256k1_fe_t a126; secp256k1_fe_sqr(&a126, &a63);
  98. secp256k1_fe_t a252; secp256k1_fe_sqr(&a252, &a126);
  99. secp256k1_fe_t a504; secp256k1_fe_sqr(&a504, &a252);
  100. secp256k1_fe_t a1008; secp256k1_fe_sqr(&a1008, &a504);
  101. secp256k1_fe_t a1019; secp256k1_fe_mul(&a1019, &a1008, &a11);
  102. secp256k1_fe_t a1023; secp256k1_fe_mul(&a1023, &a1019, &a4);
  103. secp256k1_fe_t x = a63;
  104. for (int i=0; i<21; i++) {
  105. for (int j=0; j<10; j++) secp256k1_fe_sqr(&x, &x);
  106. secp256k1_fe_mul(&x, &x, &a1023);
  107. }
  108. for (int j=0; j<10; j++) secp256k1_fe_sqr(&x, &x);
  109. secp256k1_fe_mul(&x, &x, &a1019);
  110. for (int i=0; i<2; i++) {
  111. for (int j=0; j<10; j++) secp256k1_fe_sqr(&x, &x);
  112. secp256k1_fe_mul(&x, &x, &a1023);
  113. }
  114. for (int j=0; j<10; j++) secp256k1_fe_sqr(&x, &x);
  115. secp256k1_fe_mul(r, &x, &a45);
  116. }
  117. void static secp256k1_fe_inv_var(secp256k1_fe_t *r, const secp256k1_fe_t *a) {
  118. #if defined(USE_FIELD_INV_BUILTIN)
  119. secp256k1_fe_inv(r, a);
  120. #elif defined(USE_FIELD_INV_NUM)
  121. unsigned char b[32];
  122. secp256k1_fe_t c = *a;
  123. secp256k1_fe_normalize(&c);
  124. secp256k1_fe_get_b32(b, &c);
  125. secp256k1_num_t n;
  126. secp256k1_num_init(&n);
  127. secp256k1_num_set_bin(&n, b, 32);
  128. secp256k1_num_mod_inverse(&n, &n, &secp256k1_fe_consts->p);
  129. secp256k1_num_get_bin(b, 32, &n);
  130. secp256k1_num_free(&n);
  131. secp256k1_fe_set_b32(r, b);
  132. #else
  133. #error "Please select field inverse implementation"
  134. #endif
  135. }
  136. void static secp256k1_fe_start(void) {
  137. static const unsigned char secp256k1_fe_consts_p[] = {
  138. 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
  139. 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
  140. 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
  141. 0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFC,0x2F
  142. };
  143. if (secp256k1_fe_consts == NULL) {
  144. secp256k1_fe_inner_start();
  145. secp256k1_fe_consts_t *ret = (secp256k1_fe_consts_t*)malloc(sizeof(secp256k1_fe_t));
  146. secp256k1_num_init(&ret->p);
  147. secp256k1_num_set_bin(&ret->p, secp256k1_fe_consts_p, sizeof(secp256k1_fe_consts_p));
  148. secp256k1_fe_consts = ret;
  149. }
  150. }
  151. void static secp256k1_fe_stop(void) {
  152. if (secp256k1_fe_consts != NULL) {
  153. secp256k1_fe_consts_t *c = (secp256k1_fe_consts_t*)secp256k1_fe_consts;
  154. secp256k1_num_free(&c->p);
  155. free((void*)c);
  156. secp256k1_fe_consts = NULL;
  157. secp256k1_fe_inner_stop();
  158. }
  159. }
  160. #endif