eckey_impl.h 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. /**********************************************************************
  2. * Copyright (c) 2013, 2014 Pieter Wuille *
  3. * Distributed under the MIT software license, see the accompanying *
  4. * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
  5. **********************************************************************/
  6. #ifndef _SECP256K1_ECKEY_IMPL_H_
  7. #define _SECP256K1_ECKEY_IMPL_H_
  8. #include "eckey.h"
  9. #include "scalar.h"
  10. #include "field.h"
  11. #include "group.h"
  12. #include "ecmult_gen.h"
  13. static int secp256k1_eckey_pubkey_parse(secp256k1_ge_t *elem, const unsigned char *pub, int size) {
  14. if (size == 33 && (pub[0] == 0x02 || pub[0] == 0x03)) {
  15. secp256k1_fe_t x;
  16. return secp256k1_fe_set_b32(&x, pub+1) && secp256k1_ge_set_xo_var(elem, &x, pub[0] == 0x03);
  17. } else if (size == 65 && (pub[0] == 0x04 || pub[0] == 0x06 || pub[0] == 0x07)) {
  18. secp256k1_fe_t x, y;
  19. if (!secp256k1_fe_set_b32(&x, pub+1) || !secp256k1_fe_set_b32(&y, pub+33)) {
  20. return 0;
  21. }
  22. secp256k1_ge_set_xy(elem, &x, &y);
  23. if ((pub[0] == 0x06 || pub[0] == 0x07) && secp256k1_fe_is_odd(&y) != (pub[0] == 0x07)) {
  24. return 0;
  25. }
  26. return secp256k1_ge_is_valid_var(elem);
  27. } else {
  28. return 0;
  29. }
  30. }
  31. static int secp256k1_eckey_pubkey_serialize(secp256k1_ge_t *elem, unsigned char *pub, int *size, int compressed) {
  32. if (secp256k1_ge_is_infinity(elem)) {
  33. return 0;
  34. }
  35. secp256k1_fe_normalize_var(&elem->x);
  36. secp256k1_fe_normalize_var(&elem->y);
  37. secp256k1_fe_get_b32(&pub[1], &elem->x);
  38. if (compressed) {
  39. *size = 33;
  40. pub[0] = 0x02 | (secp256k1_fe_is_odd(&elem->y) ? 0x01 : 0x00);
  41. } else {
  42. *size = 65;
  43. pub[0] = 0x04;
  44. secp256k1_fe_get_b32(&pub[33], &elem->y);
  45. }
  46. return 1;
  47. }
  48. static int secp256k1_eckey_privkey_parse(secp256k1_scalar_t *key, const unsigned char *privkey, int privkeylen) {
  49. unsigned char c[32] = {0};
  50. const unsigned char *end = privkey + privkeylen;
  51. int lenb = 0;
  52. int len = 0;
  53. int overflow = 0;
  54. /* sequence header */
  55. if (end < privkey+1 || *privkey != 0x30) {
  56. return 0;
  57. }
  58. privkey++;
  59. /* sequence length constructor */
  60. if (end < privkey+1 || !(*privkey & 0x80)) {
  61. return 0;
  62. }
  63. lenb = *privkey & ~0x80; privkey++;
  64. if (lenb < 1 || lenb > 2) {
  65. return 0;
  66. }
  67. if (end < privkey+lenb) {
  68. return 0;
  69. }
  70. /* sequence length */
  71. len = privkey[lenb-1] | (lenb > 1 ? privkey[lenb-2] << 8 : 0);
  72. privkey += lenb;
  73. if (end < privkey+len) {
  74. return 0;
  75. }
  76. /* sequence element 0: version number (=1) */
  77. if (end < privkey+3 || privkey[0] != 0x02 || privkey[1] != 0x01 || privkey[2] != 0x01) {
  78. return 0;
  79. }
  80. privkey += 3;
  81. /* sequence element 1: octet string, up to 32 bytes */
  82. if (end < privkey+2 || privkey[0] != 0x04 || privkey[1] > 0x20 || end < privkey+2+privkey[1]) {
  83. return 0;
  84. }
  85. memcpy(c + 32 - privkey[1], privkey + 2, privkey[1]);
  86. secp256k1_scalar_set_b32(key, c, &overflow);
  87. memset(c, 0, 32);
  88. return !overflow;
  89. }
  90. static int secp256k1_eckey_privkey_serialize(const secp256k1_ecmult_gen_context_t *ctx, unsigned char *privkey, int *privkeylen, const secp256k1_scalar_t *key, int compressed) {
  91. secp256k1_gej_t rp;
  92. secp256k1_ge_t r;
  93. int pubkeylen = 0;
  94. secp256k1_ecmult_gen(ctx, &rp, key);
  95. secp256k1_ge_set_gej(&r, &rp);
  96. if (compressed) {
  97. static const unsigned char begin[] = {
  98. 0x30,0x81,0xD3,0x02,0x01,0x01,0x04,0x20
  99. };
  100. static const unsigned char middle[] = {
  101. 0xA0,0x81,0x85,0x30,0x81,0x82,0x02,0x01,0x01,0x30,0x2C,0x06,0x07,0x2A,0x86,0x48,
  102. 0xCE,0x3D,0x01,0x01,0x02,0x21,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
  103. 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
  104. 0xFF,0xFF,0xFE,0xFF,0xFF,0xFC,0x2F,0x30,0x06,0x04,0x01,0x00,0x04,0x01,0x07,0x04,
  105. 0x21,0x02,0x79,0xBE,0x66,0x7E,0xF9,0xDC,0xBB,0xAC,0x55,0xA0,0x62,0x95,0xCE,0x87,
  106. 0x0B,0x07,0x02,0x9B,0xFC,0xDB,0x2D,0xCE,0x28,0xD9,0x59,0xF2,0x81,0x5B,0x16,0xF8,
  107. 0x17,0x98,0x02,0x21,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
  108. 0xFF,0xFF,0xFF,0xFF,0xFE,0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B,0xBF,0xD2,0x5E,
  109. 0x8C,0xD0,0x36,0x41,0x41,0x02,0x01,0x01,0xA1,0x24,0x03,0x22,0x00
  110. };
  111. unsigned char *ptr = privkey;
  112. memcpy(ptr, begin, sizeof(begin)); ptr += sizeof(begin);
  113. secp256k1_scalar_get_b32(ptr, key); ptr += 32;
  114. memcpy(ptr, middle, sizeof(middle)); ptr += sizeof(middle);
  115. if (!secp256k1_eckey_pubkey_serialize(&r, ptr, &pubkeylen, 1)) {
  116. return 0;
  117. }
  118. ptr += pubkeylen;
  119. *privkeylen = ptr - privkey;
  120. } else {
  121. static const unsigned char begin[] = {
  122. 0x30,0x82,0x01,0x13,0x02,0x01,0x01,0x04,0x20
  123. };
  124. static const unsigned char middle[] = {
  125. 0xA0,0x81,0xA5,0x30,0x81,0xA2,0x02,0x01,0x01,0x30,0x2C,0x06,0x07,0x2A,0x86,0x48,
  126. 0xCE,0x3D,0x01,0x01,0x02,0x21,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
  127. 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
  128. 0xFF,0xFF,0xFE,0xFF,0xFF,0xFC,0x2F,0x30,0x06,0x04,0x01,0x00,0x04,0x01,0x07,0x04,
  129. 0x41,0x04,0x79,0xBE,0x66,0x7E,0xF9,0xDC,0xBB,0xAC,0x55,0xA0,0x62,0x95,0xCE,0x87,
  130. 0x0B,0x07,0x02,0x9B,0xFC,0xDB,0x2D,0xCE,0x28,0xD9,0x59,0xF2,0x81,0x5B,0x16,0xF8,
  131. 0x17,0x98,0x48,0x3A,0xDA,0x77,0x26,0xA3,0xC4,0x65,0x5D,0xA4,0xFB,0xFC,0x0E,0x11,
  132. 0x08,0xA8,0xFD,0x17,0xB4,0x48,0xA6,0x85,0x54,0x19,0x9C,0x47,0xD0,0x8F,0xFB,0x10,
  133. 0xD4,0xB8,0x02,0x21,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
  134. 0xFF,0xFF,0xFF,0xFF,0xFE,0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B,0xBF,0xD2,0x5E,
  135. 0x8C,0xD0,0x36,0x41,0x41,0x02,0x01,0x01,0xA1,0x44,0x03,0x42,0x00
  136. };
  137. unsigned char *ptr = privkey;
  138. memcpy(ptr, begin, sizeof(begin)); ptr += sizeof(begin);
  139. secp256k1_scalar_get_b32(ptr, key); ptr += 32;
  140. memcpy(ptr, middle, sizeof(middle)); ptr += sizeof(middle);
  141. if (!secp256k1_eckey_pubkey_serialize(&r, ptr, &pubkeylen, 0)) {
  142. return 0;
  143. }
  144. ptr += pubkeylen;
  145. *privkeylen = ptr - privkey;
  146. }
  147. return 1;
  148. }
  149. static int secp256k1_eckey_privkey_tweak_add(secp256k1_scalar_t *key, const secp256k1_scalar_t *tweak) {
  150. secp256k1_scalar_add(key, key, tweak);
  151. if (secp256k1_scalar_is_zero(key)) {
  152. return 0;
  153. }
  154. return 1;
  155. }
  156. static int secp256k1_eckey_pubkey_tweak_add(const secp256k1_ecmult_context_t *ctx, secp256k1_ge_t *key, const secp256k1_scalar_t *tweak) {
  157. secp256k1_gej_t pt;
  158. secp256k1_scalar_t one;
  159. secp256k1_gej_set_ge(&pt, key);
  160. secp256k1_scalar_set_int(&one, 1);
  161. secp256k1_ecmult(ctx, &pt, &pt, &one, tweak);
  162. if (secp256k1_gej_is_infinity(&pt)) {
  163. return 0;
  164. }
  165. secp256k1_ge_set_gej(key, &pt);
  166. return 1;
  167. }
  168. static int secp256k1_eckey_privkey_tweak_mul(secp256k1_scalar_t *key, const secp256k1_scalar_t *tweak) {
  169. if (secp256k1_scalar_is_zero(tweak)) {
  170. return 0;
  171. }
  172. secp256k1_scalar_mul(key, key, tweak);
  173. return 1;
  174. }
  175. static int secp256k1_eckey_pubkey_tweak_mul(const secp256k1_ecmult_context_t *ctx, secp256k1_ge_t *key, const secp256k1_scalar_t *tweak) {
  176. secp256k1_scalar_t zero;
  177. secp256k1_gej_t pt;
  178. if (secp256k1_scalar_is_zero(tweak)) {
  179. return 0;
  180. }
  181. secp256k1_scalar_set_int(&zero, 0);
  182. secp256k1_gej_set_ge(&pt, key);
  183. secp256k1_ecmult(ctx, &pt, &pt, tweak, &zero);
  184. secp256k1_ge_set_gej(key, &pt);
  185. return 1;
  186. }
  187. #endif