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.

rfc1751.js 3.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. "use strict";
  2. var __importDefault = (this && this.__importDefault) || function (mod) {
  3. return (mod && mod.__esModule) ? mod : { "default": mod };
  4. };
  5. Object.defineProperty(exports, "__esModule", { value: true });
  6. exports.keyToRFC1751Mnemonic = exports.rfc1751MnemonicToKey = void 0;
  7. const rfc1751Words_json_1 = __importDefault(require("./rfc1751Words.json"));
  8. const rfc1751WordList = rfc1751Words_json_1.default;
  9. const BINARY = ['0000', '0001', '0010', '0011', '0100', '0101', '0110', '0111',
  10. '1000', '1001', '1010', '1011', '1100', '1101', '1110', '1111'];
  11. function keyToBinary(key) {
  12. let res = '';
  13. for (const num of key) {
  14. res += BINARY[num >> 4] + BINARY[num & 0x0f];
  15. }
  16. return res;
  17. }
  18. function extract(key, start, length) {
  19. const subKey = key.substring(start, start + length);
  20. let acc = 0;
  21. for (let index = 0; index < subKey.length; index++) {
  22. acc = acc * 2 + subKey.charCodeAt(index) - 48;
  23. }
  24. return acc;
  25. }
  26. function keyToRFC1751Mnemonic(hex_key) {
  27. const buf = Buffer.from(hex_key.replace(/\s+/gu, ''), 'hex');
  28. let key = bufferToArray(swap128(buf));
  29. const padding = [];
  30. for (let index = 0; index < (8 - (key.length % 8)) % 8; index++) {
  31. padding.push(0);
  32. }
  33. key = padding.concat(key);
  34. const english = [];
  35. for (let index = 0; index < key.length; index += 8) {
  36. const subKey = key.slice(index, index + 8);
  37. let skbin = keyToBinary(subKey);
  38. let parity = 0;
  39. for (let j = 0; j < 64; j += 2) {
  40. parity += extract(skbin, j, 2);
  41. }
  42. subKey.push((parity << 6) & 0xff);
  43. skbin = keyToBinary(subKey);
  44. for (let j = 0; j < 64; j += 11) {
  45. english.push(rfc1751WordList[extract(skbin, j, 11)]);
  46. }
  47. }
  48. return english.join(' ');
  49. }
  50. exports.keyToRFC1751Mnemonic = keyToRFC1751Mnemonic;
  51. function rfc1751MnemonicToKey(english) {
  52. const words = english.split(' ');
  53. let key = [];
  54. for (let index = 0; index < words.length; index += 6) {
  55. const { subKey, word } = getSubKey(words, index);
  56. const skbin = keyToBinary(subKey);
  57. let parity = 0;
  58. for (let j = 0; j < 64; j += 2) {
  59. parity += extract(skbin, j, 2);
  60. }
  61. const cs0 = extract(skbin, 64, 2);
  62. const cs1 = parity & 3;
  63. if (cs0 !== cs1) {
  64. throw new Error(`Parity error at ${word}`);
  65. }
  66. key = key.concat(subKey.slice(0, 8));
  67. }
  68. const bufferKey = swap128(Buffer.from(key));
  69. return bufferKey;
  70. }
  71. exports.rfc1751MnemonicToKey = rfc1751MnemonicToKey;
  72. function getSubKey(words, index) {
  73. const sublist = words.slice(index, index + 6);
  74. let bits = 0;
  75. const ch = [0, 0, 0, 0, 0, 0, 0, 0, 0];
  76. let word = '';
  77. for (word of sublist) {
  78. const idx = rfc1751WordList.indexOf(word.toUpperCase());
  79. if (idx === -1) {
  80. throw new TypeError(`Expected an RFC1751 word, but received '${word}'. ` +
  81. `For the full list of words in the RFC1751 encoding see https://datatracker.ietf.org/doc/html/rfc1751`);
  82. }
  83. const shift = (8 - ((bits + 11) % 8)) % 8;
  84. const y = idx << shift;
  85. const cl = y >> 16;
  86. const cc = (y >> 8) & 0xff;
  87. const cr = y & 0xff;
  88. const t = Math.floor(bits / 8);
  89. if (shift > 5) {
  90. ch[t] |= cl;
  91. ch[t + 1] |= cc;
  92. ch[t + 2] |= cr;
  93. }
  94. else if (shift > -3) {
  95. ch[t] |= cc;
  96. ch[t + 1] |= cr;
  97. }
  98. else {
  99. ch[t] |= cr;
  100. }
  101. bits += 11;
  102. }
  103. const subKey = ch.slice();
  104. return { subKey, word };
  105. }
  106. function bufferToArray(buf) {
  107. return Array.prototype.slice.call(buf);
  108. }
  109. function swap128(buf) {
  110. const reversedBytes = buf.swap64();
  111. return Buffer.concat([reversedBytes.slice(8, 16), reversedBytes.slice(0, 8)], 16);
  112. }
  113. //# sourceMappingURL=rfc1751.js.map