| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868 | /* * Copyright 2018 Scytl Secure Electronic Voting SA * * All rights reserved * * See our extended copyright notice in *file 'Copyright.txt' which is part of this source code package *//* global forge *//* global OV *//* global TD */describe('WriteIn api', function() {    'use strict';    var p_50_bits = new forge.jsbn.BigInteger("632675155738559");    var q_50_bits = new forge.jsbn.BigInteger("316337577869279");    var p_1024_bits = new forge.jsbn.BigInteger("127221604274531153456037811894129045050707427287018126451033610258225414570293456088114804760360499690320725081015613357713860609352611107211595355579330171109403165025745399040683371804753828679517508339451541325761038070090645847220458502400371988111691904960115084260054586776319747845360881674068179759939");    var q_1024_bits = new forge.jsbn.BigInteger("63610802137265576728018905947064522525353713643509063225516805129112707285146728044057402380180249845160362540507806678856930304676305553605797677789665085554701582512872699520341685902376914339758754169725770662880519035045322923610229251200185994055845952480057542130027293388159873922680440837034089879969");    var p_2048_bits = new forge.jsbn.BigInteger("16370518994319586760319791526293535327576438646782139419846004180837103527129035954742043590609421369665944746587885814920851694546456891767644945459124422553763416586515339978014154452159687109161090635367600349264934924141746082060353483306855352192358732451955232000593777554431798981574529854314651092086488426390776811367125009551346089319315111509277347117467107914073639456805159094562593954195960531136052208019343392906816001017488051366518122404819967204601427304267380238263913892658950281593755894747339126531018026798982785331079065126375455293409065540731646939808640273393855256230820509217411510058759");    var q_2048_bits = new forge.jsbn.BigInteger("8185259497159793380159895763146767663788219323391069709923002090418551763564517977371021795304710684832972373293942907460425847273228445883822472729562211276881708293257669989007077226079843554580545317683800174632467462070873041030176741653427676096179366225977616000296888777215899490787264927157325546043244213195388405683562504775673044659657555754638673558733553957036819728402579547281296977097980265568026104009671696453408000508744025683259061202409983602300713652133690119131956946329475140796877947373669563265509013399491392665539532563187727646704532770365823469904320136696927628115410254608705755029379");    var p_3072_bits = new forge.jsbn.BigInteger("3878981618363851403422785607049427732736469525765273964840494068543041817727859944747888587785804791336126334735655317568383325026575396502302408923900497193860574810106417647833293156361473237473851593342226591737416569274097190298794282094798839851447612748747028941226550444236500328284988232883708279903371633902500527667563618336033732682721663174483318675000290047145413356364086211940765433079496799025339463611957630842302927071374023550249041067140503160804595502533730751141852343308661226499943816174201254213525974778805126213286835381698767182787838530784771675962353210590958127004175441983883147456311021868868237863493150560311147255716532038537882133905836196893266079070881906364328006937745533954805623786263044779903135192824449840823134335864515601600386396870002243889016433896192256236768999995365293442167853292116446399454096548352527896137561043092342974345122064784985329026450531982131124347170447");    var q_3072_bits = new forge.jsbn.BigInteger("1939490809181925701711392803524713866368234762882636982420247034271520908863929972373944293892902395668063167367827658784191662513287698251151204461950248596930287405053208823916646578180736618736925796671113295868708284637048595149397141047399419925723806374373514470613275222118250164142494116441854139951685816951250263833781809168016866341360831587241659337500145023572706678182043105970382716539748399512669731805978815421151463535687011775124520533570251580402297751266865375570926171654330613249971908087100627106762987389402563106643417690849383591393919265392385837981176605295479063502087720991941573728155510934434118931746575280155573627858266019268941066952918098446633039535440953182164003468872766977402811893131522389951567596412224920411567167932257800800193198435001121944508216948096128118384499997682646721083926646058223199727048274176263948068780521546171487172561032392492664513225265991065562173585223");    var alphabet = '# ()0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ`abcdefghijklmnopqrstuvwxyz ¡¢ŠšŽžŒœŸÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ';    it('should produce expected encoding size when no writeins and no representations', function() {        var fields = [];        var usableRepresentationsEncode = [];        var numDesiredElementsInEncoding = 10;        var encoded = OV.encode(fields, alphabet, p_2048_bits, q_2048_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);        expect(encoded.length).toEqual(numDesiredElementsInEncoding);        var usableRepresentationsDecode = [];        var decoded = OV.decode(encoded, alphabet, p_2048_bits, usableRepresentationsDecode);        expect(fields).toEqual(decoded);    });    it('should encode and decode a single character', function() {        var fields = ['2#a'];        var usableRepresentationsEncode = ['2'];        var numDesiredElementsInEncoding = 10;        var encoded = OV.encode(fields, alphabet, p_2048_bits, q_2048_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);        expect(encoded.length).toEqual(numDesiredElementsInEncoding);        var usableRepresentationsDecode = ['2'];        var decoded = OV.decode(encoded, alphabet, p_2048_bits, usableRepresentationsDecode);        expect(fields).toEqual(decoded);    });    it('should encode and decode a list of short strings, using p of size 50 bits', function() {        var fields = ['2#eeny', '17#meeny', '67#miny'];        var usableRepresentationsEncode = ['2', '17', '67'];        var numDesiredElementsInEncoding = 12;        var encoded = OV.encode(fields, alphabet, p_50_bits, q_50_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);        expect(encoded.length).toEqual(numDesiredElementsInEncoding);        var usableRepresentationsDecode = ['2', '17', '67'];        var decoded = OV.decode(encoded, alphabet, p_50_bits, usableRepresentationsDecode);        expect(fields).toEqual(decoded);    });    it('should encode and decode a list of short strings, using p of size 1024 bits', function() {        var fields = ['2#eeny', '17#meeny', '67#miny'];        var usableRepresentationsEncode = ['2', '17', '67'];        var numDesiredElementsInEncoding = 10;        var encoded = OV.encode(fields, alphabet, p_1024_bits, q_1024_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);        expect(encoded.length).toEqual(numDesiredElementsInEncoding);        var usableRepresentationsDecode = ['2', '17', '67'];        var decoded = OV.decode(encoded, alphabet, p_1024_bits, usableRepresentationsDecode);        expect(fields).toEqual(decoded);    });    it('should encode and decode a list of short strings, using p of size 2048 bits', function() {        var fields = ['2#eeny', '17#meeny', '67#miny'];        var usableRepresentationsEncode = ['2', '17', '67'];        var numDesiredElementsInEncoding = 10;        var encoded = OV.encode(fields, alphabet, p_2048_bits, q_2048_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);        expect(encoded.length).toEqual(numDesiredElementsInEncoding);        var usableRepresentationsDecode = ['2', '17', '67'];        var decoded = OV.decode(encoded, alphabet, p_2048_bits, usableRepresentationsDecode);        expect(fields).toEqual(decoded);    });    it('should encode and decode a list of short strings, using p of size 3072 bits', function() {        var fields = ['2#eeny', '17#meeny', '67#miny'];        var usableRepresentationsEncode = ['2', '17', '67'];        var numDesiredElementsInEncoding = 10;        var encoded = OV.encode(fields, alphabet, p_3072_bits, q_3072_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);        expect(encoded.length).toEqual(numDesiredElementsInEncoding);        var usableRepresentationsDecode = ['2', '17', '67'];        var decoded = OV.decode(encoded, alphabet, p_3072_bits, usableRepresentationsDecode);        expect(fields).toEqual(decoded);    });    it('should encode and decode a string that includes spaces', function() {        var fields = ['2#Fred Flintstone'];        var usableRepresentationsEncode = ['2'];        var numDesiredElementsInEncoding = 10;        var encoded = OV.encode(fields, alphabet, p_2048_bits, q_2048_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);        expect(encoded.length).toEqual(numDesiredElementsInEncoding);        var usableRepresentationsDecode = ['2'];        var decoded = OV.decode(encoded, alphabet, p_2048_bits, usableRepresentationsDecode);        expect(fields).toEqual(decoded);    });    it('should encode and decode multiple strings that include spaces', function() {        var fields = ['2#Elvis Presley', '17#Micky Mouse', '67#Pope John Paul II', '107#Fred Flintstone'];        var usableRepresentationsEncode = ['2', '17', '67', '107'];        var numDesiredElementsInEncoding = 10;        var encoded = OV.encode(fields, alphabet, p_2048_bits, q_2048_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);        expect(encoded.length).toEqual(numDesiredElementsInEncoding);        var usableRepresentationsDecode = ['2', '17', '67', '107'];        var decoded = OV.decode(encoded, alphabet, p_2048_bits, usableRepresentationsDecode);        expect(fields).toEqual(decoded);    });    it('should encode and decode a list of strings that contain a single character', function() {        var fields = ['2#a', '17#b', '67#c', '107#d', '139#e', '151#f', '163#g', '197#h', '229#i', '241#j', '367#k'];        var usableRepresentationsEncode = ['2', '17', '67', '107', '139', '151', '163', '197', '229', '241', '367'];        var numDesiredElementsInEncoding = 10;        var encoded = OV.encode(fields, alphabet, p_2048_bits, q_2048_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);        expect(encoded.length).toEqual(numDesiredElementsInEncoding);        var usableRepresentationsDecode = ['2', '17', '67', '107', '139', '151', '163', '197', '229', '241', '367'];        var decoded = OV.decode(encoded, alphabet, p_2048_bits, usableRepresentationsDecode, usableRepresentationsDecode);        expect(fields).toEqual(decoded);    });    it('should encode and decode a list of strings that only includes spaces', function() {        var fields = ['2#                ',                      '17#                ',                      '67#                ',                      '107#                ',                      '139#                '];        var usableRepresentationsEncode = ['2', '17', '67', '107', '139'];        var numDesiredElementsInEncoding = 10;        var encoded = OV.encode(fields, alphabet, p_2048_bits, q_2048_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);        expect(encoded.length).toEqual(numDesiredElementsInEncoding);        var usableRepresentationsDecode = ['2', '17', '67', '107', '139'];        var decoded = OV.decode(encoded, alphabet, p_2048_bits, usableRepresentationsDecode, usableRepresentationsDecode);        expect(fields).toEqual(decoded);    });    it('should encode and decode a large amount of data', function() {        var fields = get8StringsOf100Characters();        var usableRepresentationsEncode = ['2', '17', '67', '107', '139', '151', '163', '197'];        var numDesiredElementsInEncoding = 10;        var encoded = OV.encode(fields, alphabet, p_2048_bits, q_2048_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);        expect(encoded.length).toEqual(numDesiredElementsInEncoding);        var usableRepresentationsDecode = ['2', '17', '67', '107', '139', '151', '163', '197'];        var decoded = OV.decode(encoded, alphabet, p_2048_bits, usableRepresentationsDecode, usableRepresentationsDecode);        expect(fields).toEqual(decoded);    });    it('should encode and decode a very large amount of data, using p of size 50 bits', function() {        var fields = generate20StringsOf120Characters();        var usableRepresentationsEncode = ['2', '17', '67', '107', '139', '151', '163', '197', '229', '241', '367', '373', '431', '463', '601', '683', '719', '757', '701', '821'];        var numDesiredElementsInEncoding = 1248;        var encoded = OV.encode(fields, alphabet, p_50_bits, q_50_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);        expect(encoded.length).toEqual(numDesiredElementsInEncoding);        var usableRepresentationsDecode = ['2', '17', '67', '107', '139', '151', '163', '197', '229', '241', '367', '373', '431', '463', '601', '683', '719', '757', '701', '821'];        var decoded = OV.decode(encoded, alphabet, p_50_bits, usableRepresentationsDecode);        expect(fields).toEqual(decoded);    });    it('should encode and decode a very large amount of data, using p of size 1024 bits', function() {        var fields = generate20StringsOf120Characters();        var usableRepresentationsEncode = ['2', '17', '67', '107', '139', '151', '163', '197', '229', '241', '367', '373', '431', '463', '601', '683', '719', '757', '701', '821'];        var numDesiredElementsInEncoding = 49;        var encoded = OV.encode(fields, alphabet, p_1024_bits, q_1024_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);        expect(encoded.length).toEqual(numDesiredElementsInEncoding);        var usableRepresentationsDecode = ['2', '17', '67', '107', '139', '151', '163', '197', '229', '241', '367', '373', '431', '463', '601', '683', '719', '757', '701', '821'];        var decoded = OV.decode(encoded, alphabet, p_1024_bits, usableRepresentationsDecode);        expect(fields).toEqual(decoded);    });    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() {        var fields = generate20StringsOf120Characters();        var usableRepresentationsEncode = ['2', '17', '67', '107', '139', '151', '163', '197', '229', '241', '367', '373', '431', '463', '601', '683', '719', '757', '701', '821'];        var numDesiredElementsInEncoding = 24;        expect(function() {            var encoded = OV.encode(fields, alphabet, p_2048_bits, q_2048_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);        }).toThrow(new Error('The encoding has more elements than the desired number. Desired number: 24, actual number: 25'));    });    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() {        var fields = generate20StringsOf120Characters();        var usableRepresentationsEncode = ['2', '17', '67', '107', '139', '151', '163', '197', '229', '241', '367', '373', '431', '463', '601', '683', '719', '757', '701', '821'];        var numDesiredElementsInEncoding = 25;        var encoded = OV.encode(fields, alphabet, p_2048_bits, q_2048_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);        expect(encoded.length).toEqual(numDesiredElementsInEncoding);        var usableRepresentationsDecode = ['2', '17', '67', '107', '139', '151', '163', '197', '229', '241', '367', '373', '431', '463', '601', '683', '719', '757', '701', '821'];        var decoded = OV.decode(encoded, alphabet, p_2048_bits, usableRepresentationsDecode);        expect(fields).toEqual(decoded);    });    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() {        var fields = generate20StringsOf120Characters();        var usableRepresentationsEncode = ['2', '17', '67', '107', '139', '151', '163', '197', '229', '241', '367', '373', '431', '463', '601', '683', '719', '757', '701', '821'];        var numDesiredElementsInEncoding = 26;        var encoded = OV.encode(fields, alphabet, p_2048_bits, q_2048_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);        expect(encoded.length).toEqual(numDesiredElementsInEncoding);        var usableRepresentationsDecode = ['2', '17', '67', '107', '139', '151', '163', '197', '229', '241', '367', '373', '431', '463', '601', '683', '719', '757', '701', '821'];        var decoded = OV.decode(encoded, alphabet, p_2048_bits, usableRepresentationsDecode);        expect(fields).toEqual(decoded);    });    it('should encode and decode a very large amount of data, using p of size 3072 bits', function() {        var fields = generate20StringsOf120Characters();        var usableRepresentationsEncode = ['2', '17', '67', '107', '139', '151', '163', '197', '229', '241', '367', '373', '431', '463', '601', '683', '719', '757', '701', '821'];        var numDesiredElementsInEncoding = 17;        var encoded = OV.encode(fields, alphabet, p_3072_bits, q_3072_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);        expect(encoded.length).toEqual(numDesiredElementsInEncoding);        var usableRepresentationsDecode = ['2', '17', '67', '107', '139', '151', '163', '197', '229', '241', '367', '373', '431', '463', '601', '683', '719', '757', '701', '821'];        var decoded = OV.decode(encoded, alphabet, p_3072_bits, usableRepresentationsDecode);        expect(fields).toEqual(decoded);    });    it('should encode and decode strings of various lengths', function() {        var fields = generateStringsOfVariousLengths();        var usableRepresentationsEncode = ['2', '17', '67', '107', '139', '151', '163', '197', '229', '241', '367', '373', '431', '463', '601', '683', '719', '757'];        var numDesiredElementsInEncoding = 10;        var encoded = OV.encode(fields, alphabet, p_2048_bits, q_2048_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);        expect(encoded.length).toEqual(numDesiredElementsInEncoding);        var usableRepresentationsDecode = ['2', '17', '67', '107', '139', '151', '163', '197', '229', '241', '367', '373', '431', '463', '601', '683', '719', '757'];        var decoded = OV.decode(encoded, alphabet, p_2048_bits, usableRepresentationsDecode);        expect(fields).toEqual(decoded);    });    it('should encode and decode strings that contain all the alphabet characters', function() {        var alphabetWithoutSeparator = alphabet.substring(1);        var representation = '2';        var bothPartsOfWritinString = representation + '#' + alphabetWithoutSeparator;        var fields = [bothPartsOfWritinString];        var usableRepresentationsEncode = ['2'];        var numDesiredElementsInEncoding = 10;        var encoded = OV.encode(fields, alphabet, p_2048_bits, q_2048_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);        expect(encoded.length).toEqual(numDesiredElementsInEncoding);        var usableRepresentationsDecode = ['2'];        var decoded = OV.decode(encoded, alphabet, p_2048_bits, usableRepresentationsDecode);        expect(fields).toEqual(decoded);    });    it('should encode 102 chars can be encoded in one element regardless of chars', function() {            ///////////////////////////////////        //        // test one of the initial characters in alphabet        //        ///////////////////////////////////        var stringWith102InitialChars = '1#((((((((((';        for (var i = 0; i < 9; i++) {            stringWith102InitialChars += '((((((((((';        }        var fields = [stringWith102InitialChars];        var usableRepresentationsEncode = ['1'];        var numDesiredElementsInEncoding = 1;        var encoded = OV.encode(fields, alphabet, p_2048_bits, q_2048_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);        expect(encoded.length).toEqual(numDesiredElementsInEncoding);        var usableRepresentationsDecode = ['1'];        var decoded = OV.decode(encoded, alphabet, p_2048_bits, usableRepresentationsDecode);        expect(fields).toEqual(decoded);        ///////////////////////////////////        //        // test last character in alphabet        //        ///////////////////////////////////        var stringWith102LastChars = '1#ÿÿÿÿÿÿÿÿÿÿ';        for (var i = 0; i < 9; i++) {            stringWith102LastChars += 'ÿÿÿÿÿÿÿÿÿÿ';        }        var fields = [stringWith102LastChars];        var encoded = OV.encode(fields, alphabet, p_2048_bits, q_2048_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);        expect(encoded.length).toEqual(numDesiredElementsInEncoding);        var decoded = OV.decode(encoded, alphabet, p_2048_bits, usableRepresentationsDecode);        expect(fields).toEqual(decoded);    });    it('should encode and decode 6 char prime plus seperator plus 95 char string', function() {        var composedOf6charPrime1charSeperator95CharString = '478453#34567890';        for (var i = 0; i < 8; i++) {            composedOf6charPrime1charSeperator95CharString += '1234567890';        }        var fields = [composedOf6charPrime1charSeperator95CharString];        var usableRepresentationsEncode = ['478453'];        var numDesiredElementsInEncoding = 1;        var encoded = OV.encode(fields, alphabet, p_2048_bits, q_2048_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);        expect(encoded.length).toEqual(numDesiredElementsInEncoding);        var usableRepresentationsDecode = ['478453'];        var decoded = OV.decode(encoded, alphabet, p_2048_bits, usableRepresentationsDecode);        expect(fields).toEqual(decoded);    });    it('should encode and decode 6 char prime plus seperator plus 95 char string', function() {        var stringWith150Chars = '1#34567890';        for (var i = 0; i < 9; i++) {            stringWith150Chars += '1234567890';        }        var stringWith20Chars = "2#11111111";        stringWith20Chars += "1111111111";        var fields = [stringWith150Chars, stringWith20Chars];        var usableRepresentationsEncode = ['1', '2'];        var numDesiredElementsInEncoding = 2;        var encoded = OV.encode(fields, alphabet, p_2048_bits, q_2048_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);        expect(encoded.length).toEqual(numDesiredElementsInEncoding);        var usableRepresentationsDecode = ['1', '2'];        var decoded = OV.decode(encoded, alphabet, p_2048_bits, usableRepresentationsDecode);        expect(fields).toEqual(decoded);    });    //////////////////////////////////////////////////////    //    // Exception handling    //    //////////////////////////////////////////////////////		it('should refuse to decode empty write-ins', function() {				// Prepare encoding of the following write in: 1#A#2#        // With numeric representation: 008 003 022 003 009 003		var encodedWriteIns = new forge.jsbn.BigInteger('008003022003009003').pow(2);        var encoded = [ encodedWriteIns ];				var usableRepresentationsDecode = ['1', '2'];        expect(function() {            OV.decode(encoded, alphabet, p_2048_bits, usableRepresentationsDecode);        }).toThrow(new Error('Exception during decoding - empty write-in is not valid'));			});    it('should refuse to encode strings that include invalid characters', function() {        var fields = ['2#eeny',                      '27#meeny',                      '67#mi/ny'];        var usableRepresentationsEncode = ['2', '27', '67'];        var numDesiredElementsInEncoding = 10;        expect(function() {            OV.encode(fields, alphabet, p_2048_bits, q_2048_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);        }).toThrow(new Error('Invalid character for writein encoding: /'));    });    it('should refuse to encode strings including the reserved separator char', function() {        var fields = ['2#eeny',                      '17#m#eeny',                      '67#miny'];        var usableRepresentationsEncode = ['2', '27', '67'];        var numDesiredElementsInEncoding = 10;        expect(function() {            OV.encode(fields, alphabet, p_2048_bits, q_2048_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);        }).toThrow(new Error('There should be exactly one separator character in each writein string, but this was not the case for: 17#m#eeny'));    });    it('should refuse to encode if list of strings is null', function() {        var fields;        var usableRepresentationsEncode = ['2', '27', '67'];        var numDesiredElementsInEncoding = 10;        expect(function() {            OV.encode(fields, alphabet, p_2048_bits, q_2048_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);        }).toThrow(new Error('Exception during encoding - there are valid representations but no write-ins'));    });    it('should refuse to decode if list of strings is null', function() {        var numDesiredElementsInEncoding = 10;        var encoded = [];        for(var i = 0; i < numDesiredElementsInEncoding; i++) {            encoded.push(new forge.jsbn.BigInteger('2'));        }        var usableRepresentationsDecode = ['2', '17', '67', '107', '139', '151', '163', '197', '229', '241', '367'];        var numDesiredElementsInEncoding = 10;        expect(function() {            OV.decode(encoded, alphabet, p_2048_bits, q_2048_bits, usableRepresentationsDecode);        }).toThrow(new Error('Exception during decoding - there are valid representations but no write-ins'));    });    it('should refuse to encode list of strings is empty', function() {        var fields = [];        var usableRepresentationsDecode = ['2', '17', '67', '107', '139', '151', '163', '197', '229', '241', '367'];        var numDesiredElementsInEncoding = 10;        expect(function() {            OV.encode(fields, alphabet, p_2048_bits, q_2048_bits, numDesiredElementsInEncoding, usableRepresentationsDecode);        }).toThrow(new Error('Exception during encoding - there are valid representations but no write-ins'));    });    it('should refuse to encode if the alphabet is null', function() {        var fields = ['2#eeny', '17#meeny', '67#miny'];        var usableRepresentationsEncode = ['2', '17', '67'];        var alphabetNull;        var numDesiredElementsInEncoding = 10;        expect(function() {            OV.encode(fields, alphabetNull, p_2048_bits, q_2048_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);        }).toThrow(new Error('Exception during encoding - the alphabet was not initialized'));    });    it('should refuse to encode if the p parameter is null', function() {        var fields = ['2#eeny', '17#meeny', '67#miny'];        var usableRepresentationsEncode = ['2', '17', '67'];        var pNull;        var numDesiredElementsInEncoding = 10;        expect(function() {            OV.encode(fields, alphabet, pNull, q_2048_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);        }).toThrow(new Error('The p parameter was not initialized'));    });    it('should refuse to encode if the q parameter is null', function() {        var fields = ['2#eeny', '17#meeny', '67#miny'];        var usableRepresentationsEncode = ['2', '17', '67'];        var qNull;        var numDesiredElementsInEncoding = 10;        expect(function() {            OV.encode(fields, alphabet, p_2048_bits, qNull, numDesiredElementsInEncoding, usableRepresentationsEncode);        }).toThrow(new Error('The q parameter was not initialized'));    });    it('should refuse to encode if the p parameter is too small', function() {        var fields = ['2#eeny'];        var usableRepresentationsEncode = ['2'];        var numDesiredElementsInEncoding = 10;        var pSmall = new forge.jsbn.BigInteger("23");        var qSmall = new forge.jsbn.BigInteger("11");        expect(function() {            OV.encode(fields, alphabet, pSmall, qSmall, numDesiredElementsInEncoding, usableRepresentationsEncode);        }).toThrow(new Error('Encoded writein too big for the mathematical group. Value: 9003048048057068, p: 23'));    });    it('should refuse to encode if the num desired elements is null', function() {        var fields = ['2#eeny'];        var usableRepresentationsEncode = ['2'];        var numDesiredElementsInEncoding;        expect(function() {            OV.encode(fields, alphabet, p_2048_bits, q_2048_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);        }).toThrow(new Error('The number of desired elements was not initialized'));    });    it('should refuse to encode if the num desired elements is less than one', function() {        var fields = ['2#eeny'];        var usableRepresentationsEncode = ['2'];        var numDesiredElementsInEncoding = 0;        expect(function() {            OV.encode(fields, alphabet, p_2048_bits, q_2048_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);        }).toThrow(new Error('The number of desired elements was 0'));    });    it('should refuse to encode if a writeins has non-existing representation', function() {        var fields = ['1#34567890', '2#11111111'];        var usableRepresentationsEncode = ['1', '3'];        var numDesiredElementsInEncoding = 2;        expect(function() {            OV.encode(fields, alphabet, p_2048_bits, q_2048_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);        }).toThrow(new Error('Exception during encoding - invalid representation found in encoded write-in: 2'));    });    it('should refuse to decode if a writeins has non-existing representation', function() {        var element1 = new forge.jsbn.BigInteger('64048169236358500663849057129246379287397362373369349412557608601668511434281136976800608560576496512448384320256192128064');        var element2 = new forge.jsbn.BigInteger('2');        var encoded = [element1, element2];        var usableRepresentationsDecode = ['1'];        expect(function() {            OV.decode(encoded, alphabet, p_2048_bits, usableRepresentationsDecode);        }).toThrow(new Error('Exception during decoding - invalid representation found in encoded write-in: 2'));    });    it('should refuse to encode if two writeins have the same representation', function() {        var fields = ['1#34567890', '1#11111111'];        var usableRepresentationsEncode = ['1', '2'];        var numDesiredElementsInEncoding = 2;        expect(function() {            OV.encode(fields, alphabet, p_2048_bits, q_2048_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);        }).toThrow(new Error('Exception during encoding - repeated representation: 1'));    });    it('should refuse to decode if two writeins have the same representation', function() {        var element1 = new forge.jsbn.BigInteger('64048169236358500663849057129246363281377340349343321382525594595651505418265120960784592544560496512448384320256192128064');        var element2 = new forge.jsbn.BigInteger('2');        var encoded = [element1, element2];        var usableRepresentationsDecode = ['1'];        var numDesiredElementsInEncoding = 2;        expect(function() {            OV.decode(encoded, alphabet, p_2048_bits, usableRepresentationsDecode);        }).toThrow(new Error('Exception during decoding - repeated representation: 1'));    });    it('should refuse to encode unused representation', function() {        var fields = ['2#a',                      '17#b',                      '67#c',                      '107#d',                      '139#e',                      '151#f',                      '163#g',                      '197#h',                      '229#i',                      '241#j',                      '367#k'];        var usableRepresentationsEncode = ['2', '17', '67', '107', '139', '151', '163', '197', '229', '241', '367', '51545'];        var numDesiredElementsInEncoding = 2;        expect(function() {            OV.encode(fields, alphabet, p_2048_bits, q_2048_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);        }).toThrow(new Error('Exception during encoding - representations not used: 51545'));    });    it('should refuse to decode unused representation', function() {        var fields = ['2#a',                      '17#b',                      '67#c',                      '107#d',                      '139#e',                      '151#f',                      '163#g',                      '197#h',                      '229#i',                      '241#j',                      '367#k'];        var usableRepresentationsEncode = ['2', '17', '67', '107', '139', '151', '163', '197', '229', '241', '367'];        var numDesiredElementsInEncoding = 2;        var encoded = OV.encode(fields, alphabet, p_2048_bits, q_2048_bits, numDesiredElementsInEncoding, usableRepresentationsEncode);        var usableRepresentationsDecode = ['2', '17', '67', '107', '139', '151', '163', '197', '229', '241', '367', '51545'];        expect(function() {            OV.decode(encoded, alphabet, p_2048_bits, usableRepresentationsDecode);        }).toThrow(new Error('Exception during decoding - representations not used: 51545'));    });    it('should convert a writein encoding into a group member', function() {        var number = new forge.jsbn.BigInteger('1234567');        expect(OV.makeGroupElement(number, p_2048_bits).toString())            .toBe('1524155677489');    });    it('should refuse to convert a writein into a group memmber if not smaller than p', function() {        var number = p_2048_bits.add(forge.jsbn.BigInteger.ONE);        expect(function name() {            OV.makeGroupElement(number, p_2048_bits);        }).toThrow();    });    //////////////////////////////////////////////////////    //    // Square and squareroot    //    //////////////////////////////////////////////////////    it('square and squareroot recovers original value 10', function() {        var p = p_2048_bits;        var q = q_2048_bits;        var value = new forge.jsbn.BigInteger('10');        var square = OV.squareToEnsureIsGroupElement(value, p, q);        var result = OV.sqrtN(square);        expect(value.equals(result)).toBe(true);    });    it('square and squareroot recovers original value 10 digits', function() {        var p = p_2048_bits;        var q = q_2048_bits;        var value = new forge.jsbn.BigInteger('1234567890');        var square = OV.squareToEnsureIsGroupElement(value, p, q);        var result = OV.sqrtN(square);        expect(value.toString()).toEqual(result.toString());    });    it('square and squareroot recovers original value 100 digits', function() {        var p = p_2048_bits;        var q = q_2048_bits;        var value = new forge.jsbn.BigInteger('1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890');        var square = OV.squareToEnsureIsGroupElement(value, p, q);        var result = OV.sqrtN(square);        expect(value.toString()).toEqual(result.toString());    });    it('square and squareroot recovers original value 200 digits', function() {        var p = p_2048_bits;        var q = q_2048_bits;        var value = new forge.jsbn.BigInteger('12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890');        var square = OV.squareToEnsureIsGroupElement(value, p, q);        var result = OV.sqrtN(square);        expect(value.toString()).toEqual(result.toString());    });    it('square and squareroot recovers original value 300 digits', function() {        var p = p_2048_bits;        var q = q_2048_bits;        var value = new forge.jsbn.BigInteger('123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890');        var square = OV.squareToEnsureIsGroupElement(value, p, q);        var result = OV.sqrtN(square);        expect(value.toString()).toEqual(result.toString());    });    var get8StringsOf100Characters = function() {        var fields = ['2#AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',        '17#BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB',        '67#CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC',        '107#DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD',        '139#EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE',        '151#FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF',        '163#GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG',        '197#HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH'];        return fields;    };    var generate20StringsOf120Characters = function() {        var fields = ['2#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',        '17#bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',        '67#cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc',        '107#dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd',        '139#eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee',        '151#ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff',        '163#gggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg',        '197#hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh',        '229#iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii',        '241#jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj',        '367#kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkZZZZZZZZZZZZZZZZZZZZZZZ',        '373#llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll',        '431#mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm',        '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',        '601#oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooopppppppppppppppppppppppppppppppppppppppppppppppppppppppppppp',        '683#ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ',        '719#ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ',        '701#ææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææææ',        '757#start of spaces                                                                                            end of spaces',        '821#çççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççççç'];        return fields;    };    var generateStringsOfVariousLengths = function() {        var fields = ['2#A',        '17#BB',        '67#CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC',        '107#DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD',        '139#EEEEEEEEEEEEEEEEEEEEEEEEEE',        '151#FFFF',        '163#GGGGGGGGGGGGGGGGGG',        '197#HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH',        '229#IIIIIIIIIIIIIIIIIIIIIIIIII',        '241#JJJJJJJJJJJJJ',        '367#KKKKKKK',        '373#LLL',        '431#MM',        '463#N',        '601#OO',        '683#PPPPPP',        '719#QQQQQQQQQQQ',        '757#RRRRRRRRRRRRRRRRRR'];        return fields;    };});
 |