Skip to content

Commit ded3de8

Browse files
committed
Encryption/decryption using Knapsack cryptosystem added
1 parent 48bf07e commit ded3de8

File tree

5 files changed

+413
-35
lines changed

5 files changed

+413
-35
lines changed
Binary file not shown.

serverClient/client.js

Lines changed: 229 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,236 @@
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+
1194
async function postData(url, searchTopic) {
2195
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)
3205
const response = await fetch(url, {
4206
method: "POST",
5207
headers: {
6208
"Content-Type": "application/json"
7209
},
8-
body: JSON.stringify(searchTopic)
210+
body: body
9211
});
10212

11-
return await response.json();
213+
return await response.text();
12214
}
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
13231

232+
// Now send the encryptedData to the server using AJAX, fetch, etc.
233+
}
14234
function skeletonLoader() {
15235
const mainDivSelector = document.getElementById("mainDiv");
16236
mainDivSelector.innerHTML = "";
@@ -46,7 +266,13 @@ document.getElementById("searchBtn").onclick = function() {
46266

47267
postData("/submit",{ searchTopic:searchTopic})
48268
.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)
50276
})
51277
.catch(error => {
52278
console.error("Error: ", error);

serverClient/index.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
<div id="mainDiv">
1616

1717
</div>
18+
<script src="https://cdnjs.cloudflare.com/ajax/libs/jsencrypt/3.0.0/jsencrypt.min.js"></script>
19+
1820
<script src="client.js"></script>
1921
</body>
2022

0 commit comments

Comments
 (0)