crypto.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727
  1. // /*
  2. // * This file is part of the Trezor project, https://trezor.io/
  3. // *
  4. // * Copyright (C) 2014 Pavol Rusnak <stick@satoshilabs.com>
  5. // *
  6. // * This library is free software: you can redistribute it and/or modify
  7. // * it under the terms of the GNU Lesser General Public License as published by
  8. // * the Free Software Foundation, either version 3 of the License, or
  9. // * (at your option) any later version.
  10. // *
  11. // * This library is distributed in the hope that it will be useful,
  12. // * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. // * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. // * GNU Lesser General Public License for more details.
  15. // *
  16. // * You should have received a copy of the GNU Lesser General Public License
  17. // * along with this library. If not, see <http://www.gnu.org/licenses/>.
  18. // */
  19. // #include "crypto.h"
  20. // #include <string.h>
  21. // #include "../crypto/address.h"
  22. // #include "../crypto/aes/aes.h"
  23. // #include "../crypto/base58.h"
  24. // #include "../crypto/bip32.h"
  25. // #include "coins.h"
  26. // #include "../crypto/curves.h"
  27. // #include "../crypto/hmac.h"
  28. // //#include "layout.h"
  29. // #include "../crypto/pbkdf2.h"
  30. // #include "../crypto/secp256k1.h"
  31. // #include "../crypto/segwit_addr.h"
  32. // #include "../crypto/sha2.h"
  33. // #if !BITCOIN_ONLY
  34. // #include "cash_addr.h"
  35. // #endif
  36. // uint32_t ser_length(uint32_t len, uint8_t *out) {
  37. // if (len < 253) {
  38. // out[0] = len & 0xFF;
  39. // return 1;
  40. // }
  41. // if (len < 0x10000) {
  42. // out[0] = 253;
  43. // out[1] = len & 0xFF;
  44. // out[2] = (len >> 8) & 0xFF;
  45. // return 3;
  46. // }
  47. // out[0] = 254;
  48. // out[1] = len & 0xFF;
  49. // out[2] = (len >> 8) & 0xFF;
  50. // out[3] = (len >> 16) & 0xFF;
  51. // out[4] = (len >> 24) & 0xFF;
  52. // return 5;
  53. // }
  54. // uint32_t ser_length_hash(Hasher *hasher, uint32_t len) {
  55. // if (len < 253) {
  56. // hasher_Update(hasher, (const uint8_t *)&len, 1);
  57. // return 1;
  58. // }
  59. // if (len < 0x10000) {
  60. // uint8_t d = 253;
  61. // hasher_Update(hasher, &d, 1);
  62. // hasher_Update(hasher, (const uint8_t *)&len, 2);
  63. // return 3;
  64. // }
  65. // uint8_t d = 254;
  66. // hasher_Update(hasher, &d, 1);
  67. // hasher_Update(hasher, (const uint8_t *)&len, 4);
  68. // return 5;
  69. // }
  70. // uint32_t deser_length(const uint8_t *in, uint32_t *out) {
  71. // if (in[0] < 253) {
  72. // *out = in[0];
  73. // return 1;
  74. // }
  75. // if (in[0] == 253) {
  76. // *out = in[1] + (in[2] << 8);
  77. // return 1 + 2;
  78. // }
  79. // if (in[0] == 254) {
  80. // *out = in[1] + (in[2] << 8) + (in[3] << 16) + ((uint32_t)in[4] << 24);
  81. // return 1 + 4;
  82. // }
  83. // *out = 0; // ignore 64 bit
  84. // return 1 + 8;
  85. // }
  86. // int sshMessageSign(HDNode *node, const uint8_t *message, size_t message_len,
  87. // uint8_t *signature) {
  88. // signature[0] = 0; // prefix: pad with zero, so all signatures are 65 bytes
  89. // return hdnode_sign(node, message, message_len, HASHER_SHA2, signature + 1,
  90. // NULL, NULL);
  91. // }
  92. // int gpgMessageSign(HDNode *node, const uint8_t *message, size_t message_len,
  93. // uint8_t *signature) {
  94. // signature[0] = 0; // prefix: pad with zero, so all signatures are 65 bytes
  95. // const curve_info *ed25519_curve_info = get_curve_by_name(ED25519_NAME);
  96. // if (ed25519_curve_info && node->curve == ed25519_curve_info) {
  97. // // GPG supports variable size digest for Ed25519 signatures
  98. // return hdnode_sign(node, message, message_len, 0, signature + 1, NULL,
  99. // NULL);
  100. // } else {
  101. // // Ensure 256-bit digest before proceeding
  102. // if (message_len != 32) {
  103. // return 1;
  104. // }
  105. // return hdnode_sign_digest(node, message, signature + 1, NULL, NULL);
  106. // }
  107. // }
  108. // int signifyMessageSign(HDNode *node, const uint8_t *message, size_t message_len,
  109. // uint8_t *signature) {
  110. // signature[0] = 0; // prefix: pad with zero, so all signatures are 65 bytes
  111. // const curve_info *ed25519_curve_info = get_curve_by_name(ED25519_NAME);
  112. // // only ed25519 is supported
  113. // if (!ed25519_curve_info || node->curve != ed25519_curve_info) {
  114. // return 1;
  115. // }
  116. // return hdnode_sign(node, message, message_len, 0, signature + 1, NULL, NULL);
  117. // }
  118. // static void cryptoMessageHash(const CoinInfo *coin, const uint8_t *message,
  119. // size_t message_len,
  120. // uint8_t hash[HASHER_DIGEST_LENGTH]) {
  121. // Hasher hasher = {0};
  122. // hasher_Init(&hasher, coin->curve->hasher_sign);
  123. // hasher_Update(&hasher, (const uint8_t *)coin->signed_message_header,
  124. // strlen(coin->signed_message_header));
  125. // uint8_t varint[5] = {0};
  126. // uint32_t l = ser_length(message_len, varint);
  127. // hasher_Update(&hasher, varint, l);
  128. // hasher_Update(&hasher, message, message_len);
  129. // hasher_Final(&hasher, hash);
  130. // }
  131. // int cryptoMessageSign(const CoinInfo *coin, HDNode *node,
  132. // InputScriptType script_type, bool no_script_type,
  133. // const uint8_t *message, size_t message_len,
  134. // uint8_t *signature) {
  135. // uint8_t script_type_info = 0;
  136. // switch (script_type) {
  137. // case InputScriptType_SPENDADDRESS:
  138. // // p2pkh
  139. // script_type_info = 0;
  140. // break;
  141. // case InputScriptType_SPENDP2SHWITNESS:
  142. // // segwit-in-p2sh
  143. // script_type_info = 4;
  144. // break;
  145. // case InputScriptType_SPENDWITNESS:
  146. // // segwit
  147. // script_type_info = 8;
  148. // break;
  149. // default:
  150. // // unsupported script type
  151. // return 1;
  152. // }
  153. // if (no_script_type) {
  154. // script_type_info = 0;
  155. // }
  156. // uint8_t hash[HASHER_DIGEST_LENGTH] = {0};
  157. // cryptoMessageHash(coin, message, message_len, hash);
  158. // uint8_t pby = 0;
  159. // int result = hdnode_sign_digest(node, hash, signature + 1, &pby, NULL);
  160. // if (result == 0) {
  161. // signature[0] = 31 + pby + script_type_info;
  162. // }
  163. // return result;
  164. // }
  165. // // Determines the script type from a non-multisig address.
  166. // static InputScriptType address_to_script_type(const CoinInfo *coin,
  167. // const char *address) {
  168. // uint8_t addr_raw[MAX_ADDR_RAW_SIZE] = {0};
  169. // size_t addr_raw_len = 0;
  170. // // Native SegWit
  171. // if (coin->bech32_prefix) {
  172. // int witver = 0;
  173. // if (segwit_addr_decode(&witver, addr_raw, &addr_raw_len,
  174. // coin->bech32_prefix, address)) {
  175. // switch (witver) {
  176. // case 0:
  177. // return InputScriptType_SPENDWITNESS;
  178. // case 1:
  179. // return InputScriptType_SPENDTAPROOT;
  180. // default:
  181. // return InputScriptType_EXTERNAL; // unknown script type
  182. // }
  183. // }
  184. // }
  185. // #if !BITCOIN_ONLY
  186. // if (coin->cashaddr_prefix &&
  187. // cash_addr_decode(addr_raw, &addr_raw_len, coin->cashaddr_prefix,
  188. // address)) {
  189. // return InputScriptType_SPENDADDRESS;
  190. // }
  191. // #endif
  192. // addr_raw_len = base58_decode_check(address, coin->curve->hasher_base58,
  193. // addr_raw, sizeof(addr_raw));
  194. // // P2PKH
  195. // if (addr_raw_len > address_prefix_bytes_len(coin->address_type) &&
  196. // address_check_prefix(addr_raw, coin->address_type)) {
  197. // return InputScriptType_SPENDADDRESS;
  198. // }
  199. // // P2SH
  200. // if (addr_raw_len > address_prefix_bytes_len(coin->address_type_p2sh) &&
  201. // address_check_prefix(addr_raw, coin->address_type_p2sh)) {
  202. // return InputScriptType_SPENDP2SHWITNESS;
  203. // }
  204. // return InputScriptType_EXTERNAL; // unknown script type
  205. // }
  206. // int cryptoMessageVerify(const CoinInfo *coin, const uint8_t *message,
  207. // size_t message_len, const char *address,
  208. // const uint8_t *signature) {
  209. // // check if the address is correct
  210. // InputScriptType script_type = address_to_script_type(coin, address);
  211. // if (script_type == InputScriptType_EXTERNAL) {
  212. // return 1; // invalid address
  213. // }
  214. // if (signature[0] >= 27 && signature[0] <= 34) {
  215. // // p2pkh or no script type provided
  216. // // use the script type from the address
  217. // } else if (signature[0] >= 35 && signature[0] <= 38) {
  218. // // segwit-in-p2sh
  219. // if (script_type != InputScriptType_SPENDP2SHWITNESS) {
  220. // return 2; // script type mismatch
  221. // }
  222. // } else if (signature[0] >= 39 && signature[0] <= 42) {
  223. // // segwit
  224. // if (script_type != InputScriptType_SPENDWITNESS) {
  225. // return 2; // script type mismatch
  226. // }
  227. // } else {
  228. // return 3; // invalid signature prefix
  229. // }
  230. // uint8_t hash[HASHER_DIGEST_LENGTH] = {0};
  231. // cryptoMessageHash(coin, message, message_len, hash);
  232. // uint8_t recid = (signature[0] - 27) % 4;
  233. // bool compressed = signature[0] >= 31;
  234. // // check if signature verifies the digest and recover the public key
  235. // uint8_t pubkey[65] = {0};
  236. // if (ecdsa_recover_pub_from_sig(coin->curve->params, pubkey, signature + 1,
  237. // hash, recid) != 0) {
  238. // return 4; // invalid signature data
  239. // }
  240. // // convert public key to compressed pubkey if necessary
  241. // if (compressed) {
  242. // pubkey[0] = 0x02 | (pubkey[64] & 1);
  243. // }
  244. // uint8_t addr_raw[MAX_ADDR_RAW_SIZE] = {0};
  245. // uint8_t recovered_raw[MAX_ADDR_RAW_SIZE] = {0};
  246. // if (script_type == InputScriptType_SPENDADDRESS) {
  247. // // p2pkh
  248. // size_t len = 0;
  249. // #if !BITCOIN_ONLY
  250. // if (coin->cashaddr_prefix) {
  251. // if (!cash_addr_decode(addr_raw, &len, coin->cashaddr_prefix, address)) {
  252. // return 1; // invalid address
  253. // }
  254. // } else
  255. // #endif
  256. // {
  257. // len = base58_decode_check(address, coin->curve->hasher_base58, addr_raw,
  258. // MAX_ADDR_RAW_SIZE);
  259. // }
  260. // ecdsa_get_address_raw(pubkey, coin->address_type,
  261. // coin->curve->hasher_pubkey, recovered_raw);
  262. // if (memcmp(recovered_raw, addr_raw, len) != 0 ||
  263. // len != address_prefix_bytes_len(coin->address_type) + 20) {
  264. // return 5; // signature does not match address and message
  265. // }
  266. // } else if (script_type == InputScriptType_SPENDP2SHWITNESS) {
  267. // // segwit-in-p2sh
  268. // size_t len = base58_decode_check(address, coin->curve->hasher_base58,
  269. // addr_raw, MAX_ADDR_RAW_SIZE);
  270. // ecdsa_get_address_segwit_p2sh_raw(pubkey, coin->address_type_p2sh,
  271. // coin->curve->hasher_pubkey,
  272. // recovered_raw);
  273. // if (memcmp(recovered_raw, addr_raw, len) != 0 ||
  274. // len != address_prefix_bytes_len(coin->address_type_p2sh) + 20) {
  275. // return 5; // signature does not match address and message
  276. // }
  277. // } else if (script_type == InputScriptType_SPENDWITNESS) {
  278. // // segwit
  279. // int witver = 0;
  280. // size_t len = 0;
  281. // if (!coin->bech32_prefix ||
  282. // !segwit_addr_decode(&witver, recovered_raw, &len, coin->bech32_prefix,
  283. // address)) {
  284. // return 1; // invalid address
  285. // }
  286. // ecdsa_get_pubkeyhash(pubkey, coin->curve->hasher_pubkey, addr_raw);
  287. // if (memcmp(recovered_raw, addr_raw, len) != 0 || witver != 0 || len != 20) {
  288. // return 5; // signature does not match address and message
  289. // }
  290. // } else {
  291. // return 1; // invalid address
  292. // }
  293. // return 0;
  294. // }
  295. // const HDNode *cryptoMultisigPubkey(const CoinInfo *coin,
  296. // const MultisigRedeemScriptType *multisig,
  297. // uint32_t index) {
  298. // const HDNodeType *node_ptr = NULL;
  299. // const uint32_t *address_n = NULL;
  300. // uint32_t address_n_count = 0;
  301. // if (multisig->nodes_count) { // use multisig->nodes
  302. // if (index >= multisig->nodes_count) {
  303. // return 0;
  304. // }
  305. // node_ptr = &(multisig->nodes[index]);
  306. // address_n = multisig->address_n;
  307. // address_n_count = multisig->address_n_count;
  308. // } else if (multisig->pubkeys_count) { // use multisig->pubkeys
  309. // if (index >= multisig->pubkeys_count) {
  310. // return 0;
  311. // }
  312. // node_ptr = &(multisig->pubkeys[index].node);
  313. // address_n = multisig->pubkeys[index].address_n;
  314. // address_n_count = multisig->pubkeys[index].address_n_count;
  315. // } else {
  316. // return 0;
  317. // }
  318. // if (node_ptr->chain_code.size != 32) return 0;
  319. // if (node_ptr->public_key.size != 33) return 0;
  320. // static HDNode node;
  321. // if (!hdnode_from_xpub(node_ptr->depth, node_ptr->child_num,
  322. // node_ptr->chain_code.bytes, node_ptr->public_key.bytes,
  323. // coin->curve_name, &node)) {
  324. // return 0;
  325. // }
  326. // //layoutProgressUpdate(true);
  327. // for (uint32_t i = 0; i < address_n_count; i++) {
  328. // if (!hdnode_public_ckd(&node, address_n[i])) {
  329. // return 0;
  330. // }
  331. // //layoutProgressUpdate(true);
  332. // }
  333. // return &node;
  334. // }
  335. // uint32_t cryptoMultisigPubkeyCount(const MultisigRedeemScriptType *multisig) {
  336. // return multisig->nodes_count ? multisig->nodes_count
  337. // : multisig->pubkeys_count;
  338. // }
  339. // int cryptoMultisigPubkeyIndex(const CoinInfo *coin,
  340. // const MultisigRedeemScriptType *multisig,
  341. // const uint8_t *pubkey) {
  342. // for (size_t i = 0; i < cryptoMultisigPubkeyCount(multisig); i++) {
  343. // const HDNode *pubnode = cryptoMultisigPubkey(coin, multisig, i);
  344. // if (pubnode && memcmp(pubnode->public_key, pubkey, 33) == 0) {
  345. // return i;
  346. // }
  347. // }
  348. // return -1;
  349. // }
  350. // int cryptoMultisigFingerprint(const MultisigRedeemScriptType *multisig,
  351. // uint8_t *hash) {
  352. // static const HDNodeType *pubnodes[15], *swap;
  353. // const uint32_t n = cryptoMultisigPubkeyCount(multisig);
  354. // if (n < 1 || n > 15) {
  355. // return 0;
  356. // }
  357. // if (multisig->m < 1 || multisig->m > 15) {
  358. // return 0;
  359. // }
  360. // for (uint32_t i = 0; i < n; i++) {
  361. // if (multisig->nodes_count) { // use multisig->nodes
  362. // pubnodes[i] = &(multisig->nodes[i]);
  363. // } else if (multisig->pubkeys_count) { // use multisig->pubkeys
  364. // pubnodes[i] = &(multisig->pubkeys[i].node);
  365. // } else {
  366. // return 0;
  367. // }
  368. // }
  369. // for (uint32_t i = 0; i < n; i++) {
  370. // if (pubnodes[i]->public_key.size != 33) return 0;
  371. // if (pubnodes[i]->chain_code.size != 32) return 0;
  372. // }
  373. // // minsort according to pubkey
  374. // for (uint32_t i = 0; i < n - 1; i++) {
  375. // for (uint32_t j = n - 1; j > i; j--) {
  376. // if (memcmp(pubnodes[i]->public_key.bytes, pubnodes[j]->public_key.bytes,
  377. // 33) > 0) {
  378. // swap = pubnodes[i];
  379. // pubnodes[i] = pubnodes[j];
  380. // pubnodes[j] = swap;
  381. // }
  382. // }
  383. // }
  384. // // hash sorted nodes
  385. // SHA256_CTX ctx = {0};
  386. // sha256_Init(&ctx);
  387. // sha256_Update(&ctx, (const uint8_t *)&(multisig->m), sizeof(uint32_t));
  388. // for (uint32_t i = 0; i < n; i++) {
  389. // sha256_Update(&ctx, (const uint8_t *)&(pubnodes[i]->depth),
  390. // sizeof(uint32_t));
  391. // sha256_Update(&ctx, (const uint8_t *)&(pubnodes[i]->fingerprint),
  392. // sizeof(uint32_t));
  393. // sha256_Update(&ctx, (const uint8_t *)&(pubnodes[i]->child_num),
  394. // sizeof(uint32_t));
  395. // sha256_Update(&ctx, pubnodes[i]->chain_code.bytes, 32);
  396. // sha256_Update(&ctx, pubnodes[i]->public_key.bytes, 33);
  397. // }
  398. // sha256_Update(&ctx, (const uint8_t *)&n, sizeof(uint32_t));
  399. // sha256_Final(&ctx, hash);
  400. // //layoutProgressUpdate(true);
  401. // return 1;
  402. // }
  403. // int cryptoIdentityFingerprint(const IdentityType *identity, uint8_t *hash) {
  404. // SHA256_CTX ctx = {0};
  405. // sha256_Init(&ctx);
  406. // sha256_Update(&ctx, (const uint8_t *)&(identity->index), sizeof(uint32_t));
  407. // if (identity->has_proto && identity->proto[0]) {
  408. // sha256_Update(&ctx, (const uint8_t *)(identity->proto),
  409. // strlen(identity->proto));
  410. // sha256_Update(&ctx, (const uint8_t *)"://", 3);
  411. // }
  412. // if (identity->has_user && identity->user[0]) {
  413. // sha256_Update(&ctx, (const uint8_t *)(identity->user),
  414. // strlen(identity->user));
  415. // sha256_Update(&ctx, (const uint8_t *)"@", 1);
  416. // }
  417. // if (identity->has_host && identity->host[0]) {
  418. // sha256_Update(&ctx, (const uint8_t *)(identity->host),
  419. // strlen(identity->host));
  420. // }
  421. // if (identity->has_port && identity->port[0]) {
  422. // sha256_Update(&ctx, (const uint8_t *)":", 1);
  423. // sha256_Update(&ctx, (const uint8_t *)(identity->port),
  424. // strlen(identity->port));
  425. // }
  426. // if (identity->has_path && identity->path[0]) {
  427. // sha256_Update(&ctx, (const uint8_t *)(identity->path),
  428. // strlen(identity->path));
  429. // }
  430. // sha256_Final(&ctx, hash);
  431. // return 1;
  432. // }
  433. // static bool check_cointype(const CoinInfo *coin, uint32_t slip44, bool full) {
  434. // #if BITCOIN_ONLY
  435. // (void)full;
  436. // #else
  437. // if (!full) {
  438. // // Some wallets such as Electron-Cash (BCH) store coins on Bitcoin paths.
  439. // // We can allow spending these coins from Bitcoin paths if the coin has
  440. // // implemented strong replay protection via SIGHASH_FORKID. However, we
  441. // // cannot allow spending any testnet coins from Bitcoin paths, because
  442. // // otherwise an attacker could trick the user into spending BCH on a Bitcoin
  443. // // path by signing a seemingly harmless BCH Testnet transaction.
  444. // if (slip44 == SLIP44_BITCOIN && coin->has_fork_id &&
  445. // coin->coin_type != SLIP44_TESTNET) {
  446. // return true;
  447. // }
  448. // }
  449. // #endif
  450. // return coin->coin_type == slip44;
  451. // }
  452. // bool coin_path_check(const CoinInfo *coin, InputScriptType script_type,
  453. // uint32_t address_n_count, const uint32_t *address_n,
  454. // bool has_multisig, bool full_check) {
  455. // // This function checks that the path is a recognized path for the given coin.
  456. // // Used by GetAddress to prevent ransom attacks where a user could be coerced
  457. // // to use an address with an unenumerable path and used by SignTx to ensure
  458. // // that a user cannot be coerced into signing a testnet transaction or a
  459. // // Litecoin transaction which in fact spends Bitcoin. If full_check is true,
  460. // // then this function also checks that the path fully matches the script type
  461. // // and coin type. This is used to determine whether a warning should be shown.
  462. // if (address_n_count == 0) {
  463. // return false;
  464. // }
  465. // bool valid = true;
  466. // // m/44' : BIP44 Legacy
  467. // // m / purpose' / coin_type' / account' / change / address_index
  468. // if (address_n[0] == PATH_HARDENED + 44) {
  469. // valid = valid && (address_n_count == 5);
  470. // valid = valid && check_cointype(coin, address_n[1], full_check);
  471. // valid = valid && (address_n[2] & PATH_HARDENED);
  472. // valid = valid && ((address_n[2] & PATH_UNHARDEN_MASK) <= PATH_MAX_ACCOUNT);
  473. // valid = valid && (address_n[3] <= PATH_MAX_CHANGE);
  474. // valid = valid && (address_n[4] <= PATH_MAX_ADDRESS_INDEX);
  475. // if (full_check) {
  476. // valid = valid && (script_type == InputScriptType_SPENDADDRESS);
  477. // valid = valid && (!has_multisig);
  478. // }
  479. // return valid;
  480. // }
  481. // if (address_n[0] == PATH_HARDENED + 45) {
  482. // if (address_n_count == 4) {
  483. // // m/45' - BIP45 Copay Abandoned Multisig P2SH
  484. // // m / purpose' / cosigner_index / change / address_index
  485. // // Patterns without a coin_type field must be treated as Bitcoin paths.
  486. // valid = valid && check_cointype(coin, SLIP44_BITCOIN, false);
  487. // valid = valid && (address_n[1] <= 100);
  488. // valid = valid && (address_n[2] <= PATH_MAX_CHANGE);
  489. // valid = valid && (address_n[3] <= PATH_MAX_ADDRESS_INDEX);
  490. // } else if (address_n_count == 5) {
  491. // // Unchained Capital compatibility pattern. Will be removed in the
  492. // // future.
  493. // // m / 45' / coin_type' / account' / [0-1000000] / address_index
  494. // valid = valid && check_cointype(coin, address_n[1], full_check);
  495. // valid = valid && (address_n[2] & PATH_HARDENED);
  496. // valid =
  497. // valid && ((address_n[2] & PATH_UNHARDEN_MASK) <= PATH_MAX_ACCOUNT);
  498. // valid = valid && (address_n[3] <= 1000000);
  499. // valid = valid && (address_n[4] <= PATH_MAX_ADDRESS_INDEX);
  500. // } else if (address_n_count == 6) {
  501. // // Unchained Capital compatibility pattern. Will be removed in the
  502. // // future.
  503. // // m/45'/coin_type'/account'/[0-1000000]/change/address_index
  504. // // m/45'/coin_type/account/[0-1000000]/change/address_index
  505. // valid = valid &&
  506. // check_cointype(coin, PATH_HARDENED | address_n[1], full_check);
  507. // valid = valid && ((address_n[1] & PATH_HARDENED) ==
  508. // (address_n[2] & PATH_HARDENED));
  509. // valid =
  510. // valid && ((address_n[2] & PATH_UNHARDEN_MASK) <= PATH_MAX_ACCOUNT);
  511. // valid = valid && (address_n[3] <= 1000000);
  512. // valid = valid && (address_n[4] <= PATH_MAX_CHANGE);
  513. // valid = valid && (address_n[5] <= PATH_MAX_ADDRESS_INDEX);
  514. // } else {
  515. // return false;
  516. // }
  517. // if (full_check) {
  518. // valid = valid && (script_type == InputScriptType_SPENDADDRESS ||
  519. // script_type == InputScriptType_SPENDMULTISIG);
  520. // valid = valid && has_multisig;
  521. // }
  522. // return valid;
  523. // }
  524. // if (address_n[0] == PATH_HARDENED + 48) {
  525. // valid = valid && (address_n_count == 5 || address_n_count == 6);
  526. // valid = valid && check_cointype(coin, address_n[1], full_check);
  527. // valid = valid && (address_n[2] & PATH_HARDENED);
  528. // valid = valid && ((address_n[2] & PATH_UNHARDEN_MASK) <= PATH_MAX_ACCOUNT);
  529. // if (address_n_count == 5) {
  530. // // [OBSOLETE] m/48' Copay Multisig P2SH
  531. // // m / purpose' / coin_type' / account' / change / address_index
  532. // // NOTE: this pattern is not recognized by trezor-core
  533. // valid = valid && (address_n[3] <= PATH_MAX_CHANGE);
  534. // valid = valid && (address_n[4] <= PATH_MAX_ADDRESS_INDEX);
  535. // if (full_check) {
  536. // valid = valid && has_multisig;
  537. // valid = valid && (script_type == InputScriptType_SPENDMULTISIG);
  538. // }
  539. // } else if (address_n_count == 6) {
  540. // // BIP-48:
  541. // // m / purpose' / coin_type' / account' / type' / change / address_index
  542. // valid = valid && (address_n[3] & PATH_HARDENED);
  543. // uint32_t type = address_n[3] & PATH_UNHARDEN_MASK;
  544. // valid = valid && (type <= 2);
  545. // valid = valid && (type == 0 || coin->has_segwit);
  546. // valid = valid && (address_n[4] <= PATH_MAX_CHANGE);
  547. // valid = valid && (address_n[5] <= PATH_MAX_ADDRESS_INDEX);
  548. // if (full_check) {
  549. // valid = valid && has_multisig;
  550. // switch (type) {
  551. // case 0:
  552. // valid = valid && (script_type == InputScriptType_SPENDMULTISIG ||
  553. // script_type == InputScriptType_SPENDADDRESS);
  554. // break;
  555. // case 1:
  556. // valid = valid && (script_type == InputScriptType_SPENDP2SHWITNESS);
  557. // break;
  558. // case 2:
  559. // valid = valid && (script_type == InputScriptType_SPENDWITNESS);
  560. // break;
  561. // default:
  562. // return false;
  563. // }
  564. // }
  565. // } else {
  566. // return false;
  567. // }
  568. // return valid;
  569. // }
  570. // // m/49' : BIP49 SegWit
  571. // // m / purpose' / coin_type' / account' / change / address_index
  572. // if (address_n[0] == PATH_HARDENED + 49) {
  573. // valid = valid && coin->has_segwit;
  574. // valid = valid && (address_n_count == 5);
  575. // valid = valid && check_cointype(coin, address_n[1], full_check);
  576. // valid = valid && (address_n[2] & PATH_HARDENED);
  577. // valid = valid && ((address_n[2] & PATH_UNHARDEN_MASK) <= PATH_MAX_ACCOUNT);
  578. // valid = valid && (address_n[3] <= PATH_MAX_CHANGE);
  579. // valid = valid && (address_n[4] <= PATH_MAX_ADDRESS_INDEX);
  580. // if (full_check) {
  581. // valid = valid && (script_type == InputScriptType_SPENDP2SHWITNESS);
  582. // }
  583. // return valid;
  584. // }
  585. // // m/84' : BIP84 Native SegWit
  586. // // m / purpose' / coin_type' / account' / change / address_index
  587. // if (address_n[0] == PATH_HARDENED + 84) {
  588. // valid = valid && coin->has_segwit;
  589. // valid = valid && (coin->bech32_prefix != NULL);
  590. // valid = valid && (address_n_count == 5);
  591. // valid = valid && check_cointype(coin, address_n[1], full_check);
  592. // valid = valid && (address_n[2] & PATH_HARDENED);
  593. // valid = valid && ((address_n[2] & PATH_UNHARDEN_MASK) <= PATH_MAX_ACCOUNT);
  594. // valid = valid && (address_n[3] <= PATH_MAX_CHANGE);
  595. // valid = valid && (address_n[4] <= PATH_MAX_ADDRESS_INDEX);
  596. // if (full_check) {
  597. // valid = valid && (script_type == InputScriptType_SPENDWITNESS);
  598. // }
  599. // return valid;
  600. // }
  601. // // m/86' : BIP86 Taproot
  602. // // m / purpose' / coin_type' / account' / change / address_index
  603. // if (address_n[0] == PATH_HARDENED + 86) {
  604. // valid = valid && coin->has_taproot;
  605. // valid = valid && (coin->bech32_prefix != NULL);
  606. // valid = valid && (address_n_count == 5);
  607. // valid = valid && check_cointype(coin, address_n[1], full_check);
  608. // valid = valid && (address_n[2] & PATH_HARDENED);
  609. // valid = valid && ((address_n[2] & PATH_UNHARDEN_MASK) <= PATH_MAX_ACCOUNT);
  610. // valid = valid && (address_n[3] <= PATH_MAX_CHANGE);
  611. // valid = valid && (address_n[4] <= PATH_MAX_ADDRESS_INDEX);
  612. // if (full_check) {
  613. // // we do not support Multisig with Taproot yet
  614. // valid = valid && !has_multisig;
  615. // valid = valid && (script_type == InputScriptType_SPENDTAPROOT);
  616. // }
  617. // return valid;
  618. // }
  619. // // Green Address compatibility pattern. Will be removed in the future.
  620. // // m / [1,4] / address_index
  621. // if (address_n[0] == 1 || address_n[0] == 4) {
  622. // valid = valid && (coin->coin_type == SLIP44_BITCOIN);
  623. // valid = valid && (address_n_count == 2);
  624. // valid = valid && (address_n[1] <= PATH_MAX_ADDRESS_INDEX);
  625. // if (full_check) {
  626. // valid = valid && (script_type != InputScriptType_SPENDTAPROOT);
  627. // }
  628. // return valid;
  629. // }
  630. // // Green Address compatibility pattern. Will be removed in the future.
  631. // // m / 3' / [1-100]' / [1,4] / address_index
  632. // if (address_n[0] == PATH_HARDENED + 3) {
  633. // valid = valid && (coin->coin_type == SLIP44_BITCOIN);
  634. // valid = valid && (address_n_count == 4);
  635. // valid = valid && (address_n[1] & PATH_HARDENED);
  636. // valid = valid && ((address_n[1] & PATH_UNHARDEN_MASK) <= 100);
  637. // valid = valid && (address_n[2] == 1 || address_n[2] == 4);
  638. // valid = valid && (address_n[3] <= PATH_MAX_ADDRESS_INDEX);
  639. // if (full_check) {
  640. // valid = valid && (script_type != InputScriptType_SPENDTAPROOT);
  641. // }
  642. // return valid;
  643. // }
  644. // // Green Address compatibility patterns. Will be removed in the future.
  645. // // m / 1195487518
  646. // // m / 1195487518 / 6 / address_index
  647. // if (address_n[0] == 1195487518) {
  648. // valid = valid && (coin->coin_type == SLIP44_BITCOIN);
  649. // if (address_n_count == 3) {
  650. // valid = valid && (address_n[1] == 6);
  651. // valid = valid && (address_n[2] <= PATH_MAX_ADDRESS_INDEX);
  652. // } else if (address_n_count != 1) {
  653. // return false;
  654. // }
  655. // if (full_check) {
  656. // return false;
  657. // }
  658. // return valid;
  659. // }
  660. // // Casa compatibility pattern. Will be removed in the future.
  661. // // m / 49 / coin_type / account / change / address_index
  662. // if (address_n[0] == 49) {
  663. // valid = valid && (address_n_count == 5);
  664. // valid =
  665. // valid && check_cointype(coin, PATH_HARDENED | address_n[1], full_check);
  666. // valid = valid && ((address_n[1] & PATH_HARDENED) == 0);
  667. // valid = valid && (address_n[2] <= PATH_MAX_ACCOUNT);
  668. // valid = valid && (address_n[3] <= PATH_MAX_CHANGE);
  669. // valid = valid && (address_n[4] <= PATH_MAX_ADDRESS_INDEX);
  670. // if (full_check) {
  671. // valid = valid && (script_type == InputScriptType_SPENDP2SHWITNESS);
  672. // }
  673. // return valid;
  674. // }
  675. // // unknown path
  676. // return false;
  677. // }