]> foleosoft.com Git - QAnsel.git/commitdiff
Mon Jan 20 01:27:02 PM EST 2025
authormiha-q <>
Mon, 20 Jan 2025 18:27:02 +0000 (13:27 -0500)
committermiha-q <>
Mon, 20 Jan 2025 18:27:02 +0000 (13:27 -0500)
src/www/imports/code.html
src/www/imports/estouls-api.js [deleted file]
src/www/imports/rosado-api.js [new file with mode: 0644]
src/www/index.html

index 4d2ba5eb52f756b43e2ff18b79d7303b3634afe4..0ee9e62195840471b09a46c9c2701f96c3ca01d1 100644 (file)
@@ -1,10 +1,10 @@
 <!DOCTYPE html>
 <html>
 <head>
-       <title>EstoulsAPI</title>
+       <title>RosadoAPI</title>
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <link href="istina-editor.css" rel="stylesheet" />
-       <script src="estouls-api.js"></script>
+       <script src="rosado-api.js"></script>
        <script src="istina-editor.js"></script>
 </head>
 <body>
@@ -107,7 +107,7 @@ else
        {
                var a = document.createElement("a");
                a.href = "/apk";
-               a.download = "EstoulsAPI.apk";
+               a.download = "RosadoAPI.apk";
                a.style.display = "none";
                document.body.appendChild(a);
                a.click();
@@ -212,10 +212,10 @@ else
                        return;
                }
                
-               EstoulsAPI.username = dat[0];
-               EstoulsAPI.apikey = dat[1];
-               EstoulsAPI.endpoint = "https://" + dat[2];
-               EstoulsAPI.request(IstinaEditor.getText()).then(x =>
+               RosadoAPI.username = dat[0];
+               RosadoAPI.apikey = dat[1];
+               RosadoAPI.endpoint = "https://" + dat[2];
+               RosadoAPI.request(IstinaEditor.getText()).then(x =>
                {
                        if (x.success && x.response.trim().length > 0)
                        {
diff --git a/src/www/imports/estouls-api.js b/src/www/imports/estouls-api.js
deleted file mode 100644 (file)
index 73760d7..0000000
+++ /dev/null
@@ -1,357 +0,0 @@
-var EstoulsAPI =
-{
-       username: undefined,
-       apikey: undefined,
-       endpoint: undefined,
-       
-       Math32:
-       {
-               clamp: a =>
-               {
-                       while (a < 0 || a > 0xFFFFFFFF)
-                               a += a < 0 ? 0x100000000 : -0x100000000;
-                       return a;
-               },
-               shl: (a, b) => EstoulsAPI.Math32.clamp(a << b),
-               shr: (a, b) => EstoulsAPI.Math32.clamp(a >>> b),
-               rtl: (a, b) => EstoulsAPI.Math32.clamp((a << b) | (a >>> (32 - b))),
-               rtr: (a, b) => EstoulsAPI.Math32.clamp((a >>> b) | (a << (32 - b))),
-               add: (a, b) => EstoulsAPI.Math32.clamp(a + b),
-               sub: (a, b) => EstoulsAPI.Math32.clamp(a + b),
-               or: (a, b) => EstoulsAPI.Math32.clamp(a | b),
-               xor: (a, b) => EstoulsAPI.Math32.clamp(a ^ b)
-       },
-       HMACSHA256:
-       {
-               sign: async (key, msg) =>
-               {
-                       key = new Uint8Array(key);
-                       msg = new Uint8Array(msg);
-                       var ikey = await crypto.subtle.importKey
-                       (
-                               "raw",
-                               key,
-                               { name: "HMAC", hash: { name: "SHA-256" }},
-                               false,
-                               ["sign", "verify"]
-                       );
-                       return new Uint8Array(await window.crypto.subtle.sign({ name: "HMAC", }, ikey, msg));
-               }
-       },
-       ChaCha20:
-       {
-               QR: (cc, a, b, c, d) =>
-               {
-                       cc[a] = EstoulsAPI.Math32.add(cc[a], cc[b]);
-                       cc[d] = EstoulsAPI.Math32.xor(cc[d], cc[a]);
-                       cc[d] = EstoulsAPI.Math32.rtl(cc[d], 16);
-
-                       cc[c] = EstoulsAPI.Math32.add(cc[c], cc[d]);
-                       cc[b] = EstoulsAPI.Math32.xor(cc[b], cc[c]);
-                       cc[b] = EstoulsAPI.Math32.rtl(cc[b], 12);
-
-                       cc[a] = EstoulsAPI.Math32.add(cc[a], cc[b]);
-                       cc[d] = EstoulsAPI.Math32.xor(cc[d], cc[a]);
-                       cc[d] = EstoulsAPI.Math32.rtl(cc[d], 8);
-                       
-                       cc[c] = EstoulsAPI.Math32.add(cc[c], cc[d]);
-                       cc[b] = EstoulsAPI.Math32.xor(cc[b], cc[c]);
-                       cc[b] = EstoulsAPI.Math32.rtl(cc[b], 7);
-               },
-               DR: (cc) =>
-               {       
-                       EstoulsAPI.ChaCha20.QR(cc, 0, 4,  8, 12);
-                       EstoulsAPI.ChaCha20.QR(cc, 1, 5,  9, 13);
-                       EstoulsAPI.ChaCha20.QR(cc, 2, 6, 10, 14);
-                       EstoulsAPI.ChaCha20.QR(cc, 3, 7, 11, 15);
-                       EstoulsAPI.ChaCha20.QR(cc, 0, 5, 10, 15);
-                       EstoulsAPI.ChaCha20.QR(cc, 1, 6, 11, 12);
-                       EstoulsAPI.ChaCha20.QR(cc, 2, 7,  8, 13);
-                       EstoulsAPI.ChaCha20.QR(cc, 3, 4,  9, 14);                               
-               },
-               CB: (cc) =>
-               {
-                       var i;
-                       var x = new Array(16);
-                       for (i = 0; i < 16; i++)
-                       {
-                               x[i] = cc[i];
-                       }
-                       for (i = 0; i < 10; i++)
-                       {
-                               EstoulsAPI.ChaCha20.DR(cc);
-                       }
-                       for (i = 0; i < 16; i++)
-                       {
-                               cc[i] = EstoulsAPI.Math32.add(cc[i], x[i]);
-                       }
-               },
-               S: (cc, cs) =>
-               {
-                       for (var i = 0; i < 16; i++)
-                       {
-                               cs[4 * i] = (cc[i] & 0xFF);
-                               cs[4 * i + 1] = ((cc[i] >> 8) & 0xFF);
-                               cs[4 * i + 2] = ((cc[i] >> 16) & 0xFF);
-                               cs[4 * i + 3] = ((cc[i] >> 24) & 0xFF);
-                       }
-               },
-               B: (key, nonce, block, out) =>
-               {
-                       var cc =
-                       [
-                               0x61707865, 0x3320646e, 0x79622d32, 0x6b206574,
-
-                               key[0] | (key[1] << 8) | (key[2] << 16) | (key[3] << 24),
-                               key[4] | (key[5] << 8) | (key[6] << 16) | (key[7] << 24),
-                               key[8] | (key[9] << 8) | (key[10] << 16) | (key[11] << 24),
-                               key[12] | (key[13] << 8) | (key[14] << 16) | (key[15] << 24),
-
-                               key[16] | (key[17] << 8) | (key[18] << 16) | (key[19] << 24),
-                               key[20] | (key[21] << 8) | (key[22] << 16) | (key[23] << 24),
-                               key[24] | (key[25] << 8) | (key[26] << 16) | (key[27] << 24),
-                               key[28] | (key[29] << 8) | (key[30] << 16) | (key[31] << 24),
-
-                               block,
-
-                               nonce[0] | (nonce[1] << 8) | (nonce[2] << 16) | (nonce[3] << 24),
-                               nonce[4] | (nonce[5] << 8) | (nonce[6] << 16) | (nonce[7] << 24),
-                               nonce[8] | (nonce[9] << 8) | (nonce[10] << 16) | (nonce[11] << 24)
-                       ];
-
-                       EstoulsAPI.ChaCha20.CB(cc);
-                       EstoulsAPI.ChaCha20.S(cc, out);
-               },
-               encrypt: async (key, nonce, block, data) =>
-               {
-                       var count = data.length;
-                       if (count > (274877906944 - block * 64)) return null;
-                       var ret = new Array(0);
-                       var ccblock = new Array(64);
-                       var size = 0;
-                       while (count > 64)
-                       {
-                               ret.length = size + 64;
-                               EstoulsAPI.ChaCha20.B(key, nonce, block++, ccblock);
-                               for (var i = 0; i < 64; i++) ret[size + i] = ccblock[i];
-                               size += 64;
-                               count -= 64;
-                       }
-                       if (count > 0)
-                       {
-                               ret.length = size + count;
-                               EstoulsAPI.ChaCha20.B(key, nonce, block, ccblock);
-                               for (var i = 0; i < count; i++) ret[size + i] = ccblock[i];
-                       }
-                       for (var i = 0; i < data.length; i++) ret[i] ^= data[i];
-                       return new Uint8Array(ret);
-               }
-       },
-       
-       Base64:
-       {
-               encode: async (x) =>
-               {
-                       return await new Promise(r =>
-                       {
-                               const reader = new FileReader();
-                               reader.addEventListener("load", () => r(reader.result.split(",")[1]));
-                               reader.readAsDataURL(new Blob([new Uint8Array(x)]));                            
-                       });
-               },
-               
-               decode: (b64) =>
-               {
-                       var dec1 = (v) =>
-                       {
-                               switch (v)
-                               {
-                                       case 'A': return  0;
-                                       case 'B': return  1;
-                                       case 'C': return  2;
-                                       case 'D': return  3;
-                                       case 'E': return  4;
-                                       case 'F': return  5;
-                                       case 'G': return  6;
-                                       case 'H': return  7;
-                                       case 'I': return  8;
-                                       case 'J': return  9;
-                                       case 'K': return 10;
-                                       case 'L': return 11;
-                                       case 'M': return 12;
-                                       case 'N': return 13;
-                                       case 'O': return 14;
-                                       case 'P': return 15;
-                                       case 'Q': return 16;
-                                       case 'R': return 17;
-                                       case 'S': return 18;
-                                       case 'T': return 19;
-                                       case 'U': return 20;
-                                       case 'V': return 21;
-                                       case 'W': return 22;
-                                       case 'X': return 23;
-                                       case 'Y': return 24;
-                                       case 'Z': return 25;
-                                       case 'a': return 26;
-                                       case 'b': return 27;
-                                       case 'c': return 28;
-                                       case 'd': return 29;
-                                       case 'e': return 30;
-                                       case 'f': return 31;
-                                       case 'g': return 32;
-                                       case 'h': return 33;
-                                       case 'i': return 34;
-                                       case 'j': return 35;
-                                       case 'k': return 36;
-                                       case 'l': return 37;
-                                       case 'm': return 38;
-                                       case 'n': return 39;
-                                       case 'o': return 40;
-                                       case 'p': return 41;
-                                       case 'q': return 42;
-                                       case 'r': return 43;
-                                       case 's': return 44;
-                                       case 't': return 45;
-                                       case 'u': return 46;
-                                       case 'v': return 47;
-                                       case 'w': return 48;
-                                       case 'x': return 49;
-                                       case 'y': return 50;
-                                       case 'z': return 51;
-                                       case '0': return 52;
-                                       case '1': return 53;
-                                       case '2': return 54;
-                                       case '3': return 55;
-                                       case '4': return 56;
-                                       case '5': return 57;
-                                       case '6': return 58;
-                                       case '7': return 59;
-                                       case '8': return 60;
-                                       case '9': return 61;
-                                       case '+': return 62;
-                                       case '/': return 63;
-                               }
-                               return 255;
-                       };
-                       
-                       var ret = new Array(0);
-                       var buffer = 0;
-                       var bufferS = 0;
-                       for (var i = 0; i < b64.length; i++)
-                       {
-                               if (b64[i] == '=') { bufferS = 0; continue; };
-                               var val = dec1(b64[i]);
-                               if (val == 255) return null;
-                               buffer = ((buffer << 6) | val) & 0xFFFF;
-                               bufferS += 6;
-                               if (bufferS >= 8)
-                               {
-                                       var shift = (16 - bufferS) & 0xFF;
-                                       buffer = (buffer << shift) & 0xFFFF;
-                                       ret[ret.length] = (buffer >>> 8) & 0xFF;
-                                       buffer = buffer & 0x00FF;
-                                       buffer = (buffer >>> shift) & 0xFFFF;
-                                       bufferS -= 8;
-                               }
-                       }
-                       if (bufferS > 0)
-                       {
-                               buffer = (buffer << (16 - bufferS)) & 0xFFFF;
-                               ret[ret.length] = (buffer >>> 8) & 0xFF;
-                       }
-                       return new Uint8Array(ret);
-               }
-       },
-       
-       Hex:
-       {
-               encode: (x) =>
-               {
-                       var ret = "";
-                       x.forEach(y => { ret += y.toString(16).padStart(2, "0"); });
-                       return ret;
-               },
-               decode: (x) =>
-               {
-                       var arr = new Array(0);
-                       for (var i = 0; i < x.length; i += 2)
-                       {
-                               arr[arr.length] = parseInt(x.charAt(i) + x.charAt(i + 1), 16);
-                       }
-                       return new Uint8Array(arr);
-               }
-       },
-       
-       generateRequest: async (msg) =>
-       {
-               msg = new TextEncoder().encode(msg);
-               var key = EstoulsAPI.Hex.decode(EstoulsAPI.apikey);
-               //var sess = crypto.getRandomValues(new Uint8Array(12));
-               var r = () => { return Math.floor(Math.random() * 10000) % 256 };;
-               var sess = new Uint8Array([r(), r(), r(), r(), r(), r(), r(), r(), r(), r(), r(), r()]);
-               var rawdata = await EstoulsAPI.ChaCha20.encrypt(key, sess, 0, msg);
-               var dgst = await EstoulsAPI.Hex.encode(await EstoulsAPI.HMACSHA256.sign(key, rawdata));
-               var data = await EstoulsAPI.Base64.encode(rawdata);
-               var resp = "user=" + EstoulsAPI.username;
-               resp += "&sess=" + EstoulsAPI.Hex.encode(sess);
-               resp += "&dgst=" + dgst;
-               resp += "&data=" + data;
-               return resp;
-       },
-       
-       parseResponse: async (msg) =>
-       {
-               if (!msg.includes("user=") || !msg.includes("&sess=") || !msg.includes("&dgst=") || !msg.includes("&data="))
-               {
-                       return { success: false, response: "invalid response" };
-               }
-               var user = msg.split("user=")[1].split("&")[0].trim();
-               var sess = msg.split("&sess=")[1].split("&")[0].trim();
-               var dgst = msg.split("&dgst=")[1].split("&")[0].trim();
-               var data = msg.split("&data=")[1].split("&")[0].trim();
-               
-               if (user != EstoulsAPI.username)
-               {
-                       return { success: false, response: "invalid user in response" };
-               }
-               data = EstoulsAPI.Base64.decode(data);
-               sess = EstoulsAPI.Hex.decode(sess);
-               var key = EstoulsAPI.Hex.decode(EstoulsAPI.apikey);
-               var sig = await EstoulsAPI.Hex.encode(await EstoulsAPI.HMACSHA256.sign(key, data));
-               if (sig != dgst)
-               {
-                       return { success: false, response: "invalid signature" };
-               }
-               var resp = await EstoulsAPI.ChaCha20.encrypt(key, sess, 0, data);
-               return { success: true, response: new TextDecoder().decode(resp) };
-       },
-       
-       request: async (msg) =>
-       {
-               if (msg.trim().length == 0) return { success: true, response: "" };
-               var req = await EstoulsAPI.generateRequest(msg);
-               return await new Promise(r =>
-               {
-                       const xhr = new XMLHttpRequest();
-                       xhr.open("POST", EstoulsAPI.endpoint, true);
-                       xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
-                       xhr.onreadystatechange = (x) =>
-                       {
-                               if (xhr.readyState === XMLHttpRequest.DONE)
-                               {
-                                       if (xhr.status === 200)
-                                       {
-                                               EstoulsAPI.parseResponse(xhr.responseText).then(pr => { r(pr); }).catch(x => alert("ERR(3)"));
-                                       }
-                                       else
-                                       {
-                                               r({success: false, response: xhr.status});
-                                       }
-                               }
-                       }
-                       xhr.send(req);
-               }).catch(x => alert("ERR(1): " + x));
-       }
-       
-};
-
diff --git a/src/www/imports/rosado-api.js b/src/www/imports/rosado-api.js
new file mode 100644 (file)
index 0000000..bb8d769
--- /dev/null
@@ -0,0 +1,356 @@
+var RosadoAPI =
+{
+       username: undefined,
+       apikey: undefined,
+       endpoint: undefined,
+       
+       Math32:
+       {
+               clamp: a =>
+               {
+                       while (a < 0 || a > 0xFFFFFFFF)
+                               a += a < 0 ? 0x100000000 : -0x100000000;
+                       return a;
+               },
+               shl: (a, b) => RosadoAPI.Math32.clamp(a << b),
+               shr: (a, b) => RosadoAPI.Math32.clamp(a >>> b),
+               rtl: (a, b) => RosadoAPI.Math32.clamp((a << b) | (a >>> (32 - b))),
+               rtr: (a, b) => RosadoAPI.Math32.clamp((a >>> b) | (a << (32 - b))),
+               add: (a, b) => RosadoAPI.Math32.clamp(a + b),
+               sub: (a, b) => RosadoAPI.Math32.clamp(a + b),
+               or: (a, b) => RosadoAPI.Math32.clamp(a | b),
+               xor: (a, b) => RosadoAPI.Math32.clamp(a ^ b)
+       },
+       HMACSHA256:
+       {
+               sign: async (key, msg) =>
+               {
+                       key = new Uint8Array(key);
+                       msg = new Uint8Array(msg);
+                       var ikey = await crypto.subtle.importKey
+                       (
+                               "raw",
+                               key,
+                               { name: "HMAC", hash: { name: "SHA-256" }},
+                               false,
+                               ["sign", "verify"]
+                       );
+                       return new Uint8Array(await window.crypto.subtle.sign({ name: "HMAC", }, ikey, msg));
+               }
+       },
+       ChaCha20:
+       {
+               QR: (cc, a, b, c, d) =>
+               {
+                       cc[a] = RosadoAPI.Math32.add(cc[a], cc[b]);
+                       cc[d] = RosadoAPI.Math32.xor(cc[d], cc[a]);
+                       cc[d] = RosadoAPI.Math32.rtl(cc[d], 16);
+
+                       cc[c] = RosadoAPI.Math32.add(cc[c], cc[d]);
+                       cc[b] = RosadoAPI.Math32.xor(cc[b], cc[c]);
+                       cc[b] = RosadoAPI.Math32.rtl(cc[b], 12);
+
+                       cc[a] = RosadoAPI.Math32.add(cc[a], cc[b]);
+                       cc[d] = RosadoAPI.Math32.xor(cc[d], cc[a]);
+                       cc[d] = RosadoAPI.Math32.rtl(cc[d], 8);
+                       
+                       cc[c] = RosadoAPI.Math32.add(cc[c], cc[d]);
+                       cc[b] = RosadoAPI.Math32.xor(cc[b], cc[c]);
+                       cc[b] = RosadoAPI.Math32.rtl(cc[b], 7);
+               },
+               DR: (cc) =>
+               {       
+                       RosadoAPI.ChaCha20.QR(cc, 0, 4,  8, 12);
+                       RosadoAPI.ChaCha20.QR(cc, 1, 5,  9, 13);
+                       RosadoAPI.ChaCha20.QR(cc, 2, 6, 10, 14);
+                       RosadoAPI.ChaCha20.QR(cc, 3, 7, 11, 15);
+                       RosadoAPI.ChaCha20.QR(cc, 0, 5, 10, 15);
+                       RosadoAPI.ChaCha20.QR(cc, 1, 6, 11, 12);
+                       RosadoAPI.ChaCha20.QR(cc, 2, 7,  8, 13);
+                       RosadoAPI.ChaCha20.QR(cc, 3, 4,  9, 14);                                
+               },
+               CB: (cc) =>
+               {
+                       var i;
+                       var x = new Array(16);
+                       for (i = 0; i < 16; i++)
+                       {
+                               x[i] = cc[i];
+                       }
+                       for (i = 0; i < 10; i++)
+                       {
+                               RosadoAPI.ChaCha20.DR(cc);
+                       }
+                       for (i = 0; i < 16; i++)
+                       {
+                               cc[i] = RosadoAPI.Math32.add(cc[i], x[i]);
+                       }
+               },
+               S: (cc, cs) =>
+               {
+                       for (var i = 0; i < 16; i++)
+                       {
+                               cs[4 * i] = (cc[i] & 0xFF);
+                               cs[4 * i + 1] = ((cc[i] >> 8) & 0xFF);
+                               cs[4 * i + 2] = ((cc[i] >> 16) & 0xFF);
+                               cs[4 * i + 3] = ((cc[i] >> 24) & 0xFF);
+                       }
+               },
+               B: (key, nonce, block, out) =>
+               {
+                       var cc =
+                       [
+                               0x61707865, 0x3320646e, 0x79622d32, 0x6b206574,
+
+                               key[0] | (key[1] << 8) | (key[2] << 16) | (key[3] << 24),
+                               key[4] | (key[5] << 8) | (key[6] << 16) | (key[7] << 24),
+                               key[8] | (key[9] << 8) | (key[10] << 16) | (key[11] << 24),
+                               key[12] | (key[13] << 8) | (key[14] << 16) | (key[15] << 24),
+
+                               key[16] | (key[17] << 8) | (key[18] << 16) | (key[19] << 24),
+                               key[20] | (key[21] << 8) | (key[22] << 16) | (key[23] << 24),
+                               key[24] | (key[25] << 8) | (key[26] << 16) | (key[27] << 24),
+                               key[28] | (key[29] << 8) | (key[30] << 16) | (key[31] << 24),
+
+                               block,
+
+                               nonce[0] | (nonce[1] << 8) | (nonce[2] << 16) | (nonce[3] << 24),
+                               nonce[4] | (nonce[5] << 8) | (nonce[6] << 16) | (nonce[7] << 24),
+                               nonce[8] | (nonce[9] << 8) | (nonce[10] << 16) | (nonce[11] << 24)
+                       ];
+
+                       RosadoAPI.ChaCha20.CB(cc);
+                       RosadoAPI.ChaCha20.S(cc, out);
+               },
+               encrypt: async (key, nonce, block, data) =>
+               {
+                       var count = data.length;
+                       if (count > (274877906944 - block * 64)) return null;
+                       var ret = new Array(0);
+                       var ccblock = new Array(64);
+                       var size = 0;
+                       while (count > 64)
+                       {
+                               ret.length = size + 64;
+                               RosadoAPI.ChaCha20.B(key, nonce, block++, ccblock);
+                               for (var i = 0; i < 64; i++) ret[size + i] = ccblock[i];
+                               size += 64;
+                               count -= 64;
+                       }
+                       if (count > 0)
+                       {
+                               ret.length = size + count;
+                               RosadoAPI.ChaCha20.B(key, nonce, block, ccblock);
+                               for (var i = 0; i < count; i++) ret[size + i] = ccblock[i];
+                       }
+                       for (var i = 0; i < data.length; i++) ret[i] ^= data[i];
+                       return new Uint8Array(ret);
+               }
+       },
+       
+       Base64:
+       {
+               encode: async (x) =>
+               {
+                       return await new Promise(r =>
+                       {
+                               const reader = new FileReader();
+                               reader.addEventListener("load", () => r(reader.result.split(",")[1]));
+                               reader.readAsDataURL(new Blob([new Uint8Array(x)]));                            
+                       });
+               },
+               
+               decode: (b64) =>
+               {
+                       var dec1 = (v) =>
+                       {
+                               switch (v)
+                               {
+                                       case 'A': return  0;
+                                       case 'B': return  1;
+                                       case 'C': return  2;
+                                       case 'D': return  3;
+                                       case 'E': return  4;
+                                       case 'F': return  5;
+                                       case 'G': return  6;
+                                       case 'H': return  7;
+                                       case 'I': return  8;
+                                       case 'J': return  9;
+                                       case 'K': return 10;
+                                       case 'L': return 11;
+                                       case 'M': return 12;
+                                       case 'N': return 13;
+                                       case 'O': return 14;
+                                       case 'P': return 15;
+                                       case 'Q': return 16;
+                                       case 'R': return 17;
+                                       case 'S': return 18;
+                                       case 'T': return 19;
+                                       case 'U': return 20;
+                                       case 'V': return 21;
+                                       case 'W': return 22;
+                                       case 'X': return 23;
+                                       case 'Y': return 24;
+                                       case 'Z': return 25;
+                                       case 'a': return 26;
+                                       case 'b': return 27;
+                                       case 'c': return 28;
+                                       case 'd': return 29;
+                                       case 'e': return 30;
+                                       case 'f': return 31;
+                                       case 'g': return 32;
+                                       case 'h': return 33;
+                                       case 'i': return 34;
+                                       case 'j': return 35;
+                                       case 'k': return 36;
+                                       case 'l': return 37;
+                                       case 'm': return 38;
+                                       case 'n': return 39;
+                                       case 'o': return 40;
+                                       case 'p': return 41;
+                                       case 'q': return 42;
+                                       case 'r': return 43;
+                                       case 's': return 44;
+                                       case 't': return 45;
+                                       case 'u': return 46;
+                                       case 'v': return 47;
+                                       case 'w': return 48;
+                                       case 'x': return 49;
+                                       case 'y': return 50;
+                                       case 'z': return 51;
+                                       case '0': return 52;
+                                       case '1': return 53;
+                                       case '2': return 54;
+                                       case '3': return 55;
+                                       case '4': return 56;
+                                       case '5': return 57;
+                                       case '6': return 58;
+                                       case '7': return 59;
+                                       case '8': return 60;
+                                       case '9': return 61;
+                                       case '+': return 62;
+                                       case '/': return 63;
+                               }
+                               return 255;
+                       };
+                       
+                       var ret = new Array(0);
+                       var buffer = 0;
+                       var bufferS = 0;
+                       for (var i = 0; i < b64.length; i++)
+                       {
+                               if (b64[i] == '=') { bufferS = 0; continue; };
+                               var val = dec1(b64[i]);
+                               if (val == 255) return null;
+                               buffer = ((buffer << 6) | val) & 0xFFFF;
+                               bufferS += 6;
+                               if (bufferS >= 8)
+                               {
+                                       var shift = (16 - bufferS) & 0xFF;
+                                       buffer = (buffer << shift) & 0xFFFF;
+                                       ret[ret.length] = (buffer >>> 8) & 0xFF;
+                                       buffer = buffer & 0x00FF;
+                                       buffer = (buffer >>> shift) & 0xFFFF;
+                                       bufferS -= 8;
+                               }
+                       }
+                       if (bufferS > 0)
+                       {
+                               buffer = (buffer << (16 - bufferS)) & 0xFFFF;
+                               ret[ret.length] = (buffer >>> 8) & 0xFF;
+                       }
+                       return new Uint8Array(ret);
+               }
+       },
+       
+       Hex:
+       {
+               encode: (x) =>
+               {
+                       var ret = "";
+                       x.forEach(y => { ret += y.toString(16).padStart(2, "0"); });
+                       return ret;
+               },
+               decode: (x) =>
+               {
+                       var arr = new Array(0);
+                       for (var i = 0; i < x.length; i += 2)
+                       {
+                               arr[arr.length] = parseInt(x.charAt(i) + x.charAt(i + 1), 16);
+                       }
+                       return new Uint8Array(arr);
+               }
+       },
+       
+       generateRequest: async (msg) =>
+       {
+               msg = new TextEncoder().encode(msg);
+               var key = RosadoAPI.Hex.decode(RosadoAPI.apikey);
+               //var sess = crypto.getRandomValues(new Uint8Array(12));
+               var r = () => { return Math.floor(Math.random() * 10000) % 256 };;
+               var sess = new Uint8Array([r(), r(), r(), r(), r(), r(), r(), r(), r(), r(), r(), r()]);
+               var rawdata = await RosadoAPI.ChaCha20.encrypt(key, sess, 0, msg);
+               var dgst = await RosadoAPI.Hex.encode(await RosadoAPI.HMACSHA256.sign(key, rawdata));
+               var data = await RosadoAPI.Base64.encode(rawdata);
+               var resp = "user=" + RosadoAPI.username;
+               resp += "&sess=" + RosadoAPI.Hex.encode(sess);
+               resp += "&dgst=" + dgst;
+               resp += "&data=" + data;
+               return resp;
+       },
+       
+       parseResponse: async (msg) =>
+       {
+               if (!msg.includes("user=") || !msg.includes("&sess=") || !msg.includes("&dgst=") || !msg.includes("&data="))
+               {
+                       return { success: false, response: "invalid response" };
+               }
+               var user = msg.split("user=")[1].split("&")[0].trim();
+               var sess = msg.split("&sess=")[1].split("&")[0].trim();
+               var dgst = msg.split("&dgst=")[1].split("&")[0].trim();
+               var data = msg.split("&data=")[1].split("&")[0].trim();
+               
+               if (user != RosadoAPI.username)
+               {
+                       return { success: false, response: "invalid user in response" };
+               }
+               data = RosadoAPI.Base64.decode(data);
+               sess = RosadoAPI.Hex.decode(sess);
+               var key = RosadoAPI.Hex.decode(RosadoAPI.apikey);
+               var sig = await RosadoAPI.Hex.encode(await RosadoAPI.HMACSHA256.sign(key, data));
+               if (sig != dgst)
+               {
+                       return { success: false, response: "invalid signature" };
+               }
+               var resp = await RosadoAPI.ChaCha20.encrypt(key, sess, 0, data);
+               return { success: true, response: new TextDecoder().decode(resp) };
+       },
+       
+       request: async (msg) =>
+       {
+               if (msg.trim().length == 0) return { success: true, response: "" };
+               var req = await RosadoAPI.generateRequest(msg);
+               return await new Promise(r =>
+               {
+                       const xhr = new XMLHttpRequest();
+                       xhr.open("POST", RosadoAPI.endpoint, true);
+                       xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
+                       xhr.onreadystatechange = (x) =>
+                       {
+                               if (xhr.readyState === XMLHttpRequest.DONE)
+                               {
+                                       if (xhr.status === 200)
+                                       {
+                                               RosadoAPI.parseResponse(xhr.responseText).then(pr => { r(pr); }).catch(x => alert("ERR(3)"));
+                                       }
+                                       else
+                                       {
+                                               r({success: false, response: xhr.status});
+                                       }
+                               }
+                       }
+                       xhr.send(req);
+               }).catch(x => alert("ERR(1): " + x));
+       }
+};
+
index deace9b2409f3ae50abb4e5ad95905add07dd1f0..638bc79bac9ef83fceb5d37771f4351980d222ea 100644 (file)
@@ -3,7 +3,7 @@
        <title>QAnsel - Quantum Computer Simulator</title>
        <link href="imports/istina-editor.css" rel="stylesheet" />
        <link href="imports/micromodal.css" rel="stylesheet" />
-       <script src="imports/estouls-api.js"></script>
+       <script src="imports/rosado-api.js"></script>
        <script src="imports/istina-editor.js"></script>
        <script src="imports/chart.js"></script>
        <script src="imports/micromodal.js"></script>
                                errorModal("Please click the gear icon and input your API key.");
                                return;
                        }
-                       EstoulsAPI.username = key.split(":")[0];
-                       EstoulsAPI.apikey = key.split(":")[1];
-                       EstoulsAPI.endpoint = "https://" + key.split(":")[2];
-                       EstoulsAPI.request(IstinaEditor.getText()).then(x =>
+                       RosadoAPI.username = key.split(":")[0];
+                       RosadoAPI.apikey = key.split(":")[1];
+                       RosadoAPI.endpoint = "https://" + key.split(":")[2];
+                       RosadoAPI.request(IstinaEditor.getText()).then(x =>
                        {
                                $("#blocker-div")[0].remove();
                                $("#blocker-img")[0].remove();