Advertisement
uaa

[wip:20230317] nostr npub/nsec key -> hex

uaa
Mar 17th, 2023
131
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.11 KB | None | 0 0
  1. // SPDX-License-Identifier: WTFPL
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <stdlib.h>
  5. #include <stdint.h>
  6. #include <ctype.h>
  7.  
  8. #define unpacked_size(x) (((x) * 8 + 4) / 5) // round-up
  9. #define packed_size(x) (((x) * 5) / 8) // round-down
  10. #define expanded_hrp_size(x) (((x) * 2) + 1)
  11.  
  12. #define BECH32_CHECKSUM_LEN 6
  13.  
  14. static void hexdump(unsigned char *buf, int size)
  15. {
  16. int i;
  17.  
  18. for (i = 0; i < size; i++)
  19. printf("%02x ", buf[i]);
  20.  
  21. printf("\n");
  22. }
  23.  
  24. static uint32_t bech32_polymod(uint8_t *values, int len)
  25. {
  26. uint32_t b, chk = 1;
  27. int i;
  28.  
  29. for (i = 0; i < len; i++) {
  30. b = (chk >> 25);
  31. chk = (chk & 0x01ffffff) << 5 ^ (values[i] & 0x01f);
  32. chk ^= (b & 0x01) ? 0x3b6a57b2 : 0;
  33. chk ^= (b & 0x02) ? 0x26508e6d : 0;
  34. chk ^= (b & 0x04) ? 0x1ea119fa : 0;
  35. chk ^= (b & 0x08) ? 0x3d4233dd : 0;
  36. chk ^= (b & 0x10) ? 0x2a1462b3 : 0;
  37. }
  38.  
  39. return chk;
  40. }
  41.  
  42. static uint8_t bech32_char_decode(int c)
  43. {
  44. const static uint8_t decode_table[] = {
  45. 0x0f, 0xff, 0x0a, 0x11, 0x15, 0x14, 0x1a, 0x1e, // 01234567
  46. 0x07, 0x05, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // 89:;<=>?
  47. 0xff, 0x1d, 0xff, 0x18, 0x0d, 0x19, 0x09, 0x08, // @ABCDEFG
  48. 0x17, 0xff, 0x12, 0x16, 0x1f, 0x1b, 0x13, 0xff, // HIJKLMNO
  49. 0x01, 0x00, 0x03, 0x10, 0x0b, 0x1c, 0x0c, 0x0e, // PQRSTUVW
  50. 0x06, 0x04, 0x02, 0xff, 0xff, 0xff, 0xff, 0xff, // XYZ[\]^_
  51. };
  52.  
  53. /* use upper case to reduce table size */
  54. if (c >= 'a' && c <= 'z') c -= 'a' - 'A';
  55.  
  56. return (c < '0' || c > 'Z') ? 0xff : decode_table[c - '0'];
  57. }
  58.  
  59. static int pack5to8(uint8_t *out, int outlen, uint8_t *in, int inlen)
  60. {
  61. int inpos, outpos, olen;
  62. uint64_t v;
  63.  
  64. olen = packed_size(inlen);
  65. outlen = (outlen < olen) ? outlen : olen;
  66.  
  67. for (inpos = outpos = 0; inpos < inlen && outpos < outlen; ) {
  68. v = (uint64_t)(in[inpos++] & 0x1f) << 35;
  69. if (inpos < inlen) v |= (uint64_t)(in[inpos++] & 0x1f) << 30;
  70. if (inpos < inlen) v |= (uint64_t)(in[inpos++] & 0x1f) << 25;
  71. if (inpos < inlen) v |= (uint64_t)(in[inpos++] & 0x1f) << 20;
  72. if (inpos < inlen) v |= (uint64_t)(in[inpos++] & 0x1f) << 15;
  73. if (inpos < inlen) v |= (uint64_t)(in[inpos++] & 0x1f) << 10;
  74. if (inpos < inlen) v |= (uint64_t)(in[inpos++] & 0x1f) << 5;
  75. if (inpos < inlen) v |= (uint64_t)(in[inpos++] & 0x1f);
  76.  
  77. out[outpos++] = v >> 32;
  78. if (outpos < outlen) out[outpos++] = v >> 24;
  79. if (outpos < outlen) out[outpos++] = v >> 16;
  80. if (outpos < outlen) out[outpos++] = v >> 8;
  81. if (outpos < outlen) out[outpos++] = v;
  82. }
  83.  
  84. return outpos;
  85. }
  86.  
  87. static int unpack8to5(uint8_t *out, int outlen, uint8_t *in, int inlen)
  88. {
  89. int inpos, outpos, olen;
  90. uint64_t v;
  91.  
  92. olen = unpacked_size(inlen);
  93. outlen = (outlen < olen) ? outlen : olen;
  94.  
  95. for (inpos = outpos = 0; inpos < inlen && outpos < outlen; ) {
  96. v = (uint64_t)in[inpos++] << 32;
  97. if (inpos < inlen) v |= (uint64_t)in[inpos++] << 24;
  98. if (inpos < inlen) v |= (uint64_t)in[inpos++] << 16;
  99. if (inpos < inlen) v |= (uint64_t)in[inpos++] << 8;
  100. if (inpos < inlen) v |= (uint64_t)in[inpos++];
  101.  
  102. out[outpos++] = (v >> 35) & 0x1f;
  103. if (outpos < outlen) out[outpos++] = (v >> 30) & 0x1f;
  104. if (outpos < outlen) out[outpos++] = (v >> 25) & 0x1f;
  105. if (outpos < outlen) out[outpos++] = (v >> 20) & 0x1f;
  106. if (outpos < outlen) out[outpos++] = (v >> 15) & 0x1f;
  107. if (outpos < outlen) out[outpos++] = (v >> 10) & 0x1f;
  108. if (outpos < outlen) out[outpos++] = (v >> 5) & 0x1f;
  109. if (outpos < outlen) out[outpos++] = v & 0x1f;
  110. }
  111.  
  112. return outpos;
  113. }
  114.  
  115. static int expand_hrp(uint8_t *out, int outlen, char *in, int inlen)
  116. {
  117. int inpos, outpos, olen;
  118.  
  119. olen = expanded_hrp_size(inlen);
  120. outlen = (outlen < olen) ? outlen : olen;
  121.  
  122. for (inpos = outpos = 0; inpos < inlen && outpos < outlen; )
  123. out[outpos++] = (in[inpos++] >> 5) & 0x07;
  124.  
  125. if (outpos < outlen)
  126. out[outpos++] = 0;
  127.  
  128. for (inpos = 0; inpos < inlen && outpos < outlen; )
  129. out[outpos++] = in[inpos++] & 0x1f;
  130.  
  131. return outpos;
  132. }
  133.  
  134. int nostr_key_decode(char *str, uint8_t *hex, int hexlen)
  135. {
  136. int i, j, hrplen, tmpsize, v = -1;
  137. char *sep;
  138. uint8_t *tmp;
  139.  
  140. /* get HRP length */
  141. if ((sep = strchr(str, '1')) == NULL)
  142. goto fin0;
  143. hrplen = sep - str;
  144.  
  145. /* allocate working buffer */
  146. tmpsize = expanded_hrp_size(hrplen) +
  147. unpacked_size(hexlen) + BECH32_CHECKSUM_LEN;
  148. if ((tmp = calloc(tmpsize, sizeof(*tmp))) == NULL)
  149. goto fin0;
  150.  
  151. /* expand HRP string to calculate checksum */
  152. expand_hrp(tmp, tmpsize, str, hrplen);
  153.  
  154. /* decode bech32 string with checksum */
  155. for (i = hrplen + 1, j = expanded_hrp_size(hrplen); str[i]; i++, j++)
  156. if ((tmp[j] = bech32_char_decode(str[i])) == 0xff)
  157. goto fin1;
  158.  
  159. /* validate checksum */
  160. if (bech32_polymod(tmp, tmpsize) != 1)
  161. goto fin1;
  162.  
  163. /* output result */
  164. pack5to8(hex, hexlen, tmp + expanded_hrp_size(hrplen),
  165. unpacked_size(hexlen));
  166.  
  167. fin1:
  168. memset(tmp, 0, tmpsize);
  169. free(tmp);
  170. fin0:
  171. return v;
  172. }
  173.  
  174.  
  175. int main(int argc, char *argv[])
  176. {
  177. #define NOSTR_HEXKEY_LEN 32
  178.  
  179. char str[] = "npub1rarr265r9f9j6ewp960hcm7cvz9zskc7l2ykwul57e7xa60r8css7uf890";
  180. uint8_t buf[NOSTR_HEXKEY_LEN];
  181.  
  182. memset(buf, 0xff, sizeof(buf));
  183. nostr_key_decode(str, buf, 32);
  184. hexdump(buf, NOSTR_HEXKEY_LEN);
  185.  
  186. return 0;
  187.  
  188. }
  189.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement