/* * 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; }; });