proofs.service.or.spec.js 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635
  1. /*
  2. * Copyright 2018 Scytl Secure Electronic Voting SA
  3. *
  4. * All rights reserved
  5. *
  6. * See our extended copyright notice in *file 'Copyright.txt' which is part of this source code package
  7. */
  8. describe('Proofs service ...', function() {
  9. 'use strict';
  10. // Initialize variables common to all proof tests.
  11. beforeEach(initializeTestVars);
  12. // OR-proof tests.
  13. describe('should be able to ..', function() {
  14. var public_key_length = 1;
  15. var num_elements = 5;
  16. var max_data_length = 30;
  17. var num_progress_checks = num_elements * 2;
  18. var initialized = false;
  19. var publicKey;
  20. var elements;
  21. var index;
  22. var ciphertext;
  23. var witness;
  24. var data;
  25. var proof;
  26. var preComputedValues;
  27. var anotherElements;
  28. var anotherPublicKey;
  29. var anotherCiphertext;
  30. var anotherWitness;
  31. var aLongerPublicKey;
  32. var aLongerCiphertext;
  33. var aShorterElements;
  34. var aLongerElements;
  35. // Initialize variables common to OR-proof tests.
  36. beforeEach(function() {
  37. if (!initialized) {
  38. cryptolib('proofs.service', function(box) {
  39. publicKey = generateElGamalKeyPair(public_key_length).getPublicKey();
  40. elements = generatePlaintext(num_elements);
  41. index = generateRandomInteger(0, (num_elements - 1));
  42. ciphertext = generateCiphertext(publicKey, [elements[index]]);
  43. witness = ciphertext.getR();
  44. var dataLength = generateRandomInteger(1, max_data_length);
  45. data = generateRandomString(dataLength);
  46. proof = box.proofs.service.createORProof(
  47. publicKey, ciphertext, witness, elements, index, data,
  48. _zpSubgroup);
  49. preComputedValues = box.proofs.service.preComputeORProof(
  50. publicKey, num_elements, _zpSubgroup);
  51. do {
  52. anotherElements = generatePlaintext(num_elements);
  53. } while (anotherElements.equals(elements) ||
  54. anotherElements[index].equals(elements[index]));
  55. do {
  56. anotherPublicKey =
  57. generateElGamalKeyPair(public_key_length).getPublicKey();
  58. } while (anotherPublicKey.getGroupElementsArray().equals(
  59. publicKey.getGroupElementsArray()));
  60. anotherCiphertext =
  61. generateCiphertext(anotherPublicKey, [elements[index]]);
  62. anotherWitness = anotherCiphertext.getR();
  63. do {
  64. aLongerPublicKey =
  65. generateElGamalKeyPair(public_key_length + 1).getPublicKey();
  66. } while (aLongerPublicKey.getGroupElementsArray().equals(
  67. publicKey.getGroupElementsArray()));
  68. aLongerCiphertext =
  69. generateCiphertext(aLongerPublicKey, [elements[0], elements[1]]);
  70. aShorterElements = generatePlaintext(1);
  71. aLongerElements = [];
  72. aLongerElements.addAll(elements);
  73. aLongerElements.push(elements[0]);
  74. });
  75. initialized = true;
  76. }
  77. });
  78. it('generate and verify an OR-proof', function() {
  79. cryptolib('proofs.service', function(box) {
  80. var verification = box.proofs.service.verifyORProof(
  81. publicKey, ciphertext, elements, data, proof, _zpSubgroup);
  82. expect(verification).toBeTruthy();
  83. });
  84. });
  85. it('and generate and verify an OR-proof, using pre-computed values',
  86. function() {
  87. cryptolib('proofs.service', function(box) {
  88. var anotherProof = box.proofs.service.createORProof(
  89. publicKey, ciphertext, witness, elements, index, data,
  90. _zpSubgroup, preComputedValues);
  91. var verification = box.proofs.service.verifyORProof(
  92. publicKey, ciphertext, elements, data, anotherProof,
  93. _zpSubgroup);
  94. expect(verification).toBeTruthy();
  95. });
  96. });
  97. it('and generate and verify an OR-proof, using an empty string for the data option',
  98. function() {
  99. cryptolib('proofs.service', function(box) {
  100. var anotherProof = box.proofs.service.createORProof(
  101. publicKey, ciphertext, witness, elements, index, '',
  102. _zpSubgroup);
  103. var verification = box.proofs.service.verifyORProof(
  104. publicKey, ciphertext, elements, '', anotherProof, _zpSubgroup);
  105. expect(verification).toBeTruthy();
  106. });
  107. });
  108. it('and generate and verify an OR-proof, using null for the data option',
  109. function() {
  110. cryptolib('proofs.service', function(box) {
  111. var anotherProof = box.proofs.service.createORProof(
  112. publicKey, ciphertext, witness, elements, index, null,
  113. _zpSubgroup);
  114. var verification = box.proofs.service.verifyORProof(
  115. publicKey, ciphertext, elements, null, anotherProof,
  116. _zpSubgroup);
  117. expect(verification).toBeTruthy();
  118. });
  119. });
  120. it('and generate and verify an OR-proof, using null for the pre-computed values option',
  121. function() {
  122. cryptolib('proofs.service', function(box) {
  123. var anotherProof = box.proofs.service.createORProof(
  124. publicKey, ciphertext, witness, elements, index, data,
  125. _zpSubgroup, null);
  126. var verification = box.proofs.service.verifyORProof(
  127. publicKey, ciphertext, elements, data, anotherProof,
  128. _zpSubgroup);
  129. expect(verification).toBeTruthy();
  130. });
  131. });
  132. it('generate and verify an OR-proof, using serialization', function() {
  133. cryptolib('commons.mathematical', 'proofs', function(box) {
  134. var proofAsJson = proof.stringify();
  135. var proofFromJson = box.proofs.utils.deserializeProof(proofAsJson);
  136. var verification = box.proofs.service.verifyORProof(
  137. publicKey, ciphertext, elements, data, proofFromJson, _zpSubgroup);
  138. expect(verification).toBeTruthy();
  139. });
  140. });
  141. it('generate and verify an OR-proof, using pre-computed values and serialization',
  142. function() {
  143. cryptolib('commons.mathematical', 'proofs', function(box) {
  144. var preComputedValuesAsJson = preComputedValues.stringify();
  145. var preComputedValuesFromJson =
  146. box.proofs.utils.deserializeProofPreComputedValues(
  147. preComputedValuesAsJson);
  148. var anotherProof = box.proofs.service.createORProof(
  149. publicKey, ciphertext, witness, elements, index, data,
  150. _zpSubgroup, preComputedValuesFromJson);
  151. var verification = box.proofs.service.verifyORProof(
  152. publicKey, ciphertext, elements, data, anotherProof,
  153. _zpSubgroup);
  154. expect(verification).toBeTruthy();
  155. });
  156. });
  157. it('and measure progress when generating an OR-proof', function() {
  158. cryptolib('proofs.service', function(box) {
  159. initializeProgressMeter();
  160. var anotherProof = box.proofs.service.createORProof(
  161. publicKey, ciphertext, witness, elements, index, data, _zpSubgroup,
  162. progressCallback, PROGRESS_PERCENT_MIN_CHECK_INTERVAL);
  163. expect(_progressPercentSum)
  164. .toBe(getProgressPercentSum(
  165. num_progress_checks, PROGRESS_PERCENT_MIN_CHECK_INTERVAL));
  166. expect(_progressPercentLatest).toBe(100);
  167. var verification = box.proofs.service.verifyORProof(
  168. publicKey, ciphertext, elements, data, anotherProof, _zpSubgroup);
  169. expect(verification).toBeTruthy();
  170. });
  171. });
  172. it('and measure progress when pre-computing an OR-proof', function() {
  173. cryptolib('proofs.service', function(box) {
  174. initializeProgressMeter();
  175. preComputedValues = box.proofs.service.preComputeORProof(
  176. publicKey, num_elements, _zpSubgroup, progressCallback,
  177. PROGRESS_PERCENT_MIN_CHECK_INTERVAL);
  178. expect(_progressPercentSum)
  179. .toBe(getProgressPercentSum(
  180. num_progress_checks, PROGRESS_PERCENT_MIN_CHECK_INTERVAL));
  181. expect(_progressPercentLatest).toBe(100);
  182. var anotherProof = box.proofs.service.createORProof(
  183. publicKey, ciphertext, witness, elements, index, data, _zpSubgroup,
  184. preComputedValues);
  185. var verification = box.proofs.service.verifyORProof(
  186. publicKey, ciphertext, elements, data, anotherProof, _zpSubgroup);
  187. expect(verification).toBeTruthy();
  188. });
  189. });
  190. it('and measure progress when verifying an OR-proof', function() {
  191. cryptolib('proofs.service', function(box) {
  192. initializeProgressMeter();
  193. var verification = box.proofs.service.verifyORProof(
  194. publicKey, ciphertext, elements, data, proof, _zpSubgroup,
  195. progressCallback, PROGRESS_PERCENT_MIN_CHECK_INTERVAL);
  196. expect(verification).toBeTruthy();
  197. expect(_progressPercentSum)
  198. .toBe(getProgressPercentSum(
  199. num_progress_checks, PROGRESS_PERCENT_MIN_CHECK_INTERVAL));
  200. expect(_progressPercentLatest).toBe(100);
  201. });
  202. });
  203. it('and fail to verify an OR-proof that was generated with the wrong public key',
  204. function() {
  205. cryptolib('proofs.service', function(box) {
  206. var anotherProof = box.proofs.service.createORProof(
  207. anotherPublicKey, ciphertext, witness, elements, index, data,
  208. _zpSubgroup);
  209. var verification = box.proofs.service.verifyORProof(
  210. anotherPublicKey, ciphertext, elements, data, anotherProof,
  211. _zpSubgroup);
  212. expect(verification).toBeFalsy();
  213. });
  214. });
  215. it('and fail to verify an OR-proof that was generated with the wrong ciphertext',
  216. function() {
  217. cryptolib('proofs.service', function(box) {
  218. var anotherProof = box.proofs.service.createORProof(
  219. publicKey, anotherCiphertext, witness, elements, index, data,
  220. _zpSubgroup);
  221. var verification = box.proofs.service.verifyORProof(
  222. publicKey, anotherCiphertext, elements, data, anotherProof,
  223. _zpSubgroup);
  224. expect(verification).toBeFalsy();
  225. });
  226. });
  227. it('and fail to verify an OR-proof that was generated with the wrong witness',
  228. function() {
  229. cryptolib('proofs.service', function(box) {
  230. var anotherProof = box.proofs.service.createORProof(
  231. publicKey, ciphertext, anotherWitness, elements, index, data,
  232. _zpSubgroup);
  233. var verification = box.proofs.service.verifyORProof(
  234. publicKey, ciphertext, elements, data, anotherProof,
  235. _zpSubgroup);
  236. expect(verification).toBeFalsy();
  237. });
  238. });
  239. it('and fail to verify an OR-proof that was generated with the wrong elements',
  240. function() {
  241. cryptolib('proofs.service', function(box) {
  242. var anotherProof = box.proofs.service.createORProof(
  243. publicKey, ciphertext, witness, anotherElements, index, data,
  244. _zpSubgroup);
  245. var verification = box.proofs.service.verifyORProof(
  246. publicKey, ciphertext, anotherElements, data, anotherProof,
  247. _zpSubgroup);
  248. expect(verification).toBeFalsy();
  249. });
  250. });
  251. it('and fail to verify an OR-proof that was pre-computed with the wrong public key',
  252. function() {
  253. cryptolib('proofs.service', function(box) {
  254. var anotherPreComputedValues = box.proofs.service.preComputeORProof(
  255. anotherPublicKey, num_elements, _zpSubgroup);
  256. var anotherProof = box.proofs.service.createORProof(
  257. publicKey, ciphertext, witness, elements, index, data,
  258. _zpSubgroup, anotherPreComputedValues);
  259. var verification = box.proofs.service.verifyORProof(
  260. publicKey, ciphertext, elements, data, anotherProof,
  261. _zpSubgroup);
  262. expect(verification).toBeFalsy();
  263. });
  264. });
  265. it('and fail to verify an OR-proof that was pre-computed and generated with the wrong public key',
  266. function() {
  267. cryptolib('proofs.service', function(box) {
  268. var anotherPreComputedValues = box.proofs.service.preComputeORProof(
  269. anotherPublicKey, num_elements, _zpSubgroup);
  270. var anotherProof = box.proofs.service.createORProof(
  271. anotherPublicKey, ciphertext, witness, elements, index, data,
  272. _zpSubgroup, anotherPreComputedValues);
  273. var verification = box.proofs.service.verifyORProof(
  274. anotherPublicKey, ciphertext, elements, data, anotherProof,
  275. _zpSubgroup);
  276. expect(verification).toBeFalsy();
  277. });
  278. });
  279. it('and throw an exception when generating an OR-proof, using null input data',
  280. function() {
  281. cryptolib('proofs.service', function(box) {
  282. expect(function() {
  283. box.proofs.service.createORProof(
  284. null, ciphertext, witness, elements, index, data, _zpSubgroup);
  285. }).toThrow();
  286. expect(function() {
  287. box.proofs.service.createORProof(
  288. publicKey, null, witness, elements, index, data, _zpSubgroup);
  289. }).toThrow();
  290. expect(function() {
  291. box.proofs.service.createORProof(
  292. publicKey, ciphertext, null, elements, index, data,
  293. _zpSubgroup);
  294. }).toThrow();
  295. expect(function() {
  296. box.proofs.service.createORProof(
  297. publicKey, ciphertext, witness, null, index, data,
  298. _zpSubgroup);
  299. }).toThrow();
  300. expect(function() {
  301. box.proofs.service.createORProof(
  302. publicKey, ciphertext, witness, elements, null, data,
  303. _zpSubgroup);
  304. }).toThrow();
  305. expect(function() {
  306. box.proofs.service.createORProof(
  307. publicKey, ciphertext, witness, elements, index, data, null);
  308. }).toThrow();
  309. });
  310. });
  311. it('and throw an exception when generating an OR-proof, using the wrong mathematical group',
  312. function() {
  313. cryptolib('proofs.service', function(box) {
  314. expect(function() {
  315. box.proofs.service.createORProof(
  316. publicKey, ciphertext, witness, elements, index, data,
  317. _anotherzpSubgroup);
  318. }).toThrow();
  319. });
  320. });
  321. it('and throw an exception when generating an OR-proof, using a public key with more than one element',
  322. function() {
  323. cryptolib('proofs.service', function(box) {
  324. expect(function() {
  325. box.proofs.service.createORProof(
  326. aLongerPublicKey, ciphertext, witness, elements, index, data,
  327. _zpSubgroup);
  328. }).toThrow();
  329. });
  330. });
  331. it('and throw an exception when generating an OR-proof, using a ciphertext with more than two elements',
  332. function() {
  333. cryptolib('proofs.service', function(box) {
  334. expect(function() {
  335. box.proofs.service.createORProof(
  336. publicKey, aLongerCiphertext, witness, elements, index, data,
  337. _zpSubgroup);
  338. }).toThrow();
  339. });
  340. });
  341. it('and throw an exception when generating an OR-proof, using less than two elements',
  342. function() {
  343. cryptolib('proofs.service', function(box) {
  344. expect(function() {
  345. box.proofs.service.createORProof(
  346. publicKey, ciphertext, witness, aShorterElements, index, data,
  347. _zpSubgroup);
  348. }).toThrow();
  349. });
  350. });
  351. it('and throw an exception when generating an OR-proof, using a negative index',
  352. function() {
  353. cryptolib('proofs.service', function(box) {
  354. expect(function() {
  355. box.proofs.service.createORProof(
  356. publicKey, ciphertext, witness, elements, -1, data,
  357. _zpSubgroup);
  358. }).toThrow();
  359. });
  360. });
  361. it('and throw an exception when generating an OR-proof, using an index that is greater than the number of elements minus one',
  362. function() {
  363. cryptolib('proofs.service', function(box) {
  364. expect(function() {
  365. box.proofs.service.createORProof(
  366. publicKey, ciphertext, witness, elements, num_elements, data,
  367. _zpSubgroup);
  368. }).toThrow();
  369. });
  370. });
  371. it('and throw an exception when generating an OR-proof from pre-computed values, using too many elements',
  372. function() {
  373. cryptolib('proofs.service', function(box) {
  374. expect(function() {
  375. box.proofs.service.createORProof(
  376. publicKey, ciphertext, witness, aLongerElements, index, data,
  377. _zpSubgroup, preComputedValues);
  378. }).toThrow();
  379. });
  380. });
  381. it('and throw an exception when generating an OR-proof, using a progress callback function that is not a function',
  382. function() {
  383. cryptolib('proofs.service', function(box) {
  384. expect(function() {
  385. box.proofs.service.createORProof(
  386. publicKey, ciphertext, witness, elements, index, data,
  387. _zpSubgroup, PROGRESS_PERCENT_MIN_CHECK_INTERVAL);
  388. }).toThrow();
  389. });
  390. });
  391. it('and throw an exception when generating an OR-proof, using a progress percent check interval that is not a number',
  392. function() {
  393. cryptolib('proofs.service', function(box) {
  394. var percentMeasuredLatest = 0;
  395. var progressCallback = function(progressPercent) {
  396. percentMeasuredLatest = progressPercent;
  397. };
  398. expect(function() {
  399. box.proofs.service.createORProof(
  400. publicKey, ciphertext, witness, elements, index, data,
  401. _zpSubgroup, progressCallback, progressCallback);
  402. }).toThrow();
  403. });
  404. });
  405. it('and throw an exception when pre-computing an OR-proof, using null input data',
  406. function() {
  407. cryptolib('proofs.service', function(box) {
  408. expect(function() {
  409. box.proofs.service.preComputeORProof(
  410. null, num_elements, _zpSubgroup);
  411. }).toThrow();
  412. expect(function() {
  413. box.proofs.service.preComputeORProof(publicKey, null, _zpSubgroup);
  414. }).toThrow();
  415. expect(function() {
  416. box.proofs.service.preComputeORProof(
  417. publicKey, num_elements, null);
  418. }).toThrow();
  419. });
  420. });
  421. it('and throw an exception when pre-computing an OR-proof, using a public key with more than one element',
  422. function() {
  423. cryptolib('proofs.service', function(box) {
  424. expect(function() {
  425. box.proofs.service.preComputeORProof(
  426. aLongerPublicKey, num_elements, _zpSubgroup);
  427. }).toThrow();
  428. });
  429. });
  430. it('and throw an exception when pre-computing an OR-proof, using less than two elements',
  431. function() {
  432. cryptolib('proofs.service', function(box) {
  433. expect(function() {
  434. box.proofs.service.preComputeORProof(publicKey, 1, _zpSubgroup);
  435. }).toThrow();
  436. });
  437. });
  438. it('and throw an exception when pre-computing an OR-proof, using a progress callback function that is not a function',
  439. function() {
  440. cryptolib('proofs.service', function(box) {
  441. expect(function() {
  442. box.proofs.service.preComputeORProof(
  443. publicKey, num_elements, _zpSubgroup,
  444. PROGRESS_PERCENT_MIN_CHECK_INTERVAL);
  445. }).toThrow();
  446. });
  447. });
  448. it('and throw an exception when pre-computing an OR-proof, using a progress percent check interval that is not a number',
  449. function() {
  450. cryptolib('proofs.service', function(box) {
  451. var percentMeasuredLatest = 0;
  452. var progressCallback = function(progressPercent) {
  453. percentMeasuredLatest = progressPercent;
  454. };
  455. expect(function() {
  456. box.proofs.service.preComputeORProof(
  457. publicKey, num_elements, _zpSubgroup, progressCallback,
  458. progressCallback);
  459. }).toThrow();
  460. });
  461. });
  462. it('and throw an exception when verifying an OR-proof, using null input data',
  463. function() {
  464. cryptolib('proofs.service', function(box) {
  465. expect(function() {
  466. box.proofs.service.verifyORProof(
  467. null, ciphertext, elements, data, proof, _zpSubgroup);
  468. }).toThrow();
  469. expect(function() {
  470. box.proofs.service.verifyORProof(
  471. publicKey, null, elements, data, proof, _zpSubgroup);
  472. }).toThrow();
  473. expect(function() {
  474. box.proofs.service.verifyORProof(
  475. publicKey, ciphertext, null, data, proof, _zpSubgroup);
  476. }).toThrow();
  477. expect(function() {
  478. box.proofs.service.verifyORProof(
  479. publicKey, ciphertext, elements, data, null, _zpSubgroup);
  480. }).toThrow();
  481. expect(function() {
  482. box.proofs.service.verifyORProof(
  483. publicKey, ciphertext, elements, data, proof, null);
  484. }).toThrow();
  485. });
  486. });
  487. it('and throw an exception when verifying an OR-proof, using the wrong mathematical group',
  488. function() {
  489. cryptolib('proofs.service', function(box) {
  490. expect(function() {
  491. box.proofs.service.verifyORProof(
  492. publicKey, ciphertext, elements, data, proof,
  493. _anotherZpSubgroup);
  494. }).toThrow();
  495. });
  496. });
  497. it('and throw an exception when verifying an OR-proof, using a public key with more than one element',
  498. function() {
  499. cryptolib('proofs.service', function(box) {
  500. expect(function() {
  501. box.proofs.service.verifyORProof(
  502. aLongerPublicKey, ciphertext, elements, data, proof,
  503. _zpSubgroup);
  504. }).toThrow();
  505. });
  506. });
  507. it('and throw an exception when verifying an OR-proof, using a ciphertext with more than two elements',
  508. function() {
  509. cryptolib('proofs.service', function(box) {
  510. expect(function() {
  511. box.proofs.service.verifyORProof(
  512. publicKey, aLongerCiphertext, elements, data, proof,
  513. _zpSubgroup);
  514. }).toThrow();
  515. });
  516. });
  517. it('and throw an exception when verifying an OR-proof, using less than two elements',
  518. function() {
  519. cryptolib('proofs.service', function(box) {
  520. expect(function() {
  521. box.proofs.service.verifyORProof(
  522. publicKey, ciphertext, aShorterElements, data, proof,
  523. _zpSubgroup);
  524. }).toThrow();
  525. });
  526. });
  527. it('and throw an exception when verifying an OR-proof, using a progress callback function that is not a function',
  528. function() {
  529. cryptolib('proofs.service', function(box) {
  530. expect(function() {
  531. box.proofs.service.verifyORProof(
  532. publicKey, ciphertext, elements, data, proof, _zpSubgroup,
  533. PROGRESS_PERCENT_MIN_CHECK_INTERVAL);
  534. }).toThrow();
  535. });
  536. });
  537. it('and throw an exception when verifying an OR-proof, using a progress percent check interval that is not a number',
  538. function() {
  539. cryptolib('proofs.service', function(box) {
  540. var percentMeasuredLatest = 0;
  541. var progressCallback = function(progressPercent) {
  542. percentMeasuredLatest = progressPercent;
  543. };
  544. expect(function() {
  545. box.proofs.service.verifyORProof(
  546. publicKey, ciphertext, elements, data, proof, _zpSubgroup,
  547. progressCallback, progressCallback);
  548. }).toThrow();
  549. });
  550. });
  551. });
  552. });