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.

pubkey.cpp 9.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. // Copyright (c) 2009-2016 The Starwels developers
  2. // Distributed under the MIT software license, see the accompanying
  3. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
  4. #include "pubkey.h"
  5. #include <secp256k1.h>
  6. #include <secp256k1_recovery.h>
  7. namespace
  8. {
  9. /* Global secp256k1_context object used for verification. */
  10. secp256k1_context* secp256k1_context_verify = nullptr;
  11. } // namespace
  12. /** This function is taken from the libsecp256k1 distribution and implements
  13. * DER parsing for ECDSA signatures, while supporting an arbitrary subset of
  14. * format violations.
  15. *
  16. * Supported violations include negative integers, excessive padding, garbage
  17. * at the end, and overly long length descriptors. This is safe to use in
  18. * Starwels because since the activation of BIP66, signatures are verified to be
  19. * strict DER before being passed to this module, and we know it supports all
  20. * violations present in the blockchain before that point.
  21. */
  22. static int ecdsa_signature_parse_der_lax(const secp256k1_context* ctx, secp256k1_ecdsa_signature* sig, const unsigned char *input, size_t inputlen) {
  23. size_t rpos, rlen, spos, slen;
  24. size_t pos = 0;
  25. size_t lenbyte;
  26. unsigned char tmpsig[64] = {0};
  27. int overflow = 0;
  28. /* Hack to initialize sig with a correctly-parsed but invalid signature. */
  29. secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig);
  30. /* Sequence tag byte */
  31. if (pos == inputlen || input[pos] != 0x30) {
  32. return 0;
  33. }
  34. pos++;
  35. /* Sequence length bytes */
  36. if (pos == inputlen) {
  37. return 0;
  38. }
  39. lenbyte = input[pos++];
  40. if (lenbyte & 0x80) {
  41. lenbyte -= 0x80;
  42. if (pos + lenbyte > inputlen) {
  43. return 0;
  44. }
  45. pos += lenbyte;
  46. }
  47. /* Integer tag byte for R */
  48. if (pos == inputlen || input[pos] != 0x02) {
  49. return 0;
  50. }
  51. pos++;
  52. /* Integer length for R */
  53. if (pos == inputlen) {
  54. return 0;
  55. }
  56. lenbyte = input[pos++];
  57. if (lenbyte & 0x80) {
  58. lenbyte -= 0x80;
  59. if (pos + lenbyte > inputlen) {
  60. return 0;
  61. }
  62. while (lenbyte > 0 && input[pos] == 0) {
  63. pos++;
  64. lenbyte--;
  65. }
  66. if (lenbyte >= sizeof(size_t)) {
  67. return 0;
  68. }
  69. rlen = 0;
  70. while (lenbyte > 0) {
  71. rlen = (rlen << 8) + input[pos];
  72. pos++;
  73. lenbyte--;
  74. }
  75. } else {
  76. rlen = lenbyte;
  77. }
  78. if (rlen > inputlen - pos) {
  79. return 0;
  80. }
  81. rpos = pos;
  82. pos += rlen;
  83. /* Integer tag byte for S */
  84. if (pos == inputlen || input[pos] != 0x02) {
  85. return 0;
  86. }
  87. pos++;
  88. /* Integer length for S */
  89. if (pos == inputlen) {
  90. return 0;
  91. }
  92. lenbyte = input[pos++];
  93. if (lenbyte & 0x80) {
  94. lenbyte -= 0x80;
  95. if (pos + lenbyte > inputlen) {
  96. return 0;
  97. }
  98. while (lenbyte > 0 && input[pos] == 0) {
  99. pos++;
  100. lenbyte--;
  101. }
  102. if (lenbyte >= sizeof(size_t)) {
  103. return 0;
  104. }
  105. slen = 0;
  106. while (lenbyte > 0) {
  107. slen = (slen << 8) + input[pos];
  108. pos++;
  109. lenbyte--;
  110. }
  111. } else {
  112. slen = lenbyte;
  113. }
  114. if (slen > inputlen - pos) {
  115. return 0;
  116. }
  117. spos = pos;
  118. pos += slen;
  119. /* Ignore leading zeroes in R */
  120. while (rlen > 0 && input[rpos] == 0) {
  121. rlen--;
  122. rpos++;
  123. }
  124. /* Copy R value */
  125. if (rlen > 32) {
  126. overflow = 1;
  127. } else {
  128. memcpy(tmpsig + 32 - rlen, input + rpos, rlen);
  129. }
  130. /* Ignore leading zeroes in S */
  131. while (slen > 0 && input[spos] == 0) {
  132. slen--;
  133. spos++;
  134. }
  135. /* Copy S value */
  136. if (slen > 32) {
  137. overflow = 1;
  138. } else {
  139. memcpy(tmpsig + 64 - slen, input + spos, slen);
  140. }
  141. if (!overflow) {
  142. overflow = !secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig);
  143. }
  144. if (overflow) {
  145. /* Overwrite the result again with a correctly-parsed but invalid
  146. signature if parsing failed. */
  147. memset(tmpsig, 0, 64);
  148. secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig);
  149. }
  150. return 1;
  151. }
  152. bool CPubKey::Verify(const uint256 &hash, const std::vector<unsigned char>& vchSig) const {
  153. if (!IsValid())
  154. return false;
  155. secp256k1_pubkey pubkey;
  156. secp256k1_ecdsa_signature sig;
  157. if (!secp256k1_ec_pubkey_parse(secp256k1_context_verify, &pubkey, &(*this)[0], size())) {
  158. return false;
  159. }
  160. if (!ecdsa_signature_parse_der_lax(secp256k1_context_verify, &sig, vchSig.data(), vchSig.size())) {
  161. return false;
  162. }
  163. /* libsecp256k1's ECDSA verification requires lower-S signatures, which have
  164. * not historically been enforced in Starwels, so normalize them first. */
  165. secp256k1_ecdsa_signature_normalize(secp256k1_context_verify, &sig, &sig);
  166. return secp256k1_ecdsa_verify(secp256k1_context_verify, &sig, hash.begin(), &pubkey);
  167. }
  168. bool CPubKey::RecoverCompact(const uint256 &hash, const std::vector<unsigned char>& vchSig) {
  169. if (vchSig.size() != 65)
  170. return false;
  171. int recid = (vchSig[0] - 27) & 3;
  172. bool fComp = ((vchSig[0] - 27) & 4) != 0;
  173. secp256k1_pubkey pubkey;
  174. secp256k1_ecdsa_recoverable_signature sig;
  175. if (!secp256k1_ecdsa_recoverable_signature_parse_compact(secp256k1_context_verify, &sig, &vchSig[1], recid)) {
  176. return false;
  177. }
  178. if (!secp256k1_ecdsa_recover(secp256k1_context_verify, &pubkey, &sig, hash.begin())) {
  179. return false;
  180. }
  181. unsigned char pub[65];
  182. size_t publen = 65;
  183. secp256k1_ec_pubkey_serialize(secp256k1_context_verify, pub, &publen, &pubkey, fComp ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED);
  184. Set(pub, pub + publen);
  185. return true;
  186. }
  187. bool CPubKey::IsFullyValid() const {
  188. if (!IsValid())
  189. return false;
  190. secp256k1_pubkey pubkey;
  191. return secp256k1_ec_pubkey_parse(secp256k1_context_verify, &pubkey, &(*this)[0], size());
  192. }
  193. bool CPubKey::Decompress() {
  194. if (!IsValid())
  195. return false;
  196. secp256k1_pubkey pubkey;
  197. if (!secp256k1_ec_pubkey_parse(secp256k1_context_verify, &pubkey, &(*this)[0], size())) {
  198. return false;
  199. }
  200. unsigned char pub[65];
  201. size_t publen = 65;
  202. secp256k1_ec_pubkey_serialize(secp256k1_context_verify, pub, &publen, &pubkey, SECP256K1_EC_UNCOMPRESSED);
  203. Set(pub, pub + publen);
  204. return true;
  205. }
  206. bool CPubKey::Derive(CPubKey& pubkeyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode& cc) const {
  207. assert(IsValid());
  208. assert((nChild >> 31) == 0);
  209. assert(begin() + 33 == end());
  210. unsigned char out[64];
  211. BIP32Hash(cc, nChild, *begin(), begin()+1, out);
  212. memcpy(ccChild.begin(), out+32, 32);
  213. secp256k1_pubkey pubkey;
  214. if (!secp256k1_ec_pubkey_parse(secp256k1_context_verify, &pubkey, &(*this)[0], size())) {
  215. return false;
  216. }
  217. if (!secp256k1_ec_pubkey_tweak_add(secp256k1_context_verify, &pubkey, out)) {
  218. return false;
  219. }
  220. unsigned char pub[33];
  221. size_t publen = 33;
  222. secp256k1_ec_pubkey_serialize(secp256k1_context_verify, pub, &publen, &pubkey, SECP256K1_EC_COMPRESSED);
  223. pubkeyChild.Set(pub, pub + publen);
  224. return true;
  225. }
  226. void CExtPubKey::Encode(unsigned char code[BIP32_EXTKEY_SIZE]) const {
  227. code[0] = nDepth;
  228. memcpy(code+1, vchFingerprint, 4);
  229. code[5] = (nChild >> 24) & 0xFF; code[6] = (nChild >> 16) & 0xFF;
  230. code[7] = (nChild >> 8) & 0xFF; code[8] = (nChild >> 0) & 0xFF;
  231. memcpy(code+9, chaincode.begin(), 32);
  232. assert(pubkey.size() == 33);
  233. memcpy(code+41, pubkey.begin(), 33);
  234. }
  235. void CExtPubKey::Decode(const unsigned char code[BIP32_EXTKEY_SIZE]) {
  236. nDepth = code[0];
  237. memcpy(vchFingerprint, code+1, 4);
  238. nChild = (code[5] << 24) | (code[6] << 16) | (code[7] << 8) | code[8];
  239. memcpy(chaincode.begin(), code+9, 32);
  240. pubkey.Set(code+41, code+BIP32_EXTKEY_SIZE);
  241. }
  242. bool CExtPubKey::Derive(CExtPubKey &out, unsigned int _nChild) const {
  243. out.nDepth = nDepth + 1;
  244. CKeyID id = pubkey.GetID();
  245. memcpy(&out.vchFingerprint[0], &id, 4);
  246. out.nChild = _nChild;
  247. return pubkey.Derive(out.pubkey, out.chaincode, _nChild, chaincode);
  248. }
  249. /* static */ bool CPubKey::CheckLowS(const std::vector<unsigned char>& vchSig) {
  250. secp256k1_ecdsa_signature sig;
  251. if (!ecdsa_signature_parse_der_lax(secp256k1_context_verify, &sig, vchSig.data(), vchSig.size())) {
  252. return false;
  253. }
  254. return (!secp256k1_ecdsa_signature_normalize(secp256k1_context_verify, nullptr, &sig));
  255. }
  256. /* static */ int ECCVerifyHandle::refcount = 0;
  257. ECCVerifyHandle::ECCVerifyHandle()
  258. {
  259. if (refcount == 0) {
  260. assert(secp256k1_context_verify == nullptr);
  261. secp256k1_context_verify = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY);
  262. assert(secp256k1_context_verify != nullptr);
  263. }
  264. refcount++;
  265. }
  266. ECCVerifyHandle::~ECCVerifyHandle()
  267. {
  268. refcount--;
  269. if (refcount == 0) {
  270. assert(secp256k1_context_verify != nullptr);
  271. secp256k1_context_destroy(secp256k1_context_verify);
  272. secp256k1_context_verify = nullptr;
  273. }
  274. }