base58.c 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. // Copyright (c) 2014-2018, The Monero Project
  2. //
  3. // All rights reserved.
  4. //
  5. // Redistribution and use in source and binary forms, with or without
  6. // modification, are permitted provided that the following conditions are met:
  7. //
  8. // 1. Redistributions of source code must retain the above copyright notice,
  9. // this list of conditions and the following disclaimer.
  10. //
  11. // 2. Redistributions in binary form must reproduce the above copyright notice,
  12. // this list of conditions and the following disclaimer in the documentation
  13. // and/or other materials provided with the distribution.
  14. //
  15. // 3. Neither the name of the copyright holder nor the names of its contributors
  16. // may be used to endorse or promote products derived from this software
  17. // without specific prior written permission.
  18. //
  19. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  20. // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  21. // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  22. // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
  23. // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  24. // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  25. // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  26. // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  27. // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  28. // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  29. // POSSIBILITY OF SUCH DAMAGE.
  30. //
  31. // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote
  32. // developers
  33. #include "options.h"
  34. #if USE_MONERO
  35. #include "base58.h"
  36. #include <assert.h>
  37. #include <stdbool.h>
  38. #include <string.h>
  39. #include <sys/types.h>
  40. #include "../base58.h"
  41. #include "../byte_order.h"
  42. #include "int_util.h"
  43. #include "../sha2.h"
  44. const size_t alphabet_size = 58; // sizeof(b58digits_ordered) - 1;
  45. const size_t full_encoded_block_size = 11;
  46. const size_t encoded_block_sizes[] = {0, 2, 3, 5, 6, 7, 9, 10, full_encoded_block_size};
  47. const size_t full_block_size = sizeof(encoded_block_sizes) / sizeof(encoded_block_sizes[0]) - 1;
  48. const size_t addr_checksum_size = 4;
  49. const size_t max_bin_data_size = 72;
  50. const int decoded_block_sizes[] = {0, -1, 1, 2, -1, 3, 4, 5, -1, 6, 7, 8};
  51. #define reverse_alphabet(letter) ((int8_t)b58digits_map[(int)letter])
  52. uint64_t uint_8be_to_64(const uint8_t* data, size_t size) {
  53. assert(1 <= size && size <= sizeof(uint64_t));
  54. uint64_t res = 0;
  55. switch(9 - size) {
  56. case 1:
  57. res |= *data++; /* FALLTHRU */
  58. case 2:
  59. res <<= 8;
  60. res |= *data++; /* FALLTHRU */
  61. case 3:
  62. res <<= 8;
  63. res |= *data++; /* FALLTHRU */
  64. case 4:
  65. res <<= 8;
  66. res |= *data++; /* FALLTHRU */
  67. case 5:
  68. res <<= 8;
  69. res |= *data++; /* FALLTHRU */
  70. case 6:
  71. res <<= 8;
  72. res |= *data++; /* FALLTHRU */
  73. case 7:
  74. res <<= 8;
  75. res |= *data++; /* FALLTHRU */
  76. case 8:
  77. res <<= 8;
  78. res |= *data;
  79. break;
  80. default:
  81. assert(false);
  82. }
  83. return res;
  84. }
  85. void uint_64_to_8be(uint64_t num, size_t size, uint8_t* data) {
  86. assert(1 <= size && size <= sizeof(uint64_t));
  87. #if BYTE_ORDER == LITTLE_ENDIAN
  88. uint64_t num_be = SWAP64(num);
  89. #else
  90. uint64_t num_be = num;
  91. #endif
  92. memcpy(data, (uint8_t*)(&num_be) + sizeof(uint64_t) - size, size);
  93. }
  94. void encode_block(const char* block, size_t size, char* res) {
  95. assert(1 <= size && size <= full_block_size);
  96. uint64_t num = uint_8be_to_64((uint8_t*)(block), size);
  97. int i = ((int)(encoded_block_sizes[size])) - 1;
  98. while(0 <= i) {
  99. uint64_t remainder = num % alphabet_size;
  100. num /= alphabet_size;
  101. res[i] = b58digits_ordered[remainder];
  102. --i;
  103. }
  104. }
  105. bool decode_block(const char* block, size_t size, char* res) {
  106. assert(1 <= size && size <= full_encoded_block_size);
  107. int res_size = decoded_block_sizes[size];
  108. if(res_size <= 0) {
  109. return false; // Invalid block size
  110. }
  111. uint64_t res_num = 0;
  112. uint64_t order = 1;
  113. for(size_t i = size - 1; i < size; --i) {
  114. if(block[i] & 0x80) {
  115. return false; // Invalid symbol
  116. }
  117. int digit = reverse_alphabet(block[i]);
  118. if(digit < 0) {
  119. return false; // Invalid symbol
  120. }
  121. uint64_t product_hi = 0;
  122. uint64_t tmp = res_num + mul128(order, (uint64_t)digit, &product_hi);
  123. if(tmp < res_num || 0 != product_hi) {
  124. return false; // Overflow
  125. }
  126. res_num = tmp;
  127. // The original code comment for the order multiplication says
  128. // "Never overflows, 58^10 < 2^64"
  129. // This is incorrect since it overflows on the 11th iteration
  130. // However, there is no negative impact since the result is unused
  131. order *= alphabet_size;
  132. }
  133. if((size_t)res_size < full_block_size && (UINT64_C(1) << (8 * res_size)) <= res_num)
  134. return false; // Overflow
  135. uint_64_to_8be(res_num, res_size, (uint8_t*)(res));
  136. return true;
  137. }
  138. bool xmr_base58_encode(char* b58, size_t* b58sz, const void* data, size_t binsz) {
  139. if(binsz == 0) {
  140. if(b58sz) {
  141. *b58sz = 0;
  142. }
  143. return true;
  144. }
  145. const char* data_bin = data;
  146. size_t full_block_count = binsz / full_block_size;
  147. size_t last_block_size = binsz % full_block_size;
  148. size_t res_size =
  149. full_block_count * full_encoded_block_size + encoded_block_sizes[last_block_size];
  150. if(b58sz) {
  151. if(res_size > *b58sz) {
  152. return false;
  153. }
  154. *b58sz = res_size;
  155. }
  156. for(size_t i = 0; i < full_block_count; ++i) {
  157. encode_block(
  158. data_bin + i * full_block_size, full_block_size, b58 + i * full_encoded_block_size);
  159. }
  160. if(0 < last_block_size) {
  161. encode_block(
  162. data_bin + full_block_count * full_block_size,
  163. last_block_size,
  164. b58 + full_block_count * full_encoded_block_size);
  165. }
  166. return true;
  167. }
  168. bool xmr_base58_decode(const char* b58, size_t b58sz, void* data, size_t* binsz) {
  169. if(b58sz == 0) {
  170. *binsz = 0;
  171. return true;
  172. }
  173. size_t full_block_count = b58sz / full_encoded_block_size;
  174. size_t last_block_size = b58sz % full_encoded_block_size;
  175. int last_block_decoded_size = decoded_block_sizes[last_block_size];
  176. if(last_block_decoded_size < 0) {
  177. *binsz = 0;
  178. return false; // Invalid enc length
  179. }
  180. size_t data_size = full_block_count * full_block_size + last_block_decoded_size;
  181. if(*binsz < data_size) {
  182. *binsz = 0;
  183. return false;
  184. }
  185. char* data_bin = data;
  186. for(size_t i = 0; i < full_block_count; ++i) {
  187. if(!decode_block(
  188. b58 + i * full_encoded_block_size,
  189. full_encoded_block_size,
  190. data_bin + i * full_block_size)) {
  191. *binsz = 0;
  192. return false;
  193. }
  194. }
  195. if(0 < last_block_size) {
  196. if(!decode_block(
  197. b58 + full_block_count * full_encoded_block_size,
  198. last_block_size,
  199. data_bin + full_block_count * full_block_size)) {
  200. *binsz = 0;
  201. return false;
  202. }
  203. }
  204. *binsz = data_size;
  205. return true;
  206. }
  207. int xmr_base58_addr_encode_check(
  208. uint64_t tag,
  209. const uint8_t* data,
  210. size_t binsz,
  211. char* b58,
  212. size_t b58sz) {
  213. if(binsz > max_bin_data_size || tag > 127) { // tag varint
  214. return false;
  215. }
  216. size_t b58size = b58sz;
  217. uint8_t buf[(binsz + 1) + HASHER_DIGEST_LENGTH];
  218. memset(buf, 0, sizeof(buf));
  219. uint8_t* hash = buf + binsz + 1;
  220. buf[0] = (uint8_t)tag;
  221. memcpy(buf + 1, data, binsz);
  222. hasher_Raw(HASHER_SHA3K, buf, binsz + 1, hash);
  223. bool r = xmr_base58_encode(b58, &b58size, buf, binsz + 1 + addr_checksum_size);
  224. return (int)(!r ? 0 : b58size);
  225. }
  226. int xmr_base58_addr_decode_check(
  227. const char* addr,
  228. size_t sz,
  229. uint64_t* tag,
  230. void* data,
  231. size_t datalen) {
  232. size_t buflen = 1 + max_bin_data_size + addr_checksum_size;
  233. uint8_t buf[buflen];
  234. memset(buf, 0, sizeof(buf));
  235. uint8_t hash[HASHER_DIGEST_LENGTH] = {0};
  236. if(!xmr_base58_decode(addr, sz, buf, &buflen)) {
  237. return 0;
  238. }
  239. if(buflen <= addr_checksum_size + 1) {
  240. return 0;
  241. }
  242. size_t res_size = buflen - addr_checksum_size - 1;
  243. if(datalen < res_size) {
  244. return 0;
  245. }
  246. hasher_Raw(HASHER_SHA3K, buf, buflen - addr_checksum_size, hash);
  247. if(memcmp(hash, buf + buflen - addr_checksum_size, addr_checksum_size) != 0) {
  248. return 0;
  249. }
  250. *tag = buf[0];
  251. if(*tag > 127) {
  252. return false; // varint
  253. }
  254. memcpy(data, buf + 1, res_size);
  255. return (int)res_size;
  256. }
  257. #endif // USE_MONERO