Advertisement
Guest User

Untitled

a guest
Feb 26th, 2020
149
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.60 KB | None | 0 0
  1. /********* CryptoHill.java ********
  2. *
  3. * APCS Labs 2011-2020
  4. * Cryptology
  5. * Dr. John Pais
  6. * pais.john@gmail.com
  7. * Copyright (c) 2011 to present John Pais. All rights reserved.
  8. *
  9. * A Hill cryptosystem uses a matrix affine cipher: Ax + B.
  10. *
  11. */
  12.  
  13. package CryptoHill;
  14. import java.util.*;
  15. import CryptoAffine.Ntuple;
  16. import CryptoAffine.CryptoAffine;
  17.  
  18. public class CryptoHill
  19. {
  20. protected List<Character> alphabet;
  21. protected int alphaSize;
  22. private String dirPath;
  23. private List<Ntuple> lexicon = new ArrayList<Ntuple>();
  24. private List<String> plaintextWords = new ArrayList<String>();
  25. private List<Integer> units = new ArrayList<Integer>();
  26.  
  27. private CryptoAffine ca;
  28.  
  29. public CryptoHill(List<Character> alphabet, String dirPath, String lexicon)
  30. {
  31. this.alphabet = alphabet;
  32. this.alphaSize = alphabet.size();
  33. this.dirPath = dirPath;
  34. ca = new CryptoAffine(alphabet, dirPath, lexicon);
  35. plaintextWords = ca.getPlaintextWords();
  36. units = ca.groupOfUnits(alphaSize);
  37. }
  38.  
  39. // Problem 1.
  40. public CryptoAffine getCA()
  41. {
  42. return ca;
  43. }
  44.  
  45. // Problem 2. transpose matrix
  46. public long[][] transpose(long[][] a)
  47. {
  48. int m = a.length;
  49. int n = a[0].length;
  50. long[][] b = new long [n][m];
  51. for (int i = 0 ; i < m; i++)
  52. for (int j = 0; j < n; j++)
  53. b[j][i] = a[i][j];
  54. return b;
  55. }
  56.  
  57. // Problem 3. sum of two vectors
  58. public static long[] sum(long[] x, long[] y)
  59. {
  60. if (x.length != y.length) throw new RuntimeException("illegal vector dimensions");
  61. long[] z = new long[x.length];
  62. for (int i=0; i<x.length; i++)
  63. z[i] = x[i] + y[i];
  64. return z;
  65. }
  66.  
  67. // Problem 4. matrix multiplication: c = a * b
  68. public long[][] multiply(long[][] a, long[][] b)
  69. {
  70. int m1 = a.length;
  71. int n1 = a[0].length;
  72. int m2 = b.length;
  73. int n2 = b[0].length;
  74. if (n1 != m2) throw new RuntimeException("Illegal matrix dimensions.");
  75. long[] [] c = new long[m1][n2];
  76. for (int i = 0; i < m1; i++)
  77. for (int j = 0; j < n2; j++)
  78. for (int k = 0; k < n1; k++)
  79. c[i][j] += a[i][k] * b[k][j];
  80. return c;
  81. }
  82.  
  83. // Problem 5. matrix-vector multiplication: a * x
  84. public long[] multiply(long[][] a, long[] x)
  85. {
  86. int m = a.length;
  87. int n = a[0].length;
  88. if (x.length != n) throw new RuntimeException("Illegal matrix dimensions.");
  89. long[] y = new long[n];
  90. for (int j = 0; j < n; j++)
  91. for (int i = 0; i < m; i++)
  92. y[j] += a[i][j] * x[i];
  93. return y;
  94. }
  95.  
  96. // Problem 6. vector-matrix multiplication: x^T * a
  97. public long[] multiply(long[] x, long[][] a)
  98. {
  99. int m = a.length;
  100. int n = a[0].length;
  101. if (x.length != m) throw new RuntimeException("Illegal matrix dimensions.");
  102. long[] y = new long[m];
  103. for (int j = 0; j < n; j++)
  104. for (int i = 0; i < m; i++)
  105. y[i] += a[i][j] * x[i];
  106. return y;
  107. }
  108.  
  109. // Problem 7. method to create submatrix of mat (w.r.t. row p and col q)
  110. // written into temp
  111. public void submatrix(long[][] mat, long[][] temp, int p, int q)
  112. {
  113. int n = mat.length;
  114. int i = 0, j = 0;
  115. for (int row = 0; row < n; row++)
  116. {
  117. for (int col = 0; col < n; col++)
  118. {
  119. if (row != p && col != q)
  120. {
  121. temp[i][j++] = mat[row][col];
  122. if (j == n - 1)
  123. {
  124. j = 0;
  125. i++;
  126. }
  127. }
  128. }
  129. }
  130.  
  131. }
  132.  
  133. // Problem 8. recursive method for determinant of square matrix
  134. public long det(long[][] mat, int n)
  135. {
  136. int detVal = 0;
  137. if (n==1)
  138. {
  139. return mat[0][0];
  140. }
  141. else
  142. {
  143. //initialize temp to store submatrix
  144. long[][] temp = new long[n-1][n-1];
  145. int sign = 1;
  146. for (int k=0; k < n; k++)
  147. {
  148. submatrix(mat, temp, 0, k); //create submatrix in temp
  149. detVal += sign * mat[0][k] * det(temp, n - 1); //recursive call
  150. sign = -sign; // alternate signs
  151.  
  152. }
  153. }
  154. return detVal;
  155. }
  156.  
  157. // Problem 9. matrix adjugate of a square matrix
  158. public long[][] adjugate(long[][] a)
  159. {
  160. int n = a.length;
  161. long[][] temp = new long[n-1][n-1];
  162. long [][] adj = new long[n][n];
  163. for (int i = 0; i < n; i++)
  164. {
  165. for (int j = 0; j < n; j++)
  166. {
  167. submatrix(a,temp,i,j);
  168. adj[i][j] = ((int)Math.pow(-1, i+j))*det(temp, n-1);
  169. temp = new long[n-1][n-1];
  170. }
  171. }
  172. adj = transpose(adj);
  173. return adj;
  174. }
  175.  
  176. // Problem 10. scalar times matrix
  177. public long[][] scalarMult(long r, long[][] a)
  178. {
  179. int n = a.length;
  180. int m = a[0].length;
  181. long[][] b = new long[n][n];
  182. for (int i = 0; i < n; i++)
  183. {
  184. for (int j = 0; j < m; j++)
  185. {
  186. b[i][j] = r * a[i][j];
  187. }
  188. }
  189. return b;
  190. }
  191. // Problem 11. display matrix
  192. public void display(long[][] mat, int row, int col)
  193. {
  194. for(int i=0; i < row; i++)
  195. {
  196. for (int j = 0; j < col; j++)
  197. {
  198. System.out.print(mat[i][j] + " ");
  199. }
  200. System.out.print("\n");
  201. }
  202. }
  203.  
  204. // Vector & Matrix Methods mod k (alphaSize)
  205. // Needed for Hill Encryption/Decryption
  206.  
  207. // Problem 12. scalar times matrix mod k
  208. public long[][] scalarMultMod(long r, long[][] a, long k)
  209. {
  210. int n = a.length;
  211. int m = a[0].length;
  212. long[][] b = new long[n][n];
  213. for (int i=0; i < n; i++)
  214. {
  215. for (int j=0; j < m; j++)
  216. {
  217. b[i][j] = (r*a[i][j]) % k;
  218. if (b[i][j] < 0)
  219. {
  220. b[i][j] += k;
  221. }
  222. }
  223. }
  224. return b;
  225. }
  226.  
  227. // Problem 13. scalar times vector mod k
  228. public long[] scalarMultMod(long r, long[] v, long k)
  229. {
  230. int temp = v.length;
  231. for (int i = 0; i < temp; i++ )
  232. {
  233. v[i] = (r * v[i]) % k;
  234. if (v[i] < 0)
  235. {
  236. v[i] += k;
  237. }
  238. }
  239. return v;
  240. }
  241.  
  242. // Problem 14. matrix mod k
  243. public long[][] matrixMod(long[][] a, long k)
  244. {
  245. int n = a.length;
  246. int m = a[0].length;
  247. long [][] b = new long [n][m];
  248. for (int i = 0; i < n; i++)
  249. {
  250. for (int j = 0; j < n; j++)
  251. {
  252. b[n][m] = a[n][m] % k;
  253. if (b[n][m] < 0)
  254. {
  255. b[n][m] += k;
  256. }
  257. }
  258. }
  259. return b;
  260. }
  261.  
  262. // Problem 15. vector mod k
  263. public long[] vectorMod(long[] v, long k)
  264. {
  265. int tmp = v.length;
  266. for (int i = 0; i < tmp; i++)
  267. {
  268. v[i] %= k;
  269. if (v[i] < 0)
  270. {
  271. v[i] += k;
  272. }
  273. }
  274. return v;
  275. }
  276.  
  277. // Problem 16. matrix inverse mod k when it exists
  278. // note that we use two methods from our CryptoAffine object
  279. public long[][] matMultInvMod(long[][] a, long k)
  280. {
  281. long det = (det(a,a.length) % k + k) % k;
  282. if (det == 0 || ca.gcd((int)det,(int)k) != 1) throw new RuntimeException("matrix is not invertible.");
  283. return scalarMultMod(ca.inverse((int)det), adjugate(a),k);
  284. }
  285.  
  286. // Problem 17. vector additive inverse mod k
  287. public long[] vecAddInvMod(long[] v, long k)
  288. {
  289. int tmp = v.length;
  290. long[] b = new long[tmp];
  291. for (int i = 0; i < tmp; i++)
  292. {
  293. b[i] = k-v[i];
  294. }
  295. return b;
  296. }
  297.  
  298. // Problem 18. matrix multiplication mod k: c = a * b
  299. public long[][] multiplyMod(long[][] a, long[][] b, long k)
  300. {
  301. int m1 = a.length;
  302. int n1 = a[0].length;
  303. int m2 = b.length;
  304. int n2 = b[0].length;
  305. if (n1 != m2) throw new RuntimeException("Illegal matrix dimensions.");
  306. long[] [] c = new long[m1][n2];
  307. for (int i = 0; i < m1; i++)
  308. {
  309. for (int j = 0; j < n2; j++)
  310. {
  311. for (int x = 0; x < n1; x++)
  312. {
  313. c[i][j] += (a[i][x] * b[x][j]) % k;
  314. if (c[i][j] < 0)
  315. {
  316. c[i][j] += k;
  317. }
  318. }
  319. }
  320. }
  321. return c;
  322. }
  323.  
  324. // Problem 19. matrix-vector multiplication mod k: a * x
  325. public long[] multiplyMod(long[][] a, long[] x, long k)
  326. {
  327. int m = a.length;
  328. int n = a[0].length;
  329. if (x.length != n) throw new RuntimeException("Illegal matrix dimensions.");
  330. long[] y = new long[n];
  331. for (int j = 0; j < n; j++)
  332. {
  333. for (int i = 0; i < m; i++)
  334. {
  335. y[j] += (a[i][j] * x[i]) % k;
  336. if (y[j] < 0)
  337. {
  338. y[j] += k;
  339. }
  340. }
  341. }
  342. return y;
  343. }
  344.  
  345. // Problem 20. generate random n by n matrix invertible mod k
  346. public long[][] genRndMatrixMod(int n, int k)
  347. {
  348. long[][] a = new long[n][n];
  349. Random rnd = new Random();
  350. long det = 0;
  351. while (det == 0 || ca.gcd((int)det,(int)k) != 1)
  352. {
  353. for (int i = 0; i < n; i++)
  354. {
  355. for (int j = 0; j < n; j++)
  356. {
  357. a[i][j] = rnd.nextInt(k);
  358. }
  359. }
  360. det = det(a,a.length) % k;
  361. if (det < 0)
  362. {
  363. det += k;
  364. }
  365. }
  366. return a;
  367. }
  368.  
  369. // Problem 21. generate random n vector mod k
  370. public long[] genRndVectorMod(int n, int k)
  371. {
  372. long[] a = new long[n];
  373. Random rnd = new Random();
  374. for (int j = 0; j < n; j++)
  375. {
  376. a[j] = rnd.nextInt(k);
  377. }
  378. return a;
  379. }
  380.  
  381. // Problem 22. precondition: matKey[n][n], vecKey[n], blocksize = n
  382. // = str.length(), all characters in str are in the alphabet
  383. public String hillEncryptBlock(long[][] matKey, long[] vecKey, String block)
  384. {
  385. int n = block.length();
  386. long k = alphaSize;
  387. char[] plainChars = block.toCharArray();
  388. long[] plainIndexes = new long[n];
  389. long[] cipherIndexes = new long[n];
  390. char[] cipherChars = new char[n];
  391.  
  392. // create plainIndexes vector of plainChars
  393. for(int i = 0; i < n; i++)
  394. {
  395. plainIndexes[i] = alphabet.indexOf(plainChars[i]);
  396. }
  397.  
  398. // encrypt plainIndexes vector
  399. cipherIndexes = vectorMod(sum(multiply(matKey,plainIndexes), vecKey),k);
  400.  
  401. // create cipherChars array of characters
  402. for(int i = 0; i < n; i++)
  403. {
  404. cipherChars[i] = alphabet.get((int)cipherIndexes[i]);
  405. }
  406.  
  407. // return ciphertext string block
  408. return String.valueOf(cipherChars);
  409.  
  410. // insert your code here
  411. }
  412.  
  413. // Problem 23. precondition: matKey[n][n], vecKey[n], blocksize = n
  414. // = str.length(), all characters in str are in the alphabet
  415. public String hillDecryptBlock(long[][] matKey, long[] vecKey, String block)
  416. {
  417. int n = block.length();
  418. long k = alphaSize;
  419. char[] cipherChars = block.toCharArray();
  420. long[] cipherIndexes = new long[n];
  421. long[] plainIndexes = new long[n];
  422. char[] plainChars = new char[n];
  423.  
  424. // create cipherIndexes vector of cipherChars
  425. for(int i = 0; i < n; i++)
  426. {
  427. cipherIndexes[i] = alphabet.indexOf(cipherChars[i]);
  428. }
  429.  
  430. // decrypt cipherIndexes vector
  431.  
  432. plainIndexes = vectorMod(multiply(matMultInvMod(matKey,k), sum(cipherIndexes, vecAddInvMod(vecKey,k))),k);
  433.  
  434. // create plainChars array of characters
  435. for(int i = 0; i < n; i++)
  436. {
  437. plainChars[i] = alphabet.get((int)plainIndexes[i]);
  438. }
  439.  
  440. // return plaintext string block
  441.  
  442. return String.valueOf(plainChars);
  443. }
  444. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement