Guest User

8chan signed messages, r1

a guest
Nov 4th, 2018
124
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // Replace this comment with the content of https://tweetnacl.js.org/nacl.min.js
  2. // Replace this comment with the content of https://tweetnacl.js.org/nacl-util.min.js
  3. +function() {
  4. function traverseHtml(node, v) {
  5.   if (node.nodeType == 3) {
  6.     v.ontext(node.textContent);
  7.   } else {
  8.     var tagName = node.tagName.toLowerCase();
  9.     v.onopentag(tagName, node);
  10.     for (var i = 0; i < node.childNodes.length; ++i) {
  11.       traverseHtml(node.childNodes[i], v);
  12.     }
  13.     v.onclosetag(tagName);
  14.   }
  15. }
  16. function reverseFormatNode(node) {
  17.   let chunks = [];
  18.   function append(str) {
  19.     chunks.push(str);
  20.   }
  21.   let eolStack = [];
  22.   let spanStack = [];
  23.   traverseHtml(node, {
  24.     onopentag: function(tagName, node) {
  25.       if (tagName === 'span' && node.className === 'heading') {
  26.         append("==");
  27.         eolStack.unshift("==");
  28.       } else if (tagName === 'span' && node.className === 'spoiler') {
  29.         append("**");
  30.         spanStack.push("**")
  31.       } else if (tagName === 'em') {
  32.         append("''");
  33.       } else if (tagName === 'strong') {
  34.         append("'''");
  35.       } else if (tagName === 'u') {
  36.         append("__");
  37.       } else if (tagName === 's') {
  38.         append("~~");
  39.       }
  40.     },
  41.     onclosetag: function(tagName) {
  42.       if (tagName === 'p') {
  43.         for (var i = 0; i < eolStack.length; ++i) {
  44.           append(eolStack[i]);
  45.         }
  46.         eolStack = [];
  47.         append("\n");
  48.       } else if (tagName === 'span') {
  49.         append(spanStack.pop());
  50.       } else if (tagName === 'em') {
  51.         append("''");
  52.       } else if (tagName === 'strong') {
  53.         append("'''");
  54.       } else if (tagName === 'u') {
  55.         append("__");
  56.       } else if (tagName === 's') {
  57.         append("~~");
  58.       }
  59.     },
  60.     ontext: function (text) {
  61.       text = text.replace(/—/g, '---');
  62.       text = text.replace(/–/g, '--');
  63.       append(text);
  64.     },
  65.   });
  66.   return chunks.join('');
  67. }
  68. function getThread() {
  69.   var ps = document.location.pathname.split('/');
  70.   var opNode = document.querySelector('.post .body');
  71.   var opHash = nacl.util.encodeBase64(nacl.hash(nacl.util.decodeUTF8(reverseFormatNode(opNode))));
  72.   var board = ps[1];
  73.   var threadId = ps[3].split('.')[0];
  74.   return {board: board, id: threadId, opHash: opHash};
  75. }
  76. function encodeMessage(thread, ts, msg) {
  77.   var text = [
  78.     "Board: " + thread.board,
  79.     "ThreadId: " + thread.id,
  80.     "OP: " + thread.opHash,
  81.     "TS: " + ts,
  82.     msg
  83.   ].join('\n');
  84.   console.log(text);
  85.   return nacl.util.decodeUTF8(text);
  86. }
  87. function checkPost(thread, node) {
  88.   var ranges = [], range, msg;
  89.   var cs = node.childNodes;
  90.   for (var i = 0; i < cs.length; ++i) {
  91.     var line = reverseFormatNode(cs[i]);
  92.     if (range) {
  93.       md = /^\*\*END SIG ([0-9A-Za-z+/]+=*)\*\*/.exec(line);
  94.       if (md) {
  95.         range.last = i;
  96.         range.sig = md[1];
  97.         range.msg = msg;
  98.         ranges.push(range);
  99.         range = undefined;
  100.       } else {
  101.         msg.push(line);
  102.       }
  103.     } else {
  104.       md = /^\*\*BEGIN SIG ([0-9]+) ([0-9A-Za-z+/]+=*)\*\*/.exec(line);
  105.       if (md) {
  106.         range = {first: i, ts: md[1], pub: md[2]};
  107.         msg = [];
  108.       }
  109.     }
  110.   }
  111.   for (var i = ranges.length - 1; i >= 0; i--) {
  112.     var range = ranges[i];
  113.     var text = encodeMessage(thread, range.ts, range.msg.join(''));
  114.     var sigOk = nacl.sign.detached.verify(
  115.       text,
  116.       nacl.util.decodeBase64(range.sig),
  117.       nacl.util.decodeBase64(range.pub));
  118.     // Remove the END line
  119.     node.removeChild(cs[range.last]);
  120.     // Replace the BEGIN line with a DIV
  121.     var div = document.createElement("div");
  122.     if (sigOk) {
  123.       div.className = "signed-message signature-good";
  124.       $(div).append("<p class='body-line ltr'>Good signature by <span class='public-key'>"
  125.         + range.pub + "</span></p>");
  126.     } else {
  127.       div.className = "signed-message signature-bad";
  128.       $(div).append("<p class='body-line ltr'>Signature could not be verified.</p>");
  129.     }
  130.     node.replaceChild(div, cs[range.first]);
  131.     // Move the message lines into the DIV
  132.     for (var j = range.first + 1; j < range.last; j++) {
  133.       div.appendChild(cs[range.first + 1]);
  134.     }
  135.   }
  136. }
  137. function checkSignatures() {
  138.   var thread = getThread();
  139.   $('.post .body').each(function (i, el) { checkPost(thread, el); });
  140. }
  141. function signPostBody() {
  142.   var ts = new Date().getTime().toString();
  143.   var msg = $('#body').val() + "\n";
  144.   var text = encodeMessage(getThread(), ts, msg);
  145.   var sig = nacl.util.encodeBase64(nacl.sign.detached(text, nacl.util.decodeBase64(window.localStorage.secretKey)));
  146.   $('#body').val(`**BEGIN SIG ${ts} ${window.localStorage.publicKey}**\n${msg}**END SIG ${sig}**\n`);
  147. }
  148. $(function(){
  149.   if (!window.localStorage.secretKey) {
  150.     var keys = nacl.sign.keyPair();
  151.     window.localStorage.secretKey = nacl.util.encodeBase64(keys.secretKey);
  152.     window.localStorage.publicKey = nacl.util.encodeBase64(keys.publicKey);
  153.   }
  154.   $(document.head).append(`<style>
  155.     .signed-message { padding: 2px; }
  156.     .signed-message.signature-good { border: 2px solid green; }
  157.     .signed-message.signature-bad { border: 2px solid red; }
  158.     span.public-key { font-family: monospace; font-size: 80%; color: #181; }
  159.   </style>`);
  160.   $('#post-form-inner tr:nth(2) td').append('<input id="sign-button" accesskey="i" style="margin-left:2px;" type="button" name="sign" value="Sign">');
  161.   $('#sign-button').on('click', signPostBody);
  162.   $(document).on('new_post', checkSignatures);
  163.   checkSignatures();
  164. });
  165. }();
Advertisement
Add Comment
Please, Sign In to add comment