writein.spec.js 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868
  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. /* global forge */
  9. /* global OV */
  10. /* global TD */
  11. describe('WriteIn api', function() {
  12. 'use strict';
  13. var p_50_bits = new forge.jsbn.BigInteger("632675155738559");
  14. var q_50_bits = new forge.jsbn.BigInteger("316337577869279");
  15. var p_1024_bits = new forge.jsbn.BigInteger("127221604274531153456037811894129045050707427287018126451033610258225414570293456088114804760360499690320725081015613357713860609352611107211595355579330171109403165025745399040683371804753828679517508339451541325761038070090645847220458502400371988111691904960115084260054586776319747845360881674068179759939");
  16. var q_1024_bits = new forge.jsbn.BigInteger("63610802137265576728018905947064522525353713643509063225516805129112707285146728044057402380180249845160362540507806678856930304676305553605797677789665085554701582512872699520341685902376914339758754169725770662880519035045322923610229251200185994055845952480057542130027293388159873922680440837034089879969");
  17. var p_2048_bits = new forge.jsbn.BigInteger("16370518994319586760319791526293535327576438646782139419846004180837103527129035954742043590609421369665944746587885814920851694546456891767644945459124422553763416586515339978014154452159687109161090635367600349264934924141746082060353483306855352192358732451955232000593777554431798981574529854314651092086488426390776811367125009551346089319315111509277347117467107914073639456805159094562593954195960531136052208019343392906816001017488051366518122404819967204601427304267380238263913892658950281593755894747339126531018026798982785331079065126375455293409065540731646939808640273393855256230820509217411510058759");
  18. var q_2048_bits = new forge.jsbn.BigInteger("8185259497159793380159895763146767663788219323391069709923002090418551763564517977371021795304710684832972373293942907460425847273228445883822472729562211276881708293257669989007077226079843554580545317683800174632467462070873041030176741653427676096179366225977616000296888777215899490787264927157325546043244213195388405683562504775673044659657555754638673558733553957036819728402579547281296977097980265568026104009671696453408000508744025683259061202409983602300713652133690119131956946329475140796877947373669563265509013399491392665539532563187727646704532770365823469904320136696927628115410254608705755029379");
  19. var p_3072_bits = new forge.jsbn.BigInteger("3878981618363851403422785607049427732736469525765273964840494068543041817727859944747888587785804791336126334735655317568383325026575396502302408923900497193860574810106417647833293156361473237473851593342226591737416569274097190298794282094798839851447612748747028941226550444236500328284988232883708279903371633902500527667563618336033732682721663174483318675000290047145413356364086211940765433079496799025339463611957630842302927071374023550249041067140503160804595502533730751141852343308661226499943816174201254213525974778805126213286835381698767182787838530784771675962353210590958127004175441983883147456311021868868237863493150560311147255716532038537882133905836196893266079070881906364328006937745533954805623786263044779903135192824449840823134335864515601600386396870002243889016433896192256236768999995365293442167853292116446399454096548352527896137561043092342974345122064784985329026450531982131124347170447");
  20. var q_3072_bits = new forge.jsbn.BigInteger("1939490809181925701711392803524713866368234762882636982420247034271520908863929972373944293892902395668063167367827658784191662513287698251151204461950248596930287405053208823916646578180736618736925796671113295868708284637048595149397141047399419925723806374373514470613275222118250164142494116441854139951685816951250263833781809168016866341360831587241659337500145023572706678182043105970382716539748399512669731805978815421151463535687011775124520533570251580402297751266865375570926171654330613249971908087100627106762987389402563106643417690849383591393919265392385837981176605295479063502087720991941573728155510934434118931746575280155573627858266019268941066952918098446633039535440953182164003468872766977402811893131522389951567596412224920411567167932257800800193198435001121944508216948096128118384499997682646721083926646058223199727048274176263948068780521546171487172561032392492664513225265991065562173585223");
  21. var alphabet = '# ()0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ`abcdefghijklmnopqrstuvwxyz ¡¢ŠšŽžŒœŸÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ';
  22. it('should produce expected encoding size when no writeins and no representations', function() {
  23. var fields = [];
  24. var usableRepresentationsEncode = [];
  25. var numDesiredElementsInEncoding = 10;
  26. var encoded = OV.encode(fields, alphabet, p_2048_bits, q_2048_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);
  27. expect(encoded.length).toEqual(numDesiredElementsInEncoding);
  28. var usableRepresentationsDecode = [];
  29. var decoded = OV.decode(encoded, alphabet, p_2048_bits, usableRepresentationsDecode);
  30. expect(fields).toEqual(decoded);
  31. });
  32. it('should encode and decode a single character', function() {
  33. var fields = ['2#a'];
  34. var usableRepresentationsEncode = ['2'];
  35. var numDesiredElementsInEncoding = 10;
  36. var encoded = OV.encode(fields, alphabet, p_2048_bits, q_2048_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);
  37. expect(encoded.length).toEqual(numDesiredElementsInEncoding);
  38. var usableRepresentationsDecode = ['2'];
  39. var decoded = OV.decode(encoded, alphabet, p_2048_bits, usableRepresentationsDecode);
  40. expect(fields).toEqual(decoded);
  41. });
  42. it('should encode and decode a list of short strings, using p of size 50 bits', function() {
  43. var fields = ['2#eeny', '17#meeny', '67#miny'];
  44. var usableRepresentationsEncode = ['2', '17', '67'];
  45. var numDesiredElementsInEncoding = 12;
  46. var encoded = OV.encode(fields, alphabet, p_50_bits, q_50_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);
  47. expect(encoded.length).toEqual(numDesiredElementsInEncoding);
  48. var usableRepresentationsDecode = ['2', '17', '67'];
  49. var decoded = OV.decode(encoded, alphabet, p_50_bits, usableRepresentationsDecode);
  50. expect(fields).toEqual(decoded);
  51. });
  52. it('should encode and decode a list of short strings, using p of size 1024 bits', function() {
  53. var fields = ['2#eeny', '17#meeny', '67#miny'];
  54. var usableRepresentationsEncode = ['2', '17', '67'];
  55. var numDesiredElementsInEncoding = 10;
  56. var encoded = OV.encode(fields, alphabet, p_1024_bits, q_1024_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);
  57. expect(encoded.length).toEqual(numDesiredElementsInEncoding);
  58. var usableRepresentationsDecode = ['2', '17', '67'];
  59. var decoded = OV.decode(encoded, alphabet, p_1024_bits, usableRepresentationsDecode);
  60. expect(fields).toEqual(decoded);
  61. });
  62. it('should encode and decode a list of short strings, using p of size 2048 bits', function() {
  63. var fields = ['2#eeny', '17#meeny', '67#miny'];
  64. var usableRepresentationsEncode = ['2', '17', '67'];
  65. var numDesiredElementsInEncoding = 10;
  66. var encoded = OV.encode(fields, alphabet, p_2048_bits, q_2048_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);
  67. expect(encoded.length).toEqual(numDesiredElementsInEncoding);
  68. var usableRepresentationsDecode = ['2', '17', '67'];
  69. var decoded = OV.decode(encoded, alphabet, p_2048_bits, usableRepresentationsDecode);
  70. expect(fields).toEqual(decoded);
  71. });
  72. it('should encode and decode a list of short strings, using p of size 3072 bits', function() {
  73. var fields = ['2#eeny', '17#meeny', '67#miny'];
  74. var usableRepresentationsEncode = ['2', '17', '67'];
  75. var numDesiredElementsInEncoding = 10;
  76. var encoded = OV.encode(fields, alphabet, p_3072_bits, q_3072_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);
  77. expect(encoded.length).toEqual(numDesiredElementsInEncoding);
  78. var usableRepresentationsDecode = ['2', '17', '67'];
  79. var decoded = OV.decode(encoded, alphabet, p_3072_bits, usableRepresentationsDecode);
  80. expect(fields).toEqual(decoded);
  81. });
  82. it('should encode and decode a string that includes spaces', function() {
  83. var fields = ['2#Fred Flintstone'];
  84. var usableRepresentationsEncode = ['2'];
  85. var numDesiredElementsInEncoding = 10;
  86. var encoded = OV.encode(fields, alphabet, p_2048_bits, q_2048_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);
  87. expect(encoded.length).toEqual(numDesiredElementsInEncoding);
  88. var usableRepresentationsDecode = ['2'];
  89. var decoded = OV.decode(encoded, alphabet, p_2048_bits, usableRepresentationsDecode);
  90. expect(fields).toEqual(decoded);
  91. });
  92. it('should encode and decode multiple strings that include spaces', function() {
  93. var fields = ['2#Elvis Presley', '17#Micky Mouse', '67#Pope John Paul II', '107#Fred Flintstone'];
  94. var usableRepresentationsEncode = ['2', '17', '67', '107'];
  95. var numDesiredElementsInEncoding = 10;
  96. var encoded = OV.encode(fields, alphabet, p_2048_bits, q_2048_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);
  97. expect(encoded.length).toEqual(numDesiredElementsInEncoding);
  98. var usableRepresentationsDecode = ['2', '17', '67', '107'];
  99. var decoded = OV.decode(encoded, alphabet, p_2048_bits, usableRepresentationsDecode);
  100. expect(fields).toEqual(decoded);
  101. });
  102. it('should encode and decode a list of strings that contain a single character', function() {
  103. var fields = ['2#a', '17#b', '67#c', '107#d', '139#e', '151#f', '163#g', '197#h', '229#i', '241#j', '367#k'];
  104. var usableRepresentationsEncode = ['2', '17', '67', '107', '139', '151', '163', '197', '229', '241', '367'];
  105. var numDesiredElementsInEncoding = 10;
  106. var encoded = OV.encode(fields, alphabet, p_2048_bits, q_2048_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);
  107. expect(encoded.length).toEqual(numDesiredElementsInEncoding);
  108. var usableRepresentationsDecode = ['2', '17', '67', '107', '139', '151', '163', '197', '229', '241', '367'];
  109. var decoded = OV.decode(encoded, alphabet, p_2048_bits, usableRepresentationsDecode, usableRepresentationsDecode);
  110. expect(fields).toEqual(decoded);
  111. });
  112. it('should encode and decode a list of strings that only includes spaces', function() {
  113. var fields = ['2# ',
  114. '17# ',
  115. '67# ',
  116. '107# ',
  117. '139# '];
  118. var usableRepresentationsEncode = ['2', '17', '67', '107', '139'];
  119. var numDesiredElementsInEncoding = 10;
  120. var encoded = OV.encode(fields, alphabet, p_2048_bits, q_2048_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);
  121. expect(encoded.length).toEqual(numDesiredElementsInEncoding);
  122. var usableRepresentationsDecode = ['2', '17', '67', '107', '139'];
  123. var decoded = OV.decode(encoded, alphabet, p_2048_bits, usableRepresentationsDecode, usableRepresentationsDecode);
  124. expect(fields).toEqual(decoded);
  125. });
  126. it('should encode and decode a large amount of data', function() {
  127. var fields = get8StringsOf100Characters();
  128. var usableRepresentationsEncode = ['2', '17', '67', '107', '139', '151', '163', '197'];
  129. var numDesiredElementsInEncoding = 10;
  130. var encoded = OV.encode(fields, alphabet, p_2048_bits, q_2048_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);
  131. expect(encoded.length).toEqual(numDesiredElementsInEncoding);
  132. var usableRepresentationsDecode = ['2', '17', '67', '107', '139', '151', '163', '197'];
  133. var decoded = OV.decode(encoded, alphabet, p_2048_bits, usableRepresentationsDecode, usableRepresentationsDecode);
  134. expect(fields).toEqual(decoded);
  135. });
  136. it('should encode and decode a very large amount of data, using p of size 50 bits', function() {
  137. var fields = generate20StringsOf120Characters();
  138. var usableRepresentationsEncode = ['2', '17', '67', '107', '139', '151', '163', '197', '229', '241', '367', '373', '431', '463', '601', '683', '719', '757', '701', '821'];
  139. var numDesiredElementsInEncoding = 1248;
  140. var encoded = OV.encode(fields, alphabet, p_50_bits, q_50_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);
  141. expect(encoded.length).toEqual(numDesiredElementsInEncoding);
  142. var usableRepresentationsDecode = ['2', '17', '67', '107', '139', '151', '163', '197', '229', '241', '367', '373', '431', '463', '601', '683', '719', '757', '701', '821'];
  143. var decoded = OV.decode(encoded, alphabet, p_50_bits, usableRepresentationsDecode);
  144. expect(fields).toEqual(decoded);
  145. });
  146. it('should encode and decode a very large amount of data, using p of size 1024 bits', function() {
  147. var fields = generate20StringsOf120Characters();
  148. var usableRepresentationsEncode = ['2', '17', '67', '107', '139', '151', '163', '197', '229', '241', '367', '373', '431', '463', '601', '683', '719', '757', '701', '821'];
  149. var numDesiredElementsInEncoding = 49;
  150. var encoded = OV.encode(fields, alphabet, p_1024_bits, q_1024_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);
  151. expect(encoded.length).toEqual(numDesiredElementsInEncoding);
  152. var usableRepresentationsDecode = ['2', '17', '67', '107', '139', '151', '163', '197', '229', '241', '367', '373', '431', '463', '601', '683', '719', '757', '701', '821'];
  153. var decoded = OV.decode(encoded, alphabet, p_1024_bits, usableRepresentationsDecode);
  154. expect(fields).toEqual(decoded);
  155. });
  156. it('should encode and decode a very large amount of data, and the desired size of the encoding is one less than the actual size, using p of size 2048 bits', function() {
  157. var fields = generate20StringsOf120Characters();
  158. var usableRepresentationsEncode = ['2', '17', '67', '107', '139', '151', '163', '197', '229', '241', '367', '373', '431', '463', '601', '683', '719', '757', '701', '821'];
  159. var numDesiredElementsInEncoding = 24;
  160. expect(function() {
  161. var encoded = OV.encode(fields, alphabet, p_2048_bits, q_2048_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);
  162. }).toThrow(new Error('The encoding has more elements than the desired number. Desired number: 24, actual number: 25'));
  163. });
  164. it('should encode and decode a very large amount of data, and the desired size of the encoding is exactly equal to the actual size, using p of size 2048 bits', function() {
  165. var fields = generate20StringsOf120Characters();
  166. var usableRepresentationsEncode = ['2', '17', '67', '107', '139', '151', '163', '197', '229', '241', '367', '373', '431', '463', '601', '683', '719', '757', '701', '821'];
  167. var numDesiredElementsInEncoding = 25;
  168. var encoded = OV.encode(fields, alphabet, p_2048_bits, q_2048_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);
  169. expect(encoded.length).toEqual(numDesiredElementsInEncoding);
  170. var usableRepresentationsDecode = ['2', '17', '67', '107', '139', '151', '163', '197', '229', '241', '367', '373', '431', '463', '601', '683', '719', '757', '701', '821'];
  171. var decoded = OV.decode(encoded, alphabet, p_2048_bits, usableRepresentationsDecode);
  172. expect(fields).toEqual(decoded);
  173. });
  174. it('should encode and decode a very large amount of data, and the desired size of the encoding is one more than the actual size, using p of size 2048 bits', function() {
  175. var fields = generate20StringsOf120Characters();
  176. var usableRepresentationsEncode = ['2', '17', '67', '107', '139', '151', '163', '197', '229', '241', '367', '373', '431', '463', '601', '683', '719', '757', '701', '821'];
  177. var numDesiredElementsInEncoding = 26;
  178. var encoded = OV.encode(fields, alphabet, p_2048_bits, q_2048_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);
  179. expect(encoded.length).toEqual(numDesiredElementsInEncoding);
  180. var usableRepresentationsDecode = ['2', '17', '67', '107', '139', '151', '163', '197', '229', '241', '367', '373', '431', '463', '601', '683', '719', '757', '701', '821'];
  181. var decoded = OV.decode(encoded, alphabet, p_2048_bits, usableRepresentationsDecode);
  182. expect(fields).toEqual(decoded);
  183. });
  184. it('should encode and decode a very large amount of data, using p of size 3072 bits', function() {
  185. var fields = generate20StringsOf120Characters();
  186. var usableRepresentationsEncode = ['2', '17', '67', '107', '139', '151', '163', '197', '229', '241', '367', '373', '431', '463', '601', '683', '719', '757', '701', '821'];
  187. var numDesiredElementsInEncoding = 17;
  188. var encoded = OV.encode(fields, alphabet, p_3072_bits, q_3072_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);
  189. expect(encoded.length).toEqual(numDesiredElementsInEncoding);
  190. var usableRepresentationsDecode = ['2', '17', '67', '107', '139', '151', '163', '197', '229', '241', '367', '373', '431', '463', '601', '683', '719', '757', '701', '821'];
  191. var decoded = OV.decode(encoded, alphabet, p_3072_bits, usableRepresentationsDecode);
  192. expect(fields).toEqual(decoded);
  193. });
  194. it('should encode and decode strings of various lengths', function() {
  195. var fields = generateStringsOfVariousLengths();
  196. var usableRepresentationsEncode = ['2', '17', '67', '107', '139', '151', '163', '197', '229', '241', '367', '373', '431', '463', '601', '683', '719', '757'];
  197. var numDesiredElementsInEncoding = 10;
  198. var encoded = OV.encode(fields, alphabet, p_2048_bits, q_2048_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);
  199. expect(encoded.length).toEqual(numDesiredElementsInEncoding);
  200. var usableRepresentationsDecode = ['2', '17', '67', '107', '139', '151', '163', '197', '229', '241', '367', '373', '431', '463', '601', '683', '719', '757'];
  201. var decoded = OV.decode(encoded, alphabet, p_2048_bits, usableRepresentationsDecode);
  202. expect(fields).toEqual(decoded);
  203. });
  204. it('should encode and decode strings that contain all the alphabet characters', function() {
  205. var alphabetWithoutSeparator = alphabet.substring(1);
  206. var representation = '2';
  207. var bothPartsOfWritinString = representation + '#' + alphabetWithoutSeparator;
  208. var fields = [bothPartsOfWritinString];
  209. var usableRepresentationsEncode = ['2'];
  210. var numDesiredElementsInEncoding = 10;
  211. var encoded = OV.encode(fields, alphabet, p_2048_bits, q_2048_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);
  212. expect(encoded.length).toEqual(numDesiredElementsInEncoding);
  213. var usableRepresentationsDecode = ['2'];
  214. var decoded = OV.decode(encoded, alphabet, p_2048_bits, usableRepresentationsDecode);
  215. expect(fields).toEqual(decoded);
  216. });
  217. it('should encode 102 chars can be encoded in one element regardless of chars', function() {
  218. ///////////////////////////////////
  219. //
  220. // test one of the initial characters in alphabet
  221. //
  222. ///////////////////////////////////
  223. var stringWith102InitialChars = '1#((((((((((';
  224. for (var i = 0; i < 9; i++) {
  225. stringWith102InitialChars += '((((((((((';
  226. }
  227. var fields = [stringWith102InitialChars];
  228. var usableRepresentationsEncode = ['1'];
  229. var numDesiredElementsInEncoding = 1;
  230. var encoded = OV.encode(fields, alphabet, p_2048_bits, q_2048_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);
  231. expect(encoded.length).toEqual(numDesiredElementsInEncoding);
  232. var usableRepresentationsDecode = ['1'];
  233. var decoded = OV.decode(encoded, alphabet, p_2048_bits, usableRepresentationsDecode);
  234. expect(fields).toEqual(decoded);
  235. ///////////////////////////////////
  236. //
  237. // test last character in alphabet
  238. //
  239. ///////////////////////////////////
  240. var stringWith102LastChars = '1#ÿÿÿÿÿÿÿÿÿÿ';
  241. for (var i = 0; i < 9; i++) {
  242. stringWith102LastChars += 'ÿÿÿÿÿÿÿÿÿÿ';
  243. }
  244. var fields = [stringWith102LastChars];
  245. var encoded = OV.encode(fields, alphabet, p_2048_bits, q_2048_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);
  246. expect(encoded.length).toEqual(numDesiredElementsInEncoding);
  247. var decoded = OV.decode(encoded, alphabet, p_2048_bits, usableRepresentationsDecode);
  248. expect(fields).toEqual(decoded);
  249. });
  250. it('should encode and decode 6 char prime plus seperator plus 95 char string', function() {
  251. var composedOf6charPrime1charSeperator95CharString = '478453#34567890';
  252. for (var i = 0; i < 8; i++) {
  253. composedOf6charPrime1charSeperator95CharString += '1234567890';
  254. }
  255. var fields = [composedOf6charPrime1charSeperator95CharString];
  256. var usableRepresentationsEncode = ['478453'];
  257. var numDesiredElementsInEncoding = 1;
  258. var encoded = OV.encode(fields, alphabet, p_2048_bits, q_2048_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);
  259. expect(encoded.length).toEqual(numDesiredElementsInEncoding);
  260. var usableRepresentationsDecode = ['478453'];
  261. var decoded = OV.decode(encoded, alphabet, p_2048_bits, usableRepresentationsDecode);
  262. expect(fields).toEqual(decoded);
  263. });
  264. it('should encode and decode 6 char prime plus seperator plus 95 char string', function() {
  265. var stringWith150Chars = '1#34567890';
  266. for (var i = 0; i < 9; i++) {
  267. stringWith150Chars += '1234567890';
  268. }
  269. var stringWith20Chars = "2#11111111";
  270. stringWith20Chars += "1111111111";
  271. var fields = [stringWith150Chars, stringWith20Chars];
  272. var usableRepresentationsEncode = ['1', '2'];
  273. var numDesiredElementsInEncoding = 2;
  274. var encoded = OV.encode(fields, alphabet, p_2048_bits, q_2048_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);
  275. expect(encoded.length).toEqual(numDesiredElementsInEncoding);
  276. var usableRepresentationsDecode = ['1', '2'];
  277. var decoded = OV.decode(encoded, alphabet, p_2048_bits, usableRepresentationsDecode);
  278. expect(fields).toEqual(decoded);
  279. });
  280. //////////////////////////////////////////////////////
  281. //
  282. // Exception handling
  283. //
  284. //////////////////////////////////////////////////////
  285. it('should refuse to decode empty write-ins', function() {
  286. // Prepare encoding of the following write in: 1#A#2#
  287. // With numeric representation: 008 003 022 003 009 003
  288. var encodedWriteIns = new forge.jsbn.BigInteger('008003022003009003').pow(2);
  289. var encoded = [ encodedWriteIns ];
  290. var usableRepresentationsDecode = ['1', '2'];
  291. expect(function() {
  292. OV.decode(encoded, alphabet, p_2048_bits, usableRepresentationsDecode);
  293. }).toThrow(new Error('Exception during decoding - empty write-in is not valid'));
  294. });
  295. it('should refuse to encode strings that include invalid characters', function() {
  296. var fields = ['2#eeny',
  297. '27#meeny',
  298. '67#mi/ny'];
  299. var usableRepresentationsEncode = ['2', '27', '67'];
  300. var numDesiredElementsInEncoding = 10;
  301. expect(function() {
  302. OV.encode(fields, alphabet, p_2048_bits, q_2048_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);
  303. }).toThrow(new Error('Invalid character for writein encoding: /'));
  304. });
  305. it('should refuse to encode strings including the reserved separator char', function() {
  306. var fields = ['2#eeny',
  307. '17#m#eeny',
  308. '67#miny'];
  309. var usableRepresentationsEncode = ['2', '27', '67'];
  310. var numDesiredElementsInEncoding = 10;
  311. expect(function() {
  312. OV.encode(fields, alphabet, p_2048_bits, q_2048_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);
  313. }).toThrow(new Error('There should be exactly one separator character in each writein string, but this was not the case for: 17#m#eeny'));
  314. });
  315. it('should refuse to encode if list of strings is null', function() {
  316. var fields;
  317. var usableRepresentationsEncode = ['2', '27', '67'];
  318. var numDesiredElementsInEncoding = 10;
  319. expect(function() {
  320. OV.encode(fields, alphabet, p_2048_bits, q_2048_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);
  321. }).toThrow(new Error('Exception during encoding - there are valid representations but no write-ins'));
  322. });
  323. it('should refuse to decode if list of strings is null', function() {
  324. var numDesiredElementsInEncoding = 10;
  325. var encoded = [];
  326. for(var i = 0; i < numDesiredElementsInEncoding; i++) {
  327. encoded.push(new forge.jsbn.BigInteger('2'));
  328. }
  329. var usableRepresentationsDecode = ['2', '17', '67', '107', '139', '151', '163', '197', '229', '241', '367'];
  330. var numDesiredElementsInEncoding = 10;
  331. expect(function() {
  332. OV.decode(encoded, alphabet, p_2048_bits, q_2048_bits, usableRepresentationsDecode);
  333. }).toThrow(new Error('Exception during decoding - there are valid representations but no write-ins'));
  334. });
  335. it('should refuse to encode list of strings is empty', function() {
  336. var fields = [];
  337. var usableRepresentationsDecode = ['2', '17', '67', '107', '139', '151', '163', '197', '229', '241', '367'];
  338. var numDesiredElementsInEncoding = 10;
  339. expect(function() {
  340. OV.encode(fields, alphabet, p_2048_bits, q_2048_bits, numDesiredElementsInEncoding, usableRepresentationsDecode);
  341. }).toThrow(new Error('Exception during encoding - there are valid representations but no write-ins'));
  342. });
  343. it('should refuse to encode if the alphabet is null', function() {
  344. var fields = ['2#eeny', '17#meeny', '67#miny'];
  345. var usableRepresentationsEncode = ['2', '17', '67'];
  346. var alphabetNull;
  347. var numDesiredElementsInEncoding = 10;
  348. expect(function() {
  349. OV.encode(fields, alphabetNull, p_2048_bits, q_2048_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);
  350. }).toThrow(new Error('Exception during encoding - the alphabet was not initialized'));
  351. });
  352. it('should refuse to encode if the p parameter is null', function() {
  353. var fields = ['2#eeny', '17#meeny', '67#miny'];
  354. var usableRepresentationsEncode = ['2', '17', '67'];
  355. var pNull;
  356. var numDesiredElementsInEncoding = 10;
  357. expect(function() {
  358. OV.encode(fields, alphabet, pNull, q_2048_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);
  359. }).toThrow(new Error('The p parameter was not initialized'));
  360. });
  361. it('should refuse to encode if the q parameter is null', function() {
  362. var fields = ['2#eeny', '17#meeny', '67#miny'];
  363. var usableRepresentationsEncode = ['2', '17', '67'];
  364. var qNull;
  365. var numDesiredElementsInEncoding = 10;
  366. expect(function() {
  367. OV.encode(fields, alphabet, p_2048_bits, qNull, numDesiredElementsInEncoding, usableRepresentationsEncode);
  368. }).toThrow(new Error('The q parameter was not initialized'));
  369. });
  370. it('should refuse to encode if the p parameter is too small', function() {
  371. var fields = ['2#eeny'];
  372. var usableRepresentationsEncode = ['2'];
  373. var numDesiredElementsInEncoding = 10;
  374. var pSmall = new forge.jsbn.BigInteger("23");
  375. var qSmall = new forge.jsbn.BigInteger("11");
  376. expect(function() {
  377. OV.encode(fields, alphabet, pSmall, qSmall, numDesiredElementsInEncoding, usableRepresentationsEncode);
  378. }).toThrow(new Error('Encoded writein too big for the mathematical group. Value: 9003048048057068, p: 23'));
  379. });
  380. it('should refuse to encode if the num desired elements is null', function() {
  381. var fields = ['2#eeny'];
  382. var usableRepresentationsEncode = ['2'];
  383. var numDesiredElementsInEncoding;
  384. expect(function() {
  385. OV.encode(fields, alphabet, p_2048_bits, q_2048_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);
  386. }).toThrow(new Error('The number of desired elements was not initialized'));
  387. });
  388. it('should refuse to encode if the num desired elements is less than one', function() {
  389. var fields = ['2#eeny'];
  390. var usableRepresentationsEncode = ['2'];
  391. var numDesiredElementsInEncoding = 0;
  392. expect(function() {
  393. OV.encode(fields, alphabet, p_2048_bits, q_2048_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);
  394. }).toThrow(new Error('The number of desired elements was 0'));
  395. });
  396. it('should refuse to encode if a writeins has non-existing representation', function() {
  397. var fields = ['1#34567890', '2#11111111'];
  398. var usableRepresentationsEncode = ['1', '3'];
  399. var numDesiredElementsInEncoding = 2;
  400. expect(function() {
  401. OV.encode(fields, alphabet, p_2048_bits, q_2048_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);
  402. }).toThrow(new Error('Exception during encoding - invalid representation found in encoded write-in: 2'));
  403. });
  404. it('should refuse to decode if a writeins has non-existing representation', function() {
  405. var element1 = new forge.jsbn.BigInteger('64048169236358500663849057129246379287397362373369349412557608601668511434281136976800608560576496512448384320256192128064');
  406. var element2 = new forge.jsbn.BigInteger('2');
  407. var encoded = [element1, element2];
  408. var usableRepresentationsDecode = ['1'];
  409. expect(function() {
  410. OV.decode(encoded, alphabet, p_2048_bits, usableRepresentationsDecode);
  411. }).toThrow(new Error('Exception during decoding - invalid representation found in encoded write-in: 2'));
  412. });
  413. it('should refuse to encode if two writeins have the same representation', function() {
  414. var fields = ['1#34567890', '1#11111111'];
  415. var usableRepresentationsEncode = ['1', '2'];
  416. var numDesiredElementsInEncoding = 2;
  417. expect(function() {
  418. OV.encode(fields, alphabet, p_2048_bits, q_2048_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);
  419. }).toThrow(new Error('Exception during encoding - repeated representation: 1'));
  420. });
  421. it('should refuse to decode if two writeins have the same representation', function() {
  422. var element1 = new forge.jsbn.BigInteger('64048169236358500663849057129246363281377340349343321382525594595651505418265120960784592544560496512448384320256192128064');
  423. var element2 = new forge.jsbn.BigInteger('2');
  424. var encoded = [element1, element2];
  425. var usableRepresentationsDecode = ['1'];
  426. var numDesiredElementsInEncoding = 2;
  427. expect(function() {
  428. OV.decode(encoded, alphabet, p_2048_bits, usableRepresentationsDecode);
  429. }).toThrow(new Error('Exception during decoding - repeated representation: 1'));
  430. });
  431. it('should refuse to encode unused representation', function() {
  432. var fields = ['2#a',
  433. '17#b',
  434. '67#c',
  435. '107#d',
  436. '139#e',
  437. '151#f',
  438. '163#g',
  439. '197#h',
  440. '229#i',
  441. '241#j',
  442. '367#k'];
  443. var usableRepresentationsEncode = ['2', '17', '67', '107', '139', '151', '163', '197', '229', '241', '367', '51545'];
  444. var numDesiredElementsInEncoding = 2;
  445. expect(function() {
  446. OV.encode(fields, alphabet, p_2048_bits, q_2048_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);
  447. }).toThrow(new Error('Exception during encoding - representations not used: 51545'));
  448. });
  449. it('should refuse to decode unused representation', function() {
  450. var fields = ['2#a',
  451. '17#b',
  452. '67#c',
  453. '107#d',
  454. '139#e',
  455. '151#f',
  456. '163#g',
  457. '197#h',
  458. '229#i',
  459. '241#j',
  460. '367#k'];
  461. var usableRepresentationsEncode = ['2', '17', '67', '107', '139', '151', '163', '197', '229', '241', '367'];
  462. var numDesiredElementsInEncoding = 2;
  463. var encoded = OV.encode(fields, alphabet, p_2048_bits, q_2048_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);
  464. var usableRepresentationsDecode = ['2', '17', '67', '107', '139', '151', '163', '197', '229', '241', '367', '51545'];
  465. expect(function() {
  466. OV.decode(encoded, alphabet, p_2048_bits, usableRepresentationsDecode);
  467. }).toThrow(new Error('Exception during decoding - representations not used: 51545'));
  468. });
  469. it('should convert a writein encoding into a group member', function() {
  470. var number = new forge.jsbn.BigInteger('1234567');
  471. expect(OV.makeGroupElement(number, p_2048_bits).toString())
  472. .toBe('1524155677489');
  473. });
  474. it('should refuse to convert a writein into a group memmber if not smaller than p', function() {
  475. var number = p_2048_bits.add(forge.jsbn.BigInteger.ONE);
  476. expect(function name() {
  477. OV.makeGroupElement(number, p_2048_bits);
  478. }).toThrow();
  479. });
  480. //////////////////////////////////////////////////////
  481. //
  482. // Square and squareroot
  483. //
  484. //////////////////////////////////////////////////////
  485. it('square and squareroot recovers original value 10', function() {
  486. var p = p_2048_bits;
  487. var q = q_2048_bits;
  488. var value = new forge.jsbn.BigInteger('10');
  489. var square = OV.squareToEnsureIsGroupElement(value, p, q);
  490. var result = OV.sqrtN(square);
  491. expect(value.equals(result)).toBe(true);
  492. });
  493. it('square and squareroot recovers original value 10 digits', function() {
  494. var p = p_2048_bits;
  495. var q = q_2048_bits;
  496. var value = new forge.jsbn.BigInteger('1234567890');
  497. var square = OV.squareToEnsureIsGroupElement(value, p, q);
  498. var result = OV.sqrtN(square);
  499. expect(value.toString()).toEqual(result.toString());
  500. });
  501. it('square and squareroot recovers original value 100 digits', function() {
  502. var p = p_2048_bits;
  503. var q = q_2048_bits;
  504. var value = new forge.jsbn.BigInteger('1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890');
  505. var square = OV.squareToEnsureIsGroupElement(value, p, q);
  506. var result = OV.sqrtN(square);
  507. expect(value.toString()).toEqual(result.toString());
  508. });
  509. it('square and squareroot recovers original value 200 digits', function() {
  510. var p = p_2048_bits;
  511. var q = q_2048_bits;
  512. var value = new forge.jsbn.BigInteger('12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890');
  513. var square = OV.squareToEnsureIsGroupElement(value, p, q);
  514. var result = OV.sqrtN(square);
  515. expect(value.toString()).toEqual(result.toString());
  516. });
  517. it('square and squareroot recovers original value 300 digits', function() {
  518. var p = p_2048_bits;
  519. var q = q_2048_bits;
  520. var value = new forge.jsbn.BigInteger('123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890');
  521. var square = OV.squareToEnsureIsGroupElement(value, p, q);
  522. var result = OV.sqrtN(square);
  523. expect(value.toString()).toEqual(result.toString());
  524. });
  525. var get8StringsOf100Characters = function() {
  526. var fields = ['2#AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
  527. '17#BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB',
  528. '67#CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC',
  529. '107#DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD',
  530. '139#EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE',
  531. '151#FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF',
  532. '163#GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG',
  533. '197#HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH'];
  534. return fields;
  535. };
  536. var generate20StringsOf120Characters = function() {
  537. var fields = ['2#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
  538. '17#bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',
  539. '67#cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc',
  540. '107#dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd',
  541. '139#eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee',
  542. '151#ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff',
  543. '163#gggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg',
  544. '197#hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh',
  545. '229#iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii',
  546. '241#jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj',
  547. '367#kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkZZZZZZZZZZZZZZZZZZZZZZZ',
  548. '373#llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll',
  549. '431#mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm',
  550. '463#n n n n n n n n n n n n n n n n n n n n n n n n nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn',
  551. '601#oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooopppppppppppppppppppppppppppppppppppppppppppppppppppppppppppp',
  552. '683#ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ',
  553. '719#ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ',
  554. '701#ææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææ',
  555. '757#start of spaces end of spaces',
  556. '821#çççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççç'];
  557. return fields;
  558. };
  559. var generateStringsOfVariousLengths = function() {
  560. var fields = ['2#A',
  561. '17#BB',
  562. '67#CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC',
  563. '107#DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD',
  564. '139#EEEEEEEEEEEEEEEEEEEEEEEEEE',
  565. '151#FFFF',
  566. '163#GGGGGGGGGGGGGGGGGG',
  567. '197#HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH',
  568. '229#IIIIIIIIIIIIIIIIIIIIIIIIII',
  569. '241#JJJJJJJJJJJJJ',
  570. '367#KKKKKKK',
  571. '373#LLL',
  572. '431#MM',
  573. '463#N',
  574. '601#OO',
  575. '683#PPPPPP',
  576. '719#QQQQQQQQQQQ',
  577. '757#RRRRRRRRRRRRRRRRRR'];
  578. return fields;
  579. };
  580. });