<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <style type="text/css"> pre { font-family: monospace; display: block; white-space: pre; font-size: 2em; } </style> </head> <body> <script type="text/javascript"> if (!Math.imul) Math.imul = function(a,b) {return (a*b)|0;}/* function(a, b) { var aHi = (a >>> 16) & 0xffff; var aLo = a & 0xffff; var bHi = (b >>> 16) & 0xffff; var bLo = b & 0xffff; // the shift by 0 fixes the sign on the high part // the final |0 converts the unsigned value into a signed value return ((aLo * bLo) + (((aHi * bLo + aLo * bHi) << 16) >>> 0) | 0); };*/ if (!Math.clz32) Math.clz32 = (function(log, LN2){ return function(x) { // Let n be ToUint32(x). // Let p be the number of leading zero bits in // the 32-bit binary representation of n. // Return p. var asUint = x >>> 0; if (asUint === 0) { return 32; } return 31 - (log(asUint) / LN2 | 0) |0; // the "| 0" acts like math.floor }; })(Math.log, Math.LN2); </script> <script src="https://cdn.jsdelivr.net/npm/promise-polyfill@8/dist/polyfill.min.js"></script> <script type="text/javascript" src="../lib/olm/olm_legacy.js"></script> <script type="text/javascript"> function doit(log) { var alice = new Olm.Account(); alice.create(); log("alice", alice.identity_keys()); var bob = new Olm.Account(); bob.unpickle("secret", "EWfA87or4GgQ+wqVkyuFiW9gUk3FI6QSXgp8E2dS5RFLvXgy4oFvxwQ1gVnbMkdJz2Hy9ex9UmJ/ZyuRU0aRt0IwXpw/SUNq4IQeVJ7J/miXW7rV4Ep+4RSEf945KbDrokDCS2CoL5PIfv/NYyey32gA0hMi8wWIfIlOxFBV4SBJYSC+Qd54VjprwCg0Sn9vjQouKVrM/+5jzsv9+JK5OpWW0Vrb3qrXwyAOEAQ4WlOQcqZHAyPQIw"); log("bob", bob.identity_keys()); // generate OTK on receiver side bob.generate_one_time_keys(1); var bobOneTimeKeys = JSON.parse(bob.one_time_keys()); var otkName = Object.getOwnPropertyNames(bobOneTimeKeys.curve25519)[0]; var bobOneTimeKey = bobOneTimeKeys.curve25519[otkName]; // encrypt var aliceSession = new Olm.Session(); aliceSession.create_outbound( alice, JSON.parse(bob.identity_keys()).curve25519, bobOneTimeKey ); log("alice outbound session created"); var aliceSessionPickled = aliceSession.pickle("secret"); log("aliceSession pickled", aliceSessionPickled); try { var tmp = new Olm.Session(); tmp.unpickle("secret", aliceSessionPickled); log("aliceSession unpickled"); } finally { tmp.free(); } var message = aliceSession.encrypt("hello secret world"); log("message", message); // decrypt var bobSession = new Olm.Session(); bobSession.create_inbound(bob, message.body); var plaintext = bobSession.decrypt(message.type, message.body); log("plaintext", plaintext); // remove Bob's OTK as it was used to start an olm session log("bob OTK before removing", bob.one_time_keys()); bob.remove_one_time_keys(bobSession); log("bob OTK after removing", bob.one_time_keys()); } if (window.msCrypto && !window.crypto) { window.crypto = window.msCrypto; } function doRun(e) { e.target.setAttribute("disabled", "disabled"); var logEl = document.getElementById("log"); logEl.innerText = ""; var startTime = performance.now(); function log() { var timeDiff = Math.round(performance.now() - startTime).toString(); while (timeDiff.length < 5) { timeDiff = "0" + timeDiff; } logEl.appendChild(document.createTextNode(timeDiff + " ")); for (var i = 0; i < arguments.length; i += 1) { var value = arguments[i]; if (typeof value !== "string") { value = JSON.stringify(value); } logEl.appendChild(document.createTextNode(value + " ")); } logEl.appendChild(document.createTextNode("\n")); } doit(log); e.target.removeAttribute("disabled"); } function main() { Olm.init( ).then(function() { var startButton = document.getElementById("start"); startButton.innerText = "Start"; startButton.addEventListener("click", doRun); }); } document.addEventListener("DOMContentLoaded", main); </script> <pre id="log"></pre> <button id="start">Loading...</button> </body> </html>