|
| 1 | +//Security |
| 2 | +let public_key_server=null |
| 3 | +fetch('/public-key').then(res=>res.json()).then(publicKey => { |
| 4 | + // Set the fetched public key to the encryptor object |
| 5 | + public_key_server=publicKey; |
| 6 | + console.log(publicKey) |
| 7 | + }) |
| 8 | + |
| 9 | + class Knapsack { |
| 10 | + constructor() {} |
| 11 | + |
| 12 | + gcd(a, b) { |
| 13 | + while (b) { |
| 14 | + [a, b] = [b, a % b]; |
| 15 | + } |
| 16 | + return a; |
| 17 | + } |
| 18 | + |
| 19 | + extendedGcd(a, b) { |
| 20 | + if (a == 0) { |
| 21 | + return [b, 0, 1]; |
| 22 | + } else { |
| 23 | + const [g, y, x] = this.extendedGcd(b % a, a); |
| 24 | + return [g, x - Math.floor(b / a) * y, y]; |
| 25 | + } |
| 26 | + } |
| 27 | + |
| 28 | + modInverse(a, m) { |
| 29 | + const [g, x] = this.extendedGcd(a, m).slice(0, 2); |
| 30 | + if (g !== 1) { |
| 31 | + return null; |
| 32 | + } else { |
| 33 | + return (x % m + m) % m; |
| 34 | + } |
| 35 | + } |
| 36 | + |
| 37 | + generateSuperIncreasingSequence(length) { |
| 38 | + let sequence = [Math.floor(Math.random() * 99) + 2]; |
| 39 | + for (let i = 1; i < length; i++) { |
| 40 | + let nextElement = Math.floor(Math.random() * (2 * sequence.reduce((acc, val) => acc + val)) + sequence.reduce((acc, val) => acc + val)) + 1; |
| 41 | + sequence.push(nextElement); |
| 42 | + } |
| 43 | + return sequence; |
| 44 | + } |
| 45 | + |
| 46 | + privateKeyPublicKey(arrayLen, digitsNo) { |
| 47 | + let array = this.generateSuperIncreasingSequence(arrayLen); |
| 48 | + let minM = array.reduce((acc, val) => acc + val) + 1; |
| 49 | + let m = Math.floor(Math.random() * (10 ** digitsNo - array.reduce((acc, val) => Math.max(acc, val)))) + Math.max(array.reduce((acc, val) => Math.max(acc, val)), 10 ** (digitsNo - 1)); |
| 50 | + let n; |
| 51 | + do { |
| 52 | + n = Math.floor(Math.random() * (m - 2)) + 2; |
| 53 | + } while (this.gcd(m, n) !== 1); |
| 54 | + let privateKey = n; |
| 55 | + let publicKey = array.map(element => (element * n) % m); |
| 56 | + this.privateKey = privateKey; |
| 57 | + this.modValue = m; |
| 58 | + this.array = array; |
| 59 | + this.publicKey = publicKey; |
| 60 | + return [privateKey, m, publicKey]; |
| 61 | + } |
| 62 | + |
| 63 | + stringToBin(string) { |
| 64 | + let stringBin = ''; |
| 65 | + for (let ch of string) { |
| 66 | + let ascii = ch.charCodeAt(0); |
| 67 | + let chBin = ascii.toString(2).padStart(8, '0'); |
| 68 | + stringBin += chBin; |
| 69 | + } |
| 70 | + return stringBin; |
| 71 | + } |
| 72 | + |
| 73 | + breakIntoSumOf(target, arr) { |
| 74 | + function backtrack(start, path, target) { |
| 75 | + if (target === 0) { |
| 76 | + result.push([...path]); |
| 77 | + return; |
| 78 | + } |
| 79 | + if (target < 0 || start >= arr.length) { |
| 80 | + return; |
| 81 | + } |
| 82 | + for (let i = start; i < arr.length; i++) { |
| 83 | + if (i > start && arr[i] === arr[i - 1]) { |
| 84 | + continue; |
| 85 | + } |
| 86 | + path.push(arr[i]); |
| 87 | + backtrack(i + 1, path, target - arr[i]); |
| 88 | + path.pop(); |
| 89 | + } |
| 90 | + } |
| 91 | + |
| 92 | + let result = []; |
| 93 | + arr.sort((a, b) => a - b); |
| 94 | + backtrack(0, [], target); |
| 95 | + return result[0]; |
| 96 | + } |
| 97 | + |
| 98 | + encryption(strBin, publicKey) { |
| 99 | + strBin = this.stringToBin(strBin); |
| 100 | + if (strBin.length % this.array.length !== 0) { |
| 101 | + console.log("GCD(string length,array length) must be 0 so that\n1.No element left in encryption\n2.No elements overproduced in decryption\n"); |
| 102 | + return "Encryption Error"; |
| 103 | + } |
| 104 | + let pubLen = publicKey.length; |
| 105 | + let i = 0, |
| 106 | + portionVal = 0, |
| 107 | + cy = ''; |
| 108 | + for (let valBin of strBin) { |
| 109 | + valBin = parseInt(valBin); |
| 110 | + if (valBin) { |
| 111 | + portionVal += valBin * publicKey[i]; |
| 112 | + } |
| 113 | + i = (i + 1) % pubLen; |
| 114 | + if (i === 0) { |
| 115 | + cy += portionVal + ' '; |
| 116 | + portionVal = 0; |
| 117 | + } |
| 118 | + } |
| 119 | + if (i) { |
| 120 | + cy += portionVal + ' '; |
| 121 | + } |
| 122 | + return cy.trim(); |
| 123 | + } |
| 124 | + |
| 125 | + decryption(cypherText) { |
| 126 | + let [privateKey, modVal, array] = [this.privateKey, this.modValue, this.array]; |
| 127 | + let decryptionKey = this.modInverse(privateKey, modVal); |
| 128 | + let cypher = cypherText.split(' '); |
| 129 | + |
| 130 | + let text = ''; |
| 131 | + for (let cy of cypher) { |
| 132 | + if(cy.length==0) continue |
| 133 | + |
| 134 | + let val = (parseInt(cy) * decryptionKey) % modVal; |
| 135 | + |
| 136 | + let comb = this.breakIntoSumOf(val, array); |
| 137 | + if (comb.length === 0 && val) { |
| 138 | + console.log("ERR: decryption -> no combination found"); |
| 139 | + } |
| 140 | + let decode = ''; |
| 141 | + for (let element of array) { |
| 142 | + if (comb.includes(element)) { |
| 143 | + decode += '1'; |
| 144 | + } else { |
| 145 | + decode += '0'; |
| 146 | + } |
| 147 | + } |
| 148 | + text += decode; |
| 149 | + } |
| 150 | + return this.binToText(text); |
| 151 | + } |
| 152 | + |
| 153 | + binToText(bin) { |
| 154 | + if (bin.length % 8 !== 0) { |
| 155 | + console.log("Not convertible"); |
| 156 | + return; |
| 157 | + } |
| 158 | + let string = ''; |
| 159 | + for (let start = 0; start < bin.length; start += 8) { |
| 160 | + string += String.fromCharCode(parseInt(bin.substr(start, 8), 2)); |
| 161 | + } |
| 162 | + return string; |
| 163 | + } |
| 164 | + } |
| 165 | + |
| 166 | + // Usage |
| 167 | + let ks = new Knapsack(); |
| 168 | + let [privateKey, modValue, publicKey] = ks.privateKeyPublicKey(8,8); |
| 169 | + // console.log("Private Key:", privateKey); |
| 170 | + // console.log("Mod Value:", modValue); |
| 171 | + // console.log("Public Key:", publicKey); |
| 172 | + |
| 173 | + // let plaintext = "Hello, world!"; |
| 174 | + // let cypherText = ks.encryption(plaintext, publicKey); |
| 175 | + // console.log("Encrypted:", cypherText); |
| 176 | + |
| 177 | + // let decryptedText = ks.decryption(cypherText); |
| 178 | + // console.log("typeOfct:", typeof(cypherText)); |
| 179 | + // x='1' |
| 180 | + // while (x !='0') { |
| 181 | + // x=prompt("Plain text :") |
| 182 | + // cy=ks.encryption(x, publicKey); |
| 183 | + // alert(cy) |
| 184 | + // text=ks.decryption(cy); |
| 185 | + // alert(text) |
| 186 | + // } |
| 187 | + |
| 188 | + |
| 189 | + |
| 190 | + |
| 191 | + |
| 192 | + |
| 193 | + |
1 | 194 | async function postData(url, searchTopic) {
|
2 | 195 | skeletonLoader();
|
| 196 | + const searchTopicEnc = ks.encryption((JSON.stringify(searchTopic)), public_key_server); |
| 197 | + console.log("Encrypted search",searchTopicEnc) |
| 198 | + // Create the request body with encrypted searchTopic and public key |
| 199 | + const body = JSON.stringify({ |
| 200 | + searchTopic: searchTopicEnc, |
| 201 | + publicKey: publicKey |
| 202 | + }); |
| 203 | + |
| 204 | + console.log(body) |
3 | 205 | const response = await fetch(url, {
|
4 | 206 | method: "POST",
|
5 | 207 | headers: {
|
6 | 208 | "Content-Type": "application/json"
|
7 | 209 | },
|
8 |
| - body: JSON.stringify(searchTopic) |
| 210 | + body: body |
9 | 211 | });
|
10 | 212 |
|
11 |
| - return await response.json(); |
| 213 | + return await response.text(); |
12 | 214 | }
|
| 215 | +function decryptData(encryptedData) { |
| 216 | + |
| 217 | + |
| 218 | + |
| 219 | + |
| 220 | + const decryptedData = decryptor.decrypt(encryptedData); |
| 221 | + console.log("Decrypted data:", decryptedData); |
| 222 | + return decryptedData |
| 223 | +} |
| 224 | +function encryptData(sensitiveData) { |
| 225 | + |
| 226 | + |
| 227 | + |
| 228 | + const encryptedData = encryptor.encrypt(sensitiveData); |
| 229 | + console.log("Encrypted data:", encryptedData); |
| 230 | + return encryptedData |
13 | 231 |
|
| 232 | + // Now send the encryptedData to the server using AJAX, fetch, etc. |
| 233 | +} |
14 | 234 | function skeletonLoader() {
|
15 | 235 | const mainDivSelector = document.getElementById("mainDiv");
|
16 | 236 | mainDivSelector.innerHTML = "";
|
@@ -46,7 +266,13 @@ document.getElementById("searchBtn").onclick = function() {
|
46 | 266 |
|
47 | 267 | postData("/submit",{ searchTopic:searchTopic})
|
48 | 268 | .then(searchResult => {
|
49 |
| - populateMainDiv(searchResult) |
| 269 | + console.log("search result before Decryption",searchResult) |
| 270 | + |
| 271 | + decryptedSearchResult= ks.decryption(searchResult) |
| 272 | + |
| 273 | + decryptedSearchResult=JSON.parse(decryptedSearchResult) |
| 274 | + |
| 275 | + populateMainDiv(decryptedSearchResult) |
50 | 276 | })
|
51 | 277 | .catch(error => {
|
52 | 278 | console.error("Error: ", error);
|
|
0 commit comments