diff --git a/frontend/Ubuntu/4iCs6KVjbNBYlgoKcQ72nU6AF7xm.woff2 b/frontend/Ubuntu/4iCs6KVjbNBYlgoKcQ72nU6AF7xm.woff2 new file mode 100644 index 0000000..ae52f5c Binary files /dev/null and b/frontend/Ubuntu/4iCs6KVjbNBYlgoKcQ72nU6AF7xm.woff2 differ diff --git a/frontend/Ubuntu/4iCs6KVjbNBYlgoKcg72nU6AF7xm.woff2 b/frontend/Ubuntu/4iCs6KVjbNBYlgoKcg72nU6AF7xm.woff2 new file mode 100644 index 0000000..b96c82c Binary files /dev/null and b/frontend/Ubuntu/4iCs6KVjbNBYlgoKcg72nU6AF7xm.woff2 differ diff --git a/frontend/Ubuntu/4iCs6KVjbNBYlgoKcw72nU6AF7xm.woff2 b/frontend/Ubuntu/4iCs6KVjbNBYlgoKcw72nU6AF7xm.woff2 new file mode 100644 index 0000000..1c96c0c Binary files /dev/null and b/frontend/Ubuntu/4iCs6KVjbNBYlgoKcw72nU6AF7xm.woff2 differ diff --git a/frontend/Ubuntu/4iCs6KVjbNBYlgoKew72nU6AF7xm.woff2 b/frontend/Ubuntu/4iCs6KVjbNBYlgoKew72nU6AF7xm.woff2 new file mode 100644 index 0000000..83eefae Binary files /dev/null and b/frontend/Ubuntu/4iCs6KVjbNBYlgoKew72nU6AF7xm.woff2 differ diff --git a/frontend/Ubuntu/4iCs6KVjbNBYlgoKfA72nU6AF7xm.woff2 b/frontend/Ubuntu/4iCs6KVjbNBYlgoKfA72nU6AF7xm.woff2 new file mode 100644 index 0000000..b496474 Binary files /dev/null and b/frontend/Ubuntu/4iCs6KVjbNBYlgoKfA72nU6AF7xm.woff2 differ diff --git a/frontend/Ubuntu/4iCs6KVjbNBYlgoKfw72nU6AFw.woff2 b/frontend/Ubuntu/4iCs6KVjbNBYlgoKfw72nU6AFw.woff2 new file mode 100644 index 0000000..39e70aa Binary files /dev/null and b/frontend/Ubuntu/4iCs6KVjbNBYlgoKfw72nU6AFw.woff2 differ diff --git a/frontend/_DATA_.js b/frontend/_DATA_.js new file mode 100644 index 0000000..a32cae6 --- /dev/null +++ b/frontend/_DATA_.js @@ -0,0 +1,486 @@ + + + +const _DATA_ = { + translation_texts: { + website_title: { + is_plain: true, + prefix: 'Volt - ', + use_instead: 'website_heading', + }, + website_heading: { + de: 'Umfrage zur\ninternen Diversität', + en: 'Internal\nDiversity\nSurvey', + }, + website_description: { + // de: ` + // Um unseren internen Diversitäts-Ansprüchen nachkommen zu können, müssen wir rausfinden wie divers wir sind. + // Mit dieser Umfrage möchten wir ein Bild davon bekommen. + // `, + de: ` + Um unseren internen Diversitäts-Ansprüchen nachzukommen, müssen wir rausfinden wie divers wir sind. + Mit dieser Umfrage machen wir uns ein Bild davon. + `, + en: ` + To meet our internal diversity goals, we need to find out how diverse we actually are. + With this survey, we'll get a picture of that. + `, + }, + //website_privacy: {de:` + // Da uns Privatsphäre wichtig ist, werden die Antworten jeweils zur Frage gruppiert gespeichert, sodass die hier eingegebenen Daten nicht auf dich zurückführbar sind. + // + // Zu den einzelnen Datensätzen werden nur die im folgenden Kasten genannten Metadaten gespeichert. + // + // Bei Fragen kannst du dich an thomas.rosen@volteuropa.org wenden. + //`}, + + // necessary_metadata: {de: 'Benötigte Metadaten: '}, + // voluntary_metadata: {de: 'Freiwillige Metadaten: '}, + // metadata_running_year: {de: 'Das laufende Jahr:'}, + // metadata_running_month: {de: 'Der laufende Monat:'}, + // metadata_tatc_info: {de: 'Ein, für jede Frage unterschiedlicher, annonymer Tracking-Code.'}, + // metadata_if_it_is_first_completion: {de: 'Ob du das erste Mal an der Umfrage teilnimmst.'}, + // your_country: {de: 'Dein Land:'}, + // your_city: {de: 'Deine Stadt:'}, + // voluntary_metadata_description: {de: 'Jeweils das Land und/oder das Städteteam in dem du am aktivsten bist.'}, + + button_to_privacy: { + de: 'Los geht\'s', + en: 'Let\'s start', + }, + + heading_privacy: { + de: 'Privatsphäre und Datenschutz', + en: 'Privacy', + }, + heading_optional: { + de: 'Freiwillig', + en: 'Optional', + }, + optional_info: { + de: 'Beantworte nur die Fragen die du beantworten möchtest.', + en: 'Only answer the questions you want to answer.', + }, + heading_anonymous: { + de: 'Anonym', + en: 'Anonymous', + }, + anonymous_info: { + de: 'Die Antworten werden jeweils zur Frage gruppiert gespeichert. Rückschlüsse auf Dich sind nicht möglich.', + en: 'The answers are saved in groups for each question. It is not possible to draw conclusions about you.', + }, + privacy_details: { + de: ` + Zu jeder Frage werden das aktuelle Jahr und der aktuelle Monat gespeichert. Optional werden dazu noch dein Land und deine Stadt gespeichert. + + Volt Europa verwendet Deine im Rahmen dieser Umfrage angegebenen Daten ausschließlich, um die Umfrage auszuwerten und die Ergebnisse gegebenenfalls mit Mitgliedern von Volt Europa zu teilen. Weitere Informationen kannst Du unserer Datenschutzerklärung auf www.volteuropa.org/privacy entnehmen. + + Bei Fragen zu dieser Umfrage kannst du dich an thomas.rosen@volteuropa.org wenden. + `, + en: ` + For each question the current year and month are saved. Optionally, your current country and city are saved as well. + + Volt Europa will only use the information you provide in this survey for the purpose of evaluating the survey and sharing the results with Volt Europa members, if applicable. For more information, please see our privacy policy at www.volteuropa.org/privacy. + + If you have any questions about this survey, please contact thomas.rosen@volteuropa.org. + `, + }, + button_to_questions: { + de: 'Zu den Fragen', + en: 'To the questions', + }, + + metadata_is_this_the_first_completion: { + de: 'Nimmst du das erste Mal an der Umfrage teil?', + en: 'Is this your first time participating in the survey?', + }, + button_send_to_volt: { + de: 'An Volt senden', + en: 'Send to Volt', + }, + + saving: { + de: 'Deine Antworten werden gespeichert…', + en: 'Your answers are being saved…', + }, + success: { + de: 'Deine Antworten wurden gespeichert!', + en: 'Your answers have been saved!', + }, + error: { + de: 'Es gab ein technisches Problem!\nBist du eventuell nicht mit dem Internet verbunden?\n\nMelde dich bei Bedarf bei Thomas Rosen.', + en: 'There was a technical problem! Perhaps you are not connected to the internet?\n\nContact Thomas Rosen if necessary.', + }, + + results: { + de: 'Ergebnisse', + en: 'Results', + }, + }, + sections: [ + { + heading: { + de: 'Metadaten', + en: 'Metadata', + }, + questions: { + metadata_country: { + question: { + de: 'Dein Land', + en: 'Your country', + }, + type: 'chooser', + options: {}, + }, + metadata_city: { + question: { + de: 'Dein Städteteam', + en: 'Your cityteam', + }, + type: 'one_line_text', + }, + } + }, + { + heading: { + de: 'Bildung', + en: 'Education', + }, + questions: { + highest_degree_of_education: { + question: { de: 'Dein höchster Bildungsabschluss…' }, + // why: {de: 'Aus welcher Bildungsschicht kommen unsere Mitglieder?'}, + type: 'radio', // 'chooser', + options: { + 'none': { de: 'Kein Abschluss' }, + 'ISCED_1': { de: 'Vollendung der Grundschule' }, + 'ISCED_2': { de: 'Haupt- / Realschulabschluss' }, + 'ISCED_3': { de: 'Abitur' }, + 'ISCED_4': { de: 'Fachhochschulreife / Fachabitur' }, // {de: 'Fachhochschulreife / Fachgebundene Hochschulreife(Fachabitur)'}, + 'ISCED_5': { de: 'Meister' }, + 'ISCED_6': { de: 'Bachelor / Diplom(FH)' }, + 'ISCED_7': { de: 'Master / Diplom(Uni)' }, + 'ISCED_8': { de: 'Doktorat / PhD' }, + } + }, + good_communication_in_english: { + question: { de: 'Kannst du dich gut auf Englisch verständigen?' }, + why: { de: 'Als internationale Organisation wird viel auf Englisch kommuniziert. Hiermit möchten wir schauen, ob mehr in die einzelnen Sprachen übersetzt werden sollte.' }, + type: 'radio', + options: { + 'yes': { + de: 'Ja', + en: 'Yes', + }, + 'no': { + de: 'Nein', + en: 'No', + }, + } + }, + problems_with_computers: { + question: { de: 'Hast du gelegentlich/oft Probleme dich am Computer oder Handy zurecht zu finden?' }, + why: { de: 'Wir schauen hiermit, wie viel wir innerhalb von Volt auf technische Lösungen setzten können?' }, + type: 'radio', + options: { + 'yes': { de: '(Eher) Ja' }, + 'no': { de: '(Eher) Nein' }, + 'depends': { de: 'Kommt drauf an (Gerät, Betriebsystem, Anwendung,…)' }, + } + }, + } + }, + { + heading: { de: 'Kultur' }, + questions: { + amount_of_kown_languages: { + question: { de: 'Wie viele Sprachen kannst du sprechen/verstehen?' }, + why: { de: 'Austausch über die eigene Sprach-Bubble hinaus.' }, + info: { de: 'Zähl auch Mutter- und Gebärdensprachen dazu.' }, + type: 'radio', + options: { + '1': { de: '1' }, + '2': { de: '2' }, + '3': { de: '3' }, + '4': { de: '4' }, + '5+': { de: '5 oder mehr' }, + } + }, + different_country_of_origin: { + question: { de: 'Lebst du in einem anderen Land als du geboren bist?' }, + why: { de: 'Wissen anderer Kulturen in Volt.' }, + type: 'radio', + options: { + 'yes': { + de: 'Ja', + en: 'Yes', + }, + 'no': { + de: 'Nein', + en: 'No', + }, + } + }, + } + }, + { + heading: { de: 'LGBTQ*' }, + questions: { + gender: { + question: { de: 'Wie bezeichnest du dein Gender?' }, + why: { de: 'Gender ist nicht das Geschlecht in deinem Ausweiß, sondern beschreibt die nicht an biologische Merkmale gebundenen Geschlechtsaspekte des Menschen.' }, + type: 'radio', // 'chooser', + options: { + 'female': { de: 'weiblich' }, + 'male': { de: 'männlich' }, + 'non_binary': { de: 'non-binary / weder weiblich noch männlich' }, + 'gender_fluid': { de: 'gender-fluid' }, + 'not_sure': { de: 'Ich bin mir nicht sicher.' }, + 'terms_dont_fit': { de: 'Diese Begriffe passen nicht zu mir.' }, + }, + }, + gender_identity: { + question: { de: 'Wie bezeichnest du deine Geschlechtsidentität?' }, + why: { de: 'Um die Probleme einer Trans-Person vollständig nachvollziehen zu können, muss man selbst Trans* sein. Daher sollten wir wissen, wie gut wir zu diesem Thema aufgestellt sind.' }, + info: { de: 'Cisgender: Biologisches Geschlecht und Gender sind gleich.' }, + type: 'radio', // 'chooser', + options: { + 'transgender': { de: 'Transgender' }, + 'cisgender': { de: 'Cisgender' }, + 'not_sure': { de: 'Ich bin mir nicht sicher' }, + 'terms_dont_fit': { de: 'Diese Begriffe passen nicht zu mir.' }, + }, + }, + sexual_orientation: { + question: { de: 'Wie bezeichnest du deine sexuelle Orientierung?' }, + why: { de: 'Um die Probleme einer queeren Person vollständig nachvollziehen zu können, muss man queer sein. Daher sollten wir wissen, wie gut wir zu diesem Thema aufgestellt sind.' }, + type: 'radio', // 'chooser', + options: { + 'homosexual': { de: 'homosexuell / lesbisch / schwul / …' }, + 'interested_in_more_than_one_gender': { de: 'bisexuell / pansexuell / polysexuell / …' }, // {de: 'bisexuell / bi / ambisexuell / pansexuell / polysexuell / …'}, + 'queer': { de: 'queer' }, + 'asexual': { de: 'asexuell' }, + 'heterosexual': { de: 'heterosexuell / straight' }, + 'not_sure': { de: 'Ich bin mir nicht sicher.' }, + 'terms_dont_fit': { de: 'Diese Begriffe passen nicht zu mir.' }, + }, + }, + }, + }, + { + heading: { de: 'Diskriminierung' }, + // Diskriminierung sollte hinter LGBTQ* sein, da wir dort den Begriff "Gender" erklären. (EN: Discrimination should be after LGBTQ*, cause we teach the term "gender" in it.) + questions: { + discriminatory_experiences: { + question: { de: 'In welchen Bereichen hast du schonmal diskriminierende Erfahrungen gemacht?' }, + // why: {de: 'Hier mit möchten wir herrausfinden, wie privilegiert Volt Mitglieder sind.'}, + type: 'checkbox', + options: { + 'ancestry': { de: 'Ethnische Herkunft oder Hauttyp' }, + 'sex_or_gender': { de: 'Geschlecht oder Gender' }, + 'sexual_orientation': { de: 'Sexuelle Orientierung' }, + 'age': { de: 'Alter' }, + 'disabilities': { de: 'Behinderung oder chronische Krankheit' }, + 'ideology': { de: 'Religion oder Weltanschauung' }, + 'classism': { de: 'Vermögen oder sozialen Herkunft' }, + 'other': { de: 'andere Bereiche' }, + }, + }, + // discriminatory_experiences_within_volt: { + // question: {de: 'Hast diskriminierende Erfahrungen innerhalb von Volt gemacht?'}, + // // why: {de: 'Hier mit möchten wir herrausfinden, wie privilegiert Volt Mitglieder sind.'}, + // type: 'checkbox', + // options: { + // 'yes': {de: 'Ja'}, + // 'no': {de: 'Nein'}, + // }, + // }, + }, + }, + { + heading: { de: 'Psyche' }, + questions: { + psychological_difficulties: { + question: { de: 'Hast du (unabhängig von einer psychiatrischen Diagnose) mit anhaltenden oder immer wiederkehrenden psychischen Schwierigkeiten zu tun haben?' }, + why: { de: 'Unsere Reaktion auf, für uns ungewohntes Verhalten der Mitglieder.' }, + type: 'radio', + options: { + 'yes': { + de: 'Ja', + en: 'Yes', + }, + 'no': { + de: 'Nein', + en: 'No', + }, + } + }, + //introverted_or_extroverted: { + // question: {de: 'Bist du eher introvertiert oder extrovertiert?'}, + // why: {de: 'Wir müssen auch auf Mitglieder achten, die sich bei Diskussion nicht selbstständig durchsetzten? Oder denen viele Menschen ab und zu zuanstrengend sind.'}, + // type: 'radio', + // options: { + // 'more_introverted': {de: 'eher introvertiert'}, + // 'terms_dont_fit': {de: 'je nachdem / weder noch / kommt drauf an'}, + // 'more_extroverted': {de: 'eher extrovertiert'}, + // } + //}, + participating_in_offline_discussions: { + question: { de: 'Wie wohl würdest du dich fühlen, an einer Diskussion bei einer face-to-face Veranstaltung (z.B. einem Meet & Greet) teilzunehmen?' }, + why: { de: 'Wir müssen auch auf Mitglieder achten, die sich bei Diskussion nicht selbstständig durchsetzten, oder denen viele Menschen ab und zu zuanstrengend sind.' }, + type: 'radio', + options: { + '5': { de: 'Sehr wohl' }, + '4': { de: 'Eher wohl' }, // Einigermaßen wohl + '3': { de: 'Weder noch' }, + '2': { de: 'Eher unwohl' }, // Einigermaßen unwohl + '1': { de: 'Sehr unwohl' }, + } + }, + participating_in_online_discussions: { + question: { de: 'Wie wohl würdest du dich fühlen, an einer Diskussion auf Workplace (oder einem anderen Online-Tool) teilzunehmen?' }, + why: { de: '(Begründung, siehe vorherige Frage.)' }, + type: 'radio', + options: { + '5': { de: 'Sehr wohl' }, + '4': { de: 'Eher wohl' }, + '3': { de: 'Weder noch' }, + '2': { de: 'Eher unwohl' }, + '1': { de: 'Sehr unwohl' }, + } + }, + }, + }, + { + heading: { de: 'Hilfsmittel' }, + questions: { + everyday_aids: { + question: { de: 'Welche Hilfsmittel benötigst du im Alltag?' }, + why: { de: 'Erreichbarkeit und Verständigung bei den Events.' }, + type: 'checkbox', + options: { + 'wheelchair': { de: 'Rollstuhl' }, + 'walking_aid': { de: 'Rollator / Krücken / Gehstock / …' }, + 'hearing_aid': { de: 'Hörgerät / Mikrofon' }, + 'seeing_aid': { de: 'Brille / Lupe' }, + 'assistance': { de: 'Assistenz (Tier, Mensch oder Roboter)' }, + + 'prosthesis': { de: 'Prothese' }, + 'orthosis': { de: 'Orthese' }, + + 'other': { de: 'andere Hilfsmittel' }, // (Screenreader, Brailledisplay, …) + } + }, + financial_help: { + question: { de: 'Bekommst du finanzielle Hilfe. (Bafög, Hartz4, Jugendamt, …)' }, + why: { de: 'Je nach verfügbarer Geldmenge kann man einfacher an bestimmten Events teilnehmen.' }, + type: 'radio', + options: { + 'yes': { + de: 'Ja', + en: 'Yes', + }, + 'no': { + de: 'Nein', + en: 'No', + }, + } + }, + } + }, + { + heading: { de: 'Verbesserung der Umfrage' }, + intro: { de: 'Die ist unsere erste Umfrage dieser Art. Hier kannst du uns helfen diese weiter zu entwickeln …' }, + questions: { + text_whats_missing: { + question: { de: 'Welche Merkmale fehlen Deiner Meinung nach hier, sind aber aus Deiner Sicht für Diversität in Volt wichtig?' }, + // why: '', + info: { de: '(und sollten noch abgefragt werden)' }, + type: 'text', + }, + text_whats_to_much: { + question: { de: 'Welche Merkmale sollten wir künftig nicht mehr abfragen?' }, + // why: '(Hinweis: Alle Antworten sind freiwillig!)', + type: 'text', + }, + text_other_stuff: { + question: { de: 'Sonstige Anmerkungen?' }, + // why: '', + type: 'text', + }, + }, + }, + ], + countries: [ + // The List is from: https://volt.team/teams + + { title: 'Keine Angabe' }, + { disabled: true }, + { value: 'AUT', local_name: 'Österreich', en: 'Austria' }, + { value: 'BEL', local_name: 'Belgique / Belgie', en: 'Belgium' }, + { value: 'BGR', local_name: 'Bulgaria', en: 'Bulgaria' }, + { value: 'CYP', local_name: 'Kibris / Kypros', en: 'Cyprus' }, + { value: 'CZE', local_name: 'Ceska Republika', en: 'Czech Republic' }, + { value: 'DNK', local_name: 'Danmark', en: 'Denmark' }, + { value: 'DEU', local_name: 'Deutschland', en: 'Germany' }, + { value: 'EST', local_name: 'Eesti Vabariik', en: 'Estonia' }, + { value: 'IRL', local_name: 'Éire', en: 'Ireland' }, + { value: 'ESP', local_name: 'España', en: 'Spain' }, + { value: 'FRA', local_name: 'France', en: 'France' }, + { value: 'GRC', local_name: 'Ellas / Ellada', en: 'Greece' }, + { value: 'HRV', local_name: 'Hrvatska', en: 'Croatia' }, + { value: 'HUN', local_name: 'Magyarorszag', en: 'Hungary' }, + { value: 'ITA', local_name: 'Italia', en: 'Italy' }, + { value: 'LVA', local_name: 'Latvija', en: 'Latvia' }, + { value: 'LTU', local_name: 'Lietuva', en: 'Lithuania' }, + { value: 'LUX', local_name: 'Luxembourg / Letzebuerg', en: 'Luxembourg' }, + { value: 'MLT', local_name: 'Malta', en: 'Malta' }, + { value: 'NLD', local_name: 'Nederland / Holland', en: 'Netherlands' }, + { value: 'POL', local_name: 'Polska', en: 'Poland' }, + { value: 'PRT', local_name: 'Portugal', en: 'Portugal' }, + { value: 'ROU', local_name: 'Romania', en: 'Romania' }, + { value: 'SVK', local_name: 'Slovensko', en: 'Slovakia' }, + { value: 'SVN', local_name: 'Slovenija', en: 'Slovenia' }, + { value: 'FIN', local_name: 'Suomi', en: 'Finland' }, + { value: 'SWE', local_name: 'Sverige', en: 'Sweden' }, + { value: 'GBR', local_name: 'United Kingdom', en: 'United Kingdom' }, + + // Volt New Territories: + { disabled: true }, + { value: 'ALA', local_name: 'Landskapet Åland / Ahvenanmaan maakunta', en: 'Åland Islands' }, + { value: 'ALB', local_name: 'Shqiperia', en: 'Albania' }, + { value: 'AND', local_name: 'Andorra', en: 'Andorra' }, + { value: 'BIH', local_name: 'Bosna i Hercegovina', en: 'Bosnia and Herzegovina' }, + { value: 'FRO', local_name: 'Føroyar', en: 'Faroe Islands' }, + { value: 'GIB', local_name: 'Gibraltar', en: 'Gibraltar' }, + { value: 'GGY', local_name: 'Guernsey', en: 'Guernsey' }, + { value: 'ISL', local_name: 'Ísland', en: 'Iceland' }, + { value: 'IMN', local_name: 'Isle of Man', en: 'Isle of Man' }, + { value: 'JEY', local_name: 'Jersey', en: 'Jersey' }, + { value: 'LIE', local_name: 'Liechtenstein', en: 'Liechtenstein' }, + { value: 'MKD', local_name: 'Makedonija', en: 'Macedonia (FYROM)' }, + { value: 'MDA', local_name: 'Moldova', en: 'Moldova' }, + { value: 'MCO', local_name: 'Monaco', en: 'Monaco' }, + { value: 'MNE', local_name: 'Crna Gora', en: 'Montenegro' }, + { value: 'NOR', local_name: 'Norge', en: 'Norway' }, + { value: 'SMR', local_name: 'San Marino', en: 'San Marino' }, + { value: 'CHE', local_name: 'Schweiz / Suisse / Svizzera', en: 'Switzerland' }, + { value: 'BLR', local_name: 'Беларусь', en: 'Belarus' }, + { value: 'SRB', local_name: 'Србија', en: 'Serbia' }, + { value: 'UKR', local_name: 'Україна', en: 'Ukraine' }, + + { disabled: true }, + { value: 'Volt Abroad', title: 'Volt Abroad (Australia, Canada, Singapore, Thailand, Uruguay, USA, …)' }, + // TODO: Should there be an entry "Volt Europa"? + ] +} + +try { + if (!!module && module.exports) { + module.exports = _DATA_ + } +} catch (error) { + if (!!_DATA_GOT_LOADED) { + _DATA_GOT_LOADED() + } +} diff --git a/frontend/index.html b/frontend/index.html new file mode 100644 index 0000000..39d4a38 --- /dev/null +++ b/frontend/index.html @@ -0,0 +1,1578 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + Volt — Internal Diversity Survey + + + + + + + + + + + + + + +
+
+

+ + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + +

+

+ +
+
+

+ + +
+
+ + +
+
+ + + +
+
+

+ +
+
+

+


+ +

+

+


+ +

+
+
+

+
+
+ + +
+
+ + +
+
+ +
+ +
+ +
+ + + +
+

+

+

+
+
+
+ + + + + + + + + + + diff --git a/frontend/jsSHA/.gitignore b/frontend/jsSHA/.gitignore new file mode 100755 index 0000000..532b129 --- /dev/null +++ b/frontend/jsSHA/.gitignore @@ -0,0 +1,2 @@ +node_modules/ +*.pyc diff --git a/frontend/jsSHA/.npmignore b/frontend/jsSHA/.npmignore new file mode 100755 index 0000000..e04e7ce --- /dev/null +++ b/frontend/jsSHA/.npmignore @@ -0,0 +1,3 @@ +build +test +src/sha_dev.js diff --git a/frontend/jsSHA/.travis.yml b/frontend/jsSHA/.travis.yml new file mode 100755 index 0000000..12c4e53 --- /dev/null +++ b/frontend/jsSHA/.travis.yml @@ -0,0 +1,4 @@ +language: node_js +node_js: + - "node" + diff --git a/frontend/jsSHA/CHANGELOG.md b/frontend/jsSHA/CHANGELOG.md new file mode 100755 index 0000000..6067e51 --- /dev/null +++ b/frontend/jsSHA/CHANGELOG.md @@ -0,0 +1,164 @@ +jsSHA - ChangeLog +========================= + +2.3.1 (2017-06-10) +------------------------- +- Fix issue with SHA-3 and using a combination of TEXT/UTF-16 input + (thanks frostschutz!) + +2.3.0 (2017-05-13) +------------------------- +- Sped up SHA-3 implementation by adding little-endian capability to + conversion functions +- Further sped up SHA-3 implementation by decomposing xor\_64 function + (thanks frostschutz!) +- Fixed incorrect results when using ArrayBuffers (thanks conref!) +- Added externs/sha.js for Google Closure Compiler users (thanks IvanRF!) + +2.2.0 (2016-07-10) +------------------------- +- Added support for the SHA-3 family of hashes (SHA3-224, SHA3-256, + SHA3-384, SHA3-512, SHAKE128, and SHAKE256) +- Fixed bug with using ARRAYBUFFER as a HMAC key type +- Switched testing framework to Mocha and Chai + +2.1.0 (2016-05-13) +------------------------- +- Added ability to call `update` on hashes between `getHash` and `getHMAC` calls +- Added new input and output type, "ARRAYBUFFER" which is a JavaScript + ArrayBuffer +- Now keeping smaller build files in NPM (thanks vogievetsky!) +- Fixed problem with hashing strings over 4 billion bits (thanks Eicar!) + +2.0.2 (2015-10-31) +------------------------- +- Fixed inability to have a blank "b64Pad" (thanks xlc!) +- Added file hashing test (thanks kofalt!) + +2.0.1 (2015-06-25) +------------------------- +- Fixed major issue with all hashes failing if raw input was a particular size + (thanks treus!) + +2.0.0 (2015-06-13) +------------------------- +- Completely reworked API to support streaming inputs +- Exceptions now throw Errors instead of strings (thanks jclem!) + +1.6.1 (2015-06-25) +------------------------- +- Fixed issue with SHA-512 family of hashes failing is raw input was a + particular size + +1.6.0 (2015-03-08) +------------------------- +This marks the last v1.X new feature release. The API is changing +significantly with upcoming v2.0 to support streaming and it will be too +difficult to support the older API style with new features. + +- Added a BYTES input and output format that is a raw byte string +- Fixed broken AMD support (thanks drewcovi!) +- Fixed broken UTF-8 parsing on non-BMP Unicode characters +- Changed array references to remove warnings on Icedove +- Replaced "UTF16" encoding with "UTF16BE" (big endian) and "UTF16LE" (little + endian) to remove confusion + +1.5.1 (2013-12-15) +------------------------- +- Changed Google Closure Compiler options to produce "strict" compatible code + +1.5 (2013-12-15) +------------------------- +- Added optional numRounds argument to getHash + - Note: this necessitated removing the hash result caching functionality +- Reduced file size by optimizing internal constants +- Removed charSize input and replaced with encoding to handle Unicode. NOTE: + Only Code points up to 0xFFFF are supported. + - charSize = 16 is effectively replaced by encoding = "UTF16" + - charSize = 8 was wrong in terms of handling UTF-8 and has been replaced by + encoding = "UTF8" +- Changed method of referencing "window" to be compatible with WebWorkers, + Node.js, and AMD (thanks piranna!) + +1.42 (2012-12-28) +------------------------- +- Readded v1.4 Safari patch to support older versions + +1.41 (2012-12-23) +------------------------- +- Fixed incorrect hash issue with Chrome x64 v25 (Dev channel), also provides + stable patch to v1.4 Safari issue. + +1.4 (2012-12-08) +------------------------- +- Added new input type, TEXT, that is functionally identical to ASCII* +- Added new input type, B64, for base-64 encoded strings +- Added new input and output formatting parameters + - `getHash` and `getHMAC` take an optional parameter, outputFormatOpts, + that is a hash list containing the keys "outputUpper" (boolean, only + applicable to HEX output) and "b64Pad" (string, only applicable to Base-64 + output) that have default values of false and "=", respectively + - jsSHA constructor takes an optional parameter, charSize (8 or 16) that + specifies the character width of the input (TEXT and ASCII input only) +- Modified comments to be Google Closure Compiler compliant +- Added a SUPPORTED_ALGS flag that, when used with the Google Closure Compiler, + will remove unused functions/function portions + - Removed all src/*_nice.js files as the SUPPORTED_ALGS flag renders them + obsolete +- All production-ready files are now produced using the Google Closure Compiler + with ADVANCED_OPTIMIZATIONS resulting in further reduced filesizes +- The SHA-1 only implementation now requires that that "SHA-1" be specified as + the variant when using getHash and getHMAC +- Removed test/HMAC.py as new NIST tests made the need for it obsolete +- Significantly changed the test/test.html to make it easier to understand and + to allow for easier adding of test cases +- Replaced previous error returning code with thrown exceptions +- Fix for 64-bit Safari issue (thanks Ron Garret and Chris Warren-Smith!) + - NOTE: While this fix works, it is merely a workaround for a WebKit JavaScript + optimizer bug, see https://bugs.webkit.org/show_bug.cgi?id=88673 for more detail + +\* This library misused the term ASCII so input type of TEXT was added with the + intention of deprecating ASCII + +1.31 (2012-07-21) +------------------------- +- Updated project URL to point to new GitHub repository +- Added a compressed version of sha.js + +1.3 (2010-09-01) +------------------------- +- Changed method of declaring objects/classes +- Moved non-instance specific variables and methods to class scope +- Removed logically correct but unneeded conditionals + +1.2 (2009-07-22) +------------------------- +- Added the HMAC algorithm for all supported hashes (using both ASCII and hex + keys) +- As a result of adding HMAC, added support for hash input text to be hex + (ASCII representation of hex) +- Added multiple variants of safeAdd functions, resulting in a significant + performance gain +- Removed wrapper.js file +- Used a different JavaScript compressor resulting in smaller file sizes + +1.11 (2008-12-07) +------------------------- +- Fixed a base-64 encoding issue resulting from a missing capital 'X' + +1.1 (2008-09-25) +------------------------- +- Fixed an issue with incorrect hashes being generated when jsSHA ojbects were + used to generate multiple hashes + +1.0 (2008-09-25) +------------------------- +- Made all functions/variables follow an object-orientated methodology +- Removed support for string hash output as the hash is rarely ASCII friendly +- Changed the interface to calculate hashes (see README) +- Made sha.js validate against [JSLint](http://www.jslint.com/) using + "Recommended" settings + +0.1 (2008-02-21) +------------------------- +- Initial public release diff --git a/frontend/jsSHA/LICENSE b/frontend/jsSHA/LICENSE new file mode 100755 index 0000000..b7a6907 --- /dev/null +++ b/frontend/jsSHA/LICENSE @@ -0,0 +1,26 @@ +Copyright (c) 2008-2018 Brian Turek, 1998-2009 Paul Johnston & Contributors +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of the the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from this + software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + diff --git a/frontend/jsSHA/README.md b/frontend/jsSHA/README.md new file mode 100755 index 0000000..b49da5b --- /dev/null +++ b/frontend/jsSHA/README.md @@ -0,0 +1,125 @@ +# jsSHA +A pure JavaScript streaming implementation of the complete Secure Hash Standard +family (SHA-1, SHA-224, SHA3-224, SHA-256, SHA3-256, SHA-384, SHA3-384, SHA-512, +SHA3-512, SHAKE128, and SHAKE256) as well as HMAC. + +[![Build Status](https://travis-ci.org/Caligatio/jsSHA.svg?branch=master)](https://travis-ci.org/Caligatio/jsSHA) + +## Usage + +### Installation +#### Browser +Include the desired JavaScript file (sha.js, sha1.js, sha256.js, sha512.js, or +sha3.js) in your header (sha.js used below): + + + +#### Node.js +jsSHA is available through NPM and be installed by simply doing + + npm install jssha + +To use the module, first require it using: + + jsSHA = require("jssha"); + + +### Hashing +Instantiate a new jsSHA object with the desired hash type, input type, and +options as parameters. The hash type can be one of SHA-1, SHA-224, SHA3-224, +SHA-256, SHA3-256, SHA-384, SHA3-384, SHA-512, SHA3-512, SHAKE128, or SHAKE256. +The input type can be one of HEX, TEXT, B64, BYTES, or ARRAYBUFFER. You can +then stream in input using the `update` object function, calling it multiple +times if needed. Finally, simply call `getHash` with the output type as a +parameter (B64, HEX, BYTES, or ARRAYBUFFER). Example to calculate the SHA-512 +of "This is a test": + + var shaObj = new jsSHA("SHA-512", "TEXT"); + shaObj.update("This is a "); + shaObj.update("test"); + var hash = shaObj.getHash("HEX"); + +The constructor takes a hashmap as a optional third argument with possible +properties of `numRounds` and `encoding`. `numRounds` controls the number of +hashing iterations/rounds performed and defaults to a value of 1 if not +specified. `encoding` specifies the encoding used to encode TEXT-type inputs. +Valid options are "UTF8", "UTF16BE", and "UTF16LE", it defaults to "UTF8". + +`getHash` also takes a hashmap as an optional second argument. By default the +hashmap is `{"outputUpper" : false, "b64Pad" : "="}`. These options are +intelligently interpreted based upon the chosen output format. **Important**: +SHAKE128 and SHAKE256 require `shakeLen` to be included in the hashmap where +`shakeLen` is the desired output length of the SHAKE algorithm in a multiple +of 8 bits. + +### HMAC +Instantiate a new jsSHA object the same way as for hashing. Then set the HMAC +key to be used by calling `setHMACKey` with the key and its input type (this +MUST be done before calling update). You can stream in the input using the +`update` object function just like hashing. Finally, get the HMAC by calling +the `getHMAC` function with the output type as its argument. Example to +calculate the SHA-512 HMAC of the string "This is a test" with the key "abc": + + var shaObj = new jsSHA("SHA-512", "TEXT"); + shaObj.setHMACKey("abc", "TEXT"); + shaObj.update("This is a "); + shaObj.update("test"); + var hmac = shaObj.getHMAC("HEX"); + +`setHMACKey` takes the same input types as the constructor and `getHMAC` takes the +same inputs as `getHash` as described above. + +Note: You cannot calculate both the hash and HMAC using the same object. + +## Files +**src/sha\_dev.js** + +A commented implementation of the entire SHA family of hashes. Not to be used +in production. + +**src/sha.js** + +A Google Closure Compiler optimized version of the entire library. + +**src/sha1.js** + +A Google Closure Compiler optimized version the library with non SHA-1 +functionality removed. + +**src/sha256.js** + +A Google Closure Compiler optimized version the library with non SHA-224/SHA-256 +functionality removed. + +**src/sha3.js** + +A Google Closure Compiler optimized version the library with non SHA-3 +functionality removed. + +**src/sha512.js** + +A Google Closure Compiler optimized version the library with non SHA-384/SHA-512 +functionality removed. + +## Compiling +This library makes use of the [Google Closure Compiler](https://developers.google.com/closure/compiler) +to both boost performance and reduce filesizes. To compile sha\_dev.js into a customized output file, +use a command like the following: + + java -jar compiler.jar --define="SUPPORTED_ALGS=" \ + --externs /path/to/build/externs.js --warning_level VERBOSE \ + --compilation_level ADVANCED_OPTIMIZATIONS \ + --js /path/to/sha_dev.js --js_output_file /path/to/sha.js + +where FLAG is a bitwise OR of the following values: + +* 8 for SHA3 +* 4 for SHA-384/SHA-512 +* 2 for SHA-224/256 +* 1 for SHA-1 + +## Contact Info +The project's website is located at [https://caligatio.github.com/jsSHA/](https://caligatio.github.com/jsSHA/) + +## Donations +Feel like donating? We're now accepting donations through [Bitcoin](bitcoin:12VMZgRAP2jCP1YCR3vFNAtLR9MvzHzJZb?message=jsSHA%20Donation)! diff --git a/frontend/jsSHA/bower.json b/frontend/jsSHA/bower.json new file mode 100755 index 0000000..efd981a --- /dev/null +++ b/frontend/jsSHA/bower.json @@ -0,0 +1,51 @@ +{ + "name" : "jsSHA", + "version" : "2.3.1", + "description" : "jsSHA is a JavaScript implementation of the complete Secure Hash Standard family (SHA-1, SHA-224, SHA3-224, SHA-256, SHA3-256, SHA-384, SHA3-384, SHA-512, SHA3-512, SHAKE128, and SHAKE256) as well as HMAC", + "main" : "src/sha.js", + "repository" : { + "type" : "git", + "url" : "https://github.com/Caligatio/jsSHA.git" + }, + "keywords" : [ + "SHA-1", + "SHA-224", + "SHA3-224", + "SHA-256", + "SHA3-256", + "SHA-384", + "SHA3-384", + "SHA-512", + "SHA3-512", + "SHAKE-128", + "SHAKE-256", + "SHAKE128", + "SHAKE256", + "SHA1", + "SHA224", + "SHA256", + "SHA384", + "SHA512", + "SHA-2", + "SHA2", + "SHA-3", + "SHA3", + "SHAKE", + "HMAC", + "hash" + ], + "license" : "BSD-3-Clause", + "authors" : [ + "Brian Turek " + ], + "homepage" : "http://caligatio.github.com/jsSHA/", + "ignore": [ + "build", + "test", + "src/sha_dev.js" + ], + "devDependencies": { + "chai": "^3.5.0", + "mocha": "^2.5.3" + } +} diff --git a/frontend/jsSHA/build/externs.js b/frontend/jsSHA/build/externs.js new file mode 100755 index 0000000..cd26d0a --- /dev/null +++ b/frontend/jsSHA/build/externs.js @@ -0,0 +1,5 @@ +/* This file is needed so that the Google Closure Compiler does not complain + * about the module, define, and exports variables being undefined */ +var module = null; +var define = null; +var exports = null; diff --git a/frontend/jsSHA/build/make-release b/frontend/jsSHA/build/make-release new file mode 100755 index 0000000..fca720a --- /dev/null +++ b/frontend/jsSHA/build/make-release @@ -0,0 +1,10 @@ +#!/bin/bash + +declare -A releases +releases=(["sha"]=15 ["sha1"]=1 ["sha256"]=2 ["sha512"]=4 ["sha3"]=8) +CLOSURE_COMPILER=${CLOSURE_COMPILER-"../compiler.jar"} + +for i in "${!releases[@]}" +do + java -jar ${CLOSURE_COMPILER} --define="SUPPORTED_ALGS=${releases[$i]}" --externs externs.js --warning_level VERBOSE --compilation_level ADVANCED_OPTIMIZATIONS --language_in=ECMASCRIPT5_STRICT --js ../src/sha_dev.js --js_output_file ../src/$i.js +done diff --git a/frontend/jsSHA/externs/sha.js b/frontend/jsSHA/externs/sha.js new file mode 100755 index 0000000..56f30e1 --- /dev/null +++ b/frontend/jsSHA/externs/sha.js @@ -0,0 +1,49 @@ +/* + * Copyright 2017 Brian Turek, Ivan Ridao Freitas + * + * Distributed under the BSD License + * See http://caligatio.github.com/jsSHA/ for more information + */ + +/* + * Ensure projects don't execute this file. + */ +if (Math.random() < 1) { // always true but the compiler doesn't know that + throw 'Externs file "sha.js" should not be executed'; +} + + +/** + * @constructor + * @param {string} variant The desired SHA variant (SHA-1, SHA-224, SHA-256, SHA-384, SHA-512, SHA3-224, SHA3-256, SHA3-384, or SHA3-512) + * @param {string} inputFormat The format of srcString: HEX, TEXT, B64, BYTES, or ARRAYBUFFER + * @param {{encoding: (string|undefined), numRounds: (number|undefined)}=} options Optional values + * @return {!jsSHA} + */ +function jsSHA(variant, inputFormat, options) {}; + +/** + * @param {string|ArrayBuffer} key The key used to calculate the HMAC + * @param {string} inputFormat The format of key, HEX, TEXT, B64, BYTES, or ARRAYBUFFER + * @param {{encoding : (string|undefined)}=} options Associative array of input format options + */ +jsSHA.prototype.setHMACKey = function(key, inputFormat, options) {}; + +/** + * @param {string|ArrayBuffer} srcString The string to be hashed + */ +jsSHA.prototype.update = function(srcString) {}; + +/** + * @param {string} format The desired output formatting (B64, HEX, BYTES, or ARRAYBUFFER) + * @param {{outputUpper : (boolean|undefined), b64Pad : (string|undefined), shakeLen : (number|undefined)}=} options Hash list of output formatting options + * @return {string|ArrayBuffer} The string representation of the hash in the format specified. + */ +jsSHA.prototype.getHash = function(format, options) {}; + +/** + * @param {string} format The desired output formatting (B64, HEX, BYTES, or ARRAYBUFFER) + * @param {{outputUpper : (boolean|undefined), b64Pad : (string|undefined), shakeLen : (number|undefined)}=} options associative array of output formatting options + * @return {string|ArrayBuffer} The string representation of the hash in the format specified. + */ +jsSHA.prototype.getHMAC = function(format, options) {}; \ No newline at end of file diff --git a/frontend/jsSHA/package.json b/frontend/jsSHA/package.json new file mode 100755 index 0000000..e050c64 --- /dev/null +++ b/frontend/jsSHA/package.json @@ -0,0 +1,54 @@ +{ + "name": "jssha", + "version": "2.3.1", + "description": "jsSHA is a JavaScript implementation of the complete Secure Hash Standard family (SHA-1, SHA-224, SHA3-224, SHA-256, SHA3-256, SHA-384, SHA3-384, SHA-512, SHA3-512, SHAKE128, and SHAKE256) as well as HMAC", + "main": "src/sha.js", + "repository": { + "type": "git", + "url": "https://github.com/Caligatio/jsSHA.git" + }, + "keywords": [ + "SHA-1", + "SHA-224", + "SHA3-224", + "SHA-256", + "SHA3-256", + "SHA-384", + "SHA3-384", + "SHA-512", + "SHA3-512", + "SHAKE-128", + "SHAKE-256", + "SHAKE128", + "SHAKE256", + "SHA1", + "SHA224", + "SHA256", + "SHA384", + "SHA512", + "SHA-2", + "SHA2", + "SHA-3", + "SHA3", + "SHAKE", + "HMAC", + "hash" + ], + "license": "BSD-3-Clause", + "author": "Brian Turek ", + "bugs": { + "url": "https://github.com/Caligatio/jsSHA/issues" + }, + "engines": { + "node": "*" + }, + "homepage": "https://github.com/Caligatio/jsSHA", + "dependencies": {}, + "devDependencies": { + "chai": "^3.5.0", + "mocha": "^2.5.3" + }, + "scripts": { + "test": "mocha --reporter spec" + } +} diff --git a/frontend/jsSHA/src/sha.js b/frontend/jsSHA/src/sha.js new file mode 100755 index 0000000..1ecd2e5 --- /dev/null +++ b/frontend/jsSHA/src/sha.js @@ -0,0 +1,43 @@ +/* + A JavaScript implementation of the SHA family of hashes, as + defined in FIPS PUB 180-4 and FIPS PUB 202, as well as the corresponding + HMAC implementation as defined in FIPS PUB 198a + + Copyright 2008-2018 Brian Turek, 1998-2009 Paul Johnston & Contributors + Distributed under the BSD License + See http://caligatio.github.com/jsSHA/ for more information +*/ +'use strict';(function(Y){function C(c,a,b){var e=0,h=[],n=0,g,l,d,f,m,q,u,r,I=!1,v=[],w=[],t,y=!1,z=!1,x=-1;b=b||{};g=b.encoding||"UTF8";t=b.numRounds||1;if(t!==parseInt(t,10)||1>t)throw Error("numRounds must a integer >= 1");if("SHA-1"===c)m=512,q=K,u=Z,f=160,r=function(a){return a.slice()};else if(0===c.lastIndexOf("SHA-",0))if(q=function(a,b){return L(a,b,c)},u=function(a,b,h,e){var k,f;if("SHA-224"===c||"SHA-256"===c)k=(b+65>>>9<<4)+15,f=16;else if("SHA-384"===c||"SHA-512"===c)k=(b+129>>>10<< +5)+31,f=32;else throw Error("Unexpected error in SHA-2 implementation");for(;a.length<=k;)a.push(0);a[b>>>5]|=128<<24-b%32;b=b+h;a[k]=b&4294967295;a[k-1]=b/4294967296|0;h=a.length;for(b=0;be;e+=1)c[e]=a[e].slice();return c};x=1;if("SHA3-224"=== +c)m=1152,f=224;else if("SHA3-256"===c)m=1088,f=256;else if("SHA3-384"===c)m=832,f=384;else if("SHA3-512"===c)m=576,f=512;else if("SHAKE128"===c)m=1344,f=-1,F=31,z=!0;else if("SHAKE256"===c)m=1088,f=-1,F=31,z=!0;else throw Error("Chosen SHA variant is not supported");u=function(a,c,e,b,h){e=m;var k=F,f,g=[],n=e>>>5,l=0,d=c>>>5;for(f=0;f=e;f+=n)b=D(a.slice(f,f+n),b),c-=e;a=a.slice(f);for(c%=e;a.length>>3;a[f>>2]^=k<=h)break;g.push(a.a);l+=1;0===64*l%e&&D(null,b)}return g}}else throw Error("Chosen SHA variant is not supported");d=M(a,g,x);l=A(c);this.setHMACKey=function(a,b,h){var k;if(!0===I)throw Error("HMAC key already set");if(!0===y)throw Error("Cannot set HMAC key after calling update");if(!0===z)throw Error("SHAKE is not supported for HMAC");g=(h||{}).encoding||"UTF8";b=M(b,g,x)(a);a=b.binLen;b=b.value;k=m>>>3;h=k/4-1;if(ka/8){for(;b.length<=h;)b.push(0);b[h]&=4294967040}for(a=0;a<=h;a+=1)v[a]=b[a]^909522486,w[a]=b[a]^1549556828;l=q(v,l);e=m;I=!0};this.update=function(a){var c,b,k,f=0,g=m>>>5;c=d(a,h,n);a=c.binLen;b=c.value;c=a>>>5;for(k=0;k>>5);n=a%m;y=!0};this.getHash=function(a,b){var k,g,d,m;if(!0===I)throw Error("Cannot call getHash after setting HMAC key");d=N(b);if(!0===z){if(-1===d.shakeLen)throw Error("shakeLen must be specified in options"); +f=d.shakeLen}switch(a){case "HEX":k=function(a){return O(a,f,x,d)};break;case "B64":k=function(a){return P(a,f,x,d)};break;case "BYTES":k=function(a){return Q(a,f,x)};break;case "ARRAYBUFFER":try{g=new ArrayBuffer(0)}catch(p){throw Error("ARRAYBUFFER not supported by this environment");}k=function(a){return R(a,f,x)};break;default:throw Error("format must be HEX, B64, BYTES, or ARRAYBUFFER");}m=u(h.slice(),n,e,r(l),f);for(g=1;g>>24-f%32),m=u(m,f, +0,A(c),f);return k(m)};this.getHMAC=function(a,b){var k,g,d,p;if(!1===I)throw Error("Cannot call getHMAC without first setting HMAC key");d=N(b);switch(a){case "HEX":k=function(a){return O(a,f,x,d)};break;case "B64":k=function(a){return P(a,f,x,d)};break;case "BYTES":k=function(a){return Q(a,f,x)};break;case "ARRAYBUFFER":try{k=new ArrayBuffer(0)}catch(v){throw Error("ARRAYBUFFER not supported by this environment");}k=function(a){return R(a,f,x)};break;default:throw Error("outputFormat must be HEX, B64, BYTES, or ARRAYBUFFER"); +}g=u(h.slice(),n,e,r(l),f);p=q(w,A(c));p=u(g,f,m,p,f);return k(p)}}function b(c,a){this.a=c;this.b=a}function O(c,a,b,e){var h="";a/=8;var n,g,d;d=-1===b?3:0;for(n=0;n>>2]>>>8*(d+n%4*b),h+="0123456789abcdef".charAt(g>>>4&15)+"0123456789abcdef".charAt(g&15);return e.outputUpper?h.toUpperCase():h}function P(c,a,b,e){var h="",n=a/8,g,d,p,f;f=-1===b?3:0;for(g=0;g>>2]:0,p=g+2>>2]:0,p=(c[g>>>2]>>>8*(f+g%4*b)&255)<<16|(d>>>8*(f+(g+1)%4*b)&255)<<8|p>>>8*(f+ +(g+2)%4*b)&255,d=0;4>d;d+=1)8*g+6*d<=a?h+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(p>>>6*(3-d)&63):h+=e.b64Pad;return h}function Q(c,a,b){var e="";a/=8;var h,d,g;g=-1===b?3:0;for(h=0;h>>2]>>>8*(g+h%4*b)&255,e+=String.fromCharCode(d);return e}function R(c,a,b){a/=8;var e,h=new ArrayBuffer(a),d,g;g=new Uint8Array(h);d=-1===b?3:0;for(e=0;e>>2]>>>8*(d+e%4*b)&255;return h}function N(c){var a={outputUpper:!1,b64Pad:"=",shakeLen:-1};c=c||{}; +a.outputUpper=c.outputUpper||!1;!0===c.hasOwnProperty("b64Pad")&&(a.b64Pad=c.b64Pad);if(!0===c.hasOwnProperty("shakeLen")){if(0!==c.shakeLen%8)throw Error("shakeLen must be a multiple of 8");a.shakeLen=c.shakeLen}if("boolean"!==typeof a.outputUpper)throw Error("Invalid outputUpper formatting option");if("string"!==typeof a.b64Pad)throw Error("Invalid b64Pad formatting option");return a}function M(c,a,b){switch(a){case "UTF8":case "UTF16BE":case "UTF16LE":break;default:throw Error("encoding must be UTF8, UTF16BE, or UTF16LE"); +}switch(c){case "HEX":c=function(a,c,d){var g=a.length,l,p,f,m,q,u;if(0!==g%2)throw Error("String of HEX type must be in byte increments");c=c||[0];d=d||0;q=d>>>3;u=-1===b?3:0;for(l=0;l>>1)+q;for(f=m>>>2;c.length<=f;)c.push(0);c[f]|=p<<8*(u+m%4*b)}return{value:c,binLen:4*g+d}};break;case "TEXT":c=function(c,h,d){var g,l,p=0,f,m,q,u,r,t;h=h||[0];d=d||0;q=d>>>3;if("UTF8"===a)for(t=-1=== +b?3:0,f=0;fg?l.push(g):2048>g?(l.push(192|g>>>6),l.push(128|g&63)):55296>g||57344<=g?l.push(224|g>>>12,128|g>>>6&63,128|g&63):(f+=1,g=65536+((g&1023)<<10|c.charCodeAt(f)&1023),l.push(240|g>>>18,128|g>>>12&63,128|g>>>6&63,128|g&63)),m=0;m>>2;h.length<=u;)h.push(0);h[u]|=l[m]<<8*(t+r%4*b);p+=1}else if("UTF16BE"===a||"UTF16LE"===a)for(t=-1===b?2:0,l="UTF16LE"===a&&1!==b||"UTF16LE"!==a&&1===b,f=0;f>>8);r=p+q;for(u=r>>>2;h.length<=u;)h.push(0);h[u]|=g<<8*(t+r%4*b);p+=2}return{value:h,binLen:8*p+d}};break;case "B64":c=function(a,c,d){var g=0,l,p,f,m,q,u,r,t;if(-1===a.search(/^[a-zA-Z0-9=+\/]+$/))throw Error("Invalid character in base-64 string");p=a.indexOf("=");a=a.replace(/\=/g,"");if(-1!==p&&pv)throw Error("numRounds must a integer >= 1");if("SHA-1"===d)l=512,p=z,q=H,e=160,t=function(a){return a.slice()};else throw Error("Chosen SHA variant is not supported");k=A(b,g);m=x(d);this.setHMACKey=function(a,f,b){var c;if(!0===w)throw Error("HMAC key already set");if(!0===r)throw Error("Cannot set HMAC key after calling update"); +g=(b||{}).encoding||"UTF8";f=A(f,g)(a);a=f.binLen;f=f.value;c=l>>>3;b=c/4-1;if(ca/8){for(;f.length<=b;)f.push(0);f[b]&=4294967040}for(a=0;a<=b;a+=1)n[a]=f[a]^909522486,u[a]=f[a]^1549556828;m=p(n,m);h=l;w=!0};this.update=function(b){var e,g,c,d=0,q=l>>>5;e=k(b,a,f);b=e.binLen;g=e.value;e=b>>>5;for(c=0;c>>5);f=b%l;r=!0};this.getHash=function(b,g){var c,k,l,p;if(!0=== +w)throw Error("Cannot call getHash after setting HMAC key");l=B(g);switch(b){case "HEX":c=function(a){return C(a,e,l)};break;case "B64":c=function(a){return D(a,e,l)};break;case "BYTES":c=function(a){return E(a,e)};break;case "ARRAYBUFFER":try{k=new ArrayBuffer(0)}catch(I){throw Error("ARRAYBUFFER not supported by this environment");}c=function(a){return F(a,e)};break;default:throw Error("format must be HEX, B64, BYTES, or ARRAYBUFFER");}p=q(a.slice(),f,h,t(m),e);for(k=1;k>>2]>>>8*(3+a%4*-1),h+="0123456789abcdef".charAt(f>>>4&15)+"0123456789abcdef".charAt(f&15);return c.outputUpper?h.toUpperCase():h}function D(d,b,c){var h="",a=b/8,f,g,m;for(f=0;f>>2]:0,m=f+2>>2]:0,m=(d[f>>>2]>>>8*(3+f%4*-1)&255)<<16|(g>>>8*(3+(f+1)%4*-1)&255)<<8|m>>>8*(3+(f+2)%4*-1)&255,g=0;4>g;g+=1)8*f+6*g<=b?h+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(m>>> +6*(3-g)&63):h+=c.b64Pad;return h}function E(d,b){var c="",h=b/8,a,f;for(a=0;a>>2]>>>8*(3+a%4*-1)&255,c+=String.fromCharCode(f);return c}function F(d,b){var c=b/8,h,a=new ArrayBuffer(c),f;f=new Uint8Array(a);for(h=0;h>>2]>>>8*(3+h%4*-1)&255;return a}function B(d){var b={outputUpper:!1,b64Pad:"=",shakeLen:-1};d=d||{};b.outputUpper=d.outputUpper||!1;!0===d.hasOwnProperty("b64Pad")&&(b.b64Pad=d.b64Pad);if("boolean"!==typeof b.outputUpper)throw Error("Invalid outputUpper formatting option"); +if("string"!==typeof b.b64Pad)throw Error("Invalid b64Pad formatting option");return b}function A(d,b){var c;switch(b){case "UTF8":case "UTF16BE":case "UTF16LE":break;default:throw Error("encoding must be UTF8, UTF16BE, or UTF16LE");}switch(d){case "HEX":c=function(b,a,f){var g=b.length,c,d,e,l,p;if(0!==g%2)throw Error("String of HEX type must be in byte increments");a=a||[0];f=f||0;p=f>>>3;for(c=0;c>>1)+p;for(e=l>>>2;a.length<=e;)a.push(0);a[e]|=d<<8*(3+l%4*-1)}return{value:a,binLen:4*g+f}};break;case "TEXT":c=function(c,a,f){var g,d,k=0,e,l,p,q,t,n;a=a||[0];f=f||0;p=f>>>3;if("UTF8"===b)for(n=3,e=0;eg?d.push(g):2048>g?(d.push(192|g>>>6),d.push(128|g&63)):55296>g||57344<=g?d.push(224|g>>>12,128|g>>>6&63,128|g&63):(e+=1,g=65536+((g&1023)<<10|c.charCodeAt(e)&1023),d.push(240|g>>>18,128|g>>>12&63,128|g>>>6&63,128|g&63)),l=0;l>>2;a.length<=q;)a.push(0);a[q]|=d[l]<<8*(n+t%4*-1);k+=1}else if("UTF16BE"===b||"UTF16LE"===b)for(n=2,d="UTF16LE"===b&&!0||"UTF16LE"!==b&&!1,e=0;e>>8);t=k+p;for(q=t>>>2;a.length<=q;)a.push(0);a[q]|=g<<8*(n+t%4*-1);k+=2}return{value:a,binLen:8*k+f}};break;case "B64":c=function(b,a,f){var c=0,d,k,e,l,p,q,n;if(-1===b.search(/^[a-zA-Z0-9=+\/]+$/))throw Error("Invalid character in base-64 string");k=b.indexOf("=");b=b.replace(/\=/g, +"");if(-1!==k&&ku)throw Error("numRounds must a integer >= 1");if(0===c.lastIndexOf("SHA-",0))if(q=function(b,a){return A(b,a,c)},y=function(b,a,l,f){var g,e;if("SHA-224"===c||"SHA-256"===c)g=(a+65>>>9<<4)+15,e=16;else throw Error("Unexpected error in SHA-2 implementation");for(;b.length<=g;)b.push(0);b[a>>>5]|=128<<24-a%32;a=a+l;b[g]=a&4294967295; +b[g-1]=a/4294967296|0;l=b.length;for(a=0;a>>3;g=e/4-1;if(eb/8){for(;a.length<=g;)a.push(0);a[g]&=4294967040}for(b=0;b<=g;b+=1)t[b]=a[b]^909522486,r[b]=a[b]^1549556828;n=q(t,n);l=h;m=!0};this.update=function(a){var c,f,e,d=0,p=h>>>5;c=k(a,b,g);a=c.binLen;f=c.value;c=a>>>5;for(e=0;e>> +5);g=a%h;z=!0};this.getHash=function(a,f){var d,h,k,q;if(!0===m)throw Error("Cannot call getHash after setting HMAC key");k=C(f);switch(a){case "HEX":d=function(a){return D(a,e,k)};break;case "B64":d=function(a){return E(a,e,k)};break;case "BYTES":d=function(a){return F(a,e)};break;case "ARRAYBUFFER":try{h=new ArrayBuffer(0)}catch(v){throw Error("ARRAYBUFFER not supported by this environment");}d=function(a){return G(a,e)};break;default:throw Error("format must be HEX, B64, BYTES, or ARRAYBUFFER"); +}q=y(b.slice(),g,l,p(n));for(h=1;h>>2]>>>8*(3+b%4*-1),l+="0123456789abcdef".charAt(g>>>4&15)+"0123456789abcdef".charAt(g&15);return d.outputUpper?l.toUpperCase():l}function E(c,a,d){var l="",b=a/8,g,f,n;for(g=0;g>>2]:0,n=g+2>>2]:0,n=(c[g>>>2]>>>8*(3+g%4*-1)&255)<<16|(f>>>8*(3+(g+1)%4*-1)&255)<<8|n>>>8*(3+(g+2)%4*-1)&255,f=0;4>f;f+=1)8*g+6*f<=a?l+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(n>>> +6*(3-f)&63):l+=d.b64Pad;return l}function F(c,a){var d="",l=a/8,b,g;for(b=0;b>>2]>>>8*(3+b%4*-1)&255,d+=String.fromCharCode(g);return d}function G(c,a){var d=a/8,l,b=new ArrayBuffer(d),g;g=new Uint8Array(b);for(l=0;l>>2]>>>8*(3+l%4*-1)&255;return b}function C(c){var a={outputUpper:!1,b64Pad:"=",shakeLen:-1};c=c||{};a.outputUpper=c.outputUpper||!1;!0===c.hasOwnProperty("b64Pad")&&(a.b64Pad=c.b64Pad);if("boolean"!==typeof a.outputUpper)throw Error("Invalid outputUpper formatting option"); +if("string"!==typeof a.b64Pad)throw Error("Invalid b64Pad formatting option");return a}function B(c,a){var d;switch(a){case "UTF8":case "UTF16BE":case "UTF16LE":break;default:throw Error("encoding must be UTF8, UTF16BE, or UTF16LE");}switch(c){case "HEX":d=function(a,b,c){var f=a.length,d,k,e,h,q;if(0!==f%2)throw Error("String of HEX type must be in byte increments");b=b||[0];c=c||0;q=c>>>3;for(d=0;d>>1)+q;for(e=h>>>2;b.length<=e;)b.push(0);b[e]|=k<<8*(3+h%4*-1)}return{value:b,binLen:4*f+c}};break;case "TEXT":d=function(c,b,d){var f,n,k=0,e,h,q,m,p,r;b=b||[0];d=d||0;q=d>>>3;if("UTF8"===a)for(r=3,e=0;ef?n.push(f):2048>f?(n.push(192|f>>>6),n.push(128|f&63)):55296>f||57344<=f?n.push(224|f>>>12,128|f>>>6&63,128|f&63):(e+=1,f=65536+((f&1023)<<10|c.charCodeAt(e)&1023),n.push(240|f>>>18,128|f>>>12&63,128|f>>>6&63,128|f&63)),h=0;h>>2;b.length<=m;)b.push(0);b[m]|=n[h]<<8*(r+p%4*-1);k+=1}else if("UTF16BE"===a||"UTF16LE"===a)for(r=2,n="UTF16LE"===a&&!0||"UTF16LE"!==a&&!1,e=0;e>>8);p=k+q;for(m=p>>>2;b.length<=m;)b.push(0);b[m]|=f<<8*(r+p%4*-1);k+=2}return{value:b,binLen:8*k+d}};break;case "B64":d=function(a,b,c){var f=0,d,k,e,h,q,m,p;if(-1===a.search(/^[a-zA-Z0-9=+\/]+$/))throw Error("Invalid character in base-64 string");k=a.indexOf("=");a=a.replace(/\=/g, +"");if(-1!==k&&kw)throw Error("numRounds must a integer >= 1");if(0===d.lastIndexOf("SHA3-",0)||0===d.lastIndexOf("SHAKE",0)){var C=6;f=B;v=function(c){var a=[],e;for(e=0;5>e;e+=1)a[e]=c[e].slice();return a};t=1;if("SHA3-224"===d)k=1152,g=224;else if("SHA3-256"===d)k=1088,g=256;else if("SHA3-384"===d)k=832,g=384;else if("SHA3-512"===d)k= +576,g=512;else if("SHAKE128"===d)k=1344,g=-1,C=31,x=!0;else if("SHAKE256"===d)k=1088,g=-1,C=31,x=!0;else throw Error("Chosen SHA variant is not supported");p=function(c,a,e,g,d){e=k;var b=C,m,l=[],f=e>>>5,h=0,r=a>>>5;for(m=0;m=e;m+=f)g=B(c.slice(m,m+f),g),a-=e;c=c.slice(m);for(a%=e;c.length>>3;c[m>>2]^=b<=d)break;l.push(c.a);h+=1;0===64*h%e&&B(null,g)}return l}}else throw Error("Chosen SHA variant is not supported"); +r=D(b,e,t);m=y(d);this.setHMACKey=function(a,b,l){var h;if(!0===A)throw Error("HMAC key already set");if(!0===z)throw Error("Cannot set HMAC key after calling update");if(!0===x)throw Error("SHAKE is not supported for HMAC");e=(l||{}).encoding||"UTF8";b=D(b,e,t)(a);a=b.binLen;b=b.value;h=k>>>3;l=h/4-1;if(ha/8){for(;b.length<=l;)b.push(0);b[l]&=4294967040}for(a=0;a<=l;a+=1)n[a]=b[a]^909522486,u[a]=b[a]^1549556828;m=f(n,m); +c=k;A=!0};this.update=function(e){var b,g,d,h=0,p=k>>>5;b=r(e,a,l);e=b.binLen;g=b.value;b=e>>>5;for(d=0;d>>5);l=e%k;z=!0};this.getHash=function(e,b){var h,f,r,k;if(!0===A)throw Error("Cannot call getHash after setting HMAC key");r=E(b);if(!0===x){if(-1===r.shakeLen)throw Error("shakeLen must be specified in options");g=r.shakeLen}switch(e){case "HEX":h=function(a){return F(a,g,t,r)};break;case "B64":h=function(a){return G(a,g,t,r)};break; +case "BYTES":h=function(a){return H(a,g,t)};break;case "ARRAYBUFFER":try{f=new ArrayBuffer(0)}catch(q){throw Error("ARRAYBUFFER not supported by this environment");}h=function(a){return I(a,g,t)};break;default:throw Error("format must be HEX, B64, BYTES, or ARRAYBUFFER");}k=p(a.slice(),l,c,v(m),g);for(f=1;f>>24-g%32),k=p(k,g,0,y(d),g);return h(k)};this.getHMAC=function(e,b){var h,r,n,w;if(!1===A)throw Error("Cannot call getHMAC without first setting HMAC key"); +n=E(b);switch(e){case "HEX":h=function(a){return F(a,g,t,n)};break;case "B64":h=function(a){return G(a,g,t,n)};break;case "BYTES":h=function(a){return H(a,g,t)};break;case "ARRAYBUFFER":try{h=new ArrayBuffer(0)}catch(M){throw Error("ARRAYBUFFER not supported by this environment");}h=function(a){return I(a,g,t)};break;default:throw Error("outputFormat must be HEX, B64, BYTES, or ARRAYBUFFER");}r=p(a.slice(),l,c,v(m),g);w=f(u,y(d));w=p(r,g,k,w,g);return h(w)}}function f(d,b){this.a=d;this.b=b}function F(d, +b,h,c){var a="";b/=8;var l,e,m;m=-1===h?3:0;for(l=0;l>>2]>>>8*(m+l%4*h),a+="0123456789abcdef".charAt(e>>>4&15)+"0123456789abcdef".charAt(e&15);return c.outputUpper?a.toUpperCase():a}function G(d,b,h,c){var a="",l=b/8,e,m,f,g;g=-1===h?3:0;for(e=0;e>>2]:0,f=e+2>>2]:0,f=(d[e>>>2]>>>8*(g+e%4*h)&255)<<16|(m>>>8*(g+(e+1)%4*h)&255)<<8|f>>>8*(g+(e+2)%4*h)&255,m=0;4>m;m+=1)8*e+6*m<=b?a+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(f>>> +6*(3-m)&63):a+=c.b64Pad;return a}function H(d,b,h){var c="";b/=8;var a,l,e;e=-1===h?3:0;for(a=0;a>>2]>>>8*(e+a%4*h)&255,c+=String.fromCharCode(l);return c}function I(d,b,h){b/=8;var c,a=new ArrayBuffer(b),l,e;e=new Uint8Array(a);l=-1===h?3:0;for(c=0;c>>2]>>>8*(l+c%4*h)&255;return a}function E(d){var b={outputUpper:!1,b64Pad:"=",shakeLen:-1};d=d||{};b.outputUpper=d.outputUpper||!1;!0===d.hasOwnProperty("b64Pad")&&(b.b64Pad=d.b64Pad);if(!0===d.hasOwnProperty("shakeLen")){if(0!== +d.shakeLen%8)throw Error("shakeLen must be a multiple of 8");b.shakeLen=d.shakeLen}if("boolean"!==typeof b.outputUpper)throw Error("Invalid outputUpper formatting option");if("string"!==typeof b.b64Pad)throw Error("Invalid b64Pad formatting option");return b}function D(d,b,h){switch(b){case "UTF8":case "UTF16BE":case "UTF16LE":break;default:throw Error("encoding must be UTF8, UTF16BE, or UTF16LE");}switch(d){case "HEX":d=function(c,a,b){var e=c.length,d,f,g,k,q,p;if(0!==e%2)throw Error("String of HEX type must be in byte increments"); +a=a||[0];b=b||0;q=b>>>3;p=-1===h?3:0;for(d=0;d>>1)+q;for(g=k>>>2;a.length<=g;)a.push(0);a[g]|=f<<8*(p+k%4*h)}return{value:a,binLen:4*e+b}};break;case "TEXT":d=function(c,a,d){var e,m,f=0,g,k,q,p,v,n;a=a||[0];d=d||0;q=d>>>3;if("UTF8"===b)for(n=-1===h?3:0,g=0;ge?m.push(e):2048>e?(m.push(192|e>>>6),m.push(128|e&63)):55296>e||57344<=e?m.push(224| +e>>>12,128|e>>>6&63,128|e&63):(g+=1,e=65536+((e&1023)<<10|c.charCodeAt(g)&1023),m.push(240|e>>>18,128|e>>>12&63,128|e>>>6&63,128|e&63)),k=0;k>>2;a.length<=p;)a.push(0);a[p]|=m[k]<<8*(n+v%4*h);f+=1}else if("UTF16BE"===b||"UTF16LE"===b)for(n=-1===h?2:0,m="UTF16LE"===b&&1!==h||"UTF16LE"!==b&&1===h,g=0;g>>8);v=f+q;for(p=v>>>2;a.length<=p;)a.push(0);a[p]|=e<<8*(n+v%4*h);f+=2}return{value:a,binLen:8*f+d}};break;case "B64":d= +function(c,a,b){var e=0,d,f,g,k,q,p,n,u;if(-1===c.search(/^[a-zA-Z0-9=+\/]+$/))throw Error("Invalid character in base-64 string");f=c.indexOf("=");c=c.replace(/\=/g,"");if(-1!==f&&fv)throw Error("numRounds must a integer >= 1");if(0===b.lastIndexOf("SHA-",0))if(p=function(a,d){return B(a,d,b)},t=function(a,d,g,e){var c,k;if("SHA-384"===b||"SHA-512"===b)c=(d+129>>>10<<5)+31,k=32;else throw Error("Unexpected error in SHA-2 implementation");for(;a.length<=c;)a.push(0);a[d>>>5]|=128<<24-d%32;d=d+g;a[c]=d&4294967295; +a[c-1]=d/4294967296|0;g=a.length;for(d=0;d>>3;g=k/4-1;if(ka/8){for(;d.length<=g;)d.push(0);d[g]&=4294967040}for(a=0;a<=g;a+=1)u[a]=d[a]^909522486,r[a]=d[a]^1549556828;c=p(u,c);e=l;y= +!0};this.update=function(a){var d,b,n,f=0,h=l>>>5;d=m(a,g,k);a=d.binLen;b=d.value;d=a>>>5;for(n=0;n>>5);k=a%l;A=!0};this.getHash=function(a,d){var f,l,m,p;if(!0===y)throw Error("Cannot call getHash after setting HMAC key");m=D(d);switch(a){case "HEX":f=function(a){return E(a,h,m)};break;case "B64":f=function(a){return F(a,h,m)};break;case "BYTES":f=function(a){return G(a,h)};break;case "ARRAYBUFFER":try{l=new ArrayBuffer(0)}catch(w){throw Error("ARRAYBUFFER not supported by this environment"); +}f=function(a){return H(a,h)};break;default:throw Error("format must be HEX, B64, BYTES, or ARRAYBUFFER");}p=t(g.slice(),k,e,q(c));for(l=1;l>>2]>>>8*(3+g%4*-1),e+="0123456789abcdef".charAt(k>>>4&15)+"0123456789abcdef".charAt(k&15);return d.outputUpper?e.toUpperCase():e}function F(b,a,d){var e="",g=a/8,k,f,c;for(k=0;k>>2]:0,c=k+2>>2]: +0,c=(b[k>>>2]>>>8*(3+k%4*-1)&255)<<16|(f>>>8*(3+(k+1)%4*-1)&255)<<8|c>>>8*(3+(k+2)%4*-1)&255,f=0;4>f;f+=1)8*k+6*f<=a?e+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(c>>>6*(3-f)&63):e+=d.b64Pad;return e}function G(b,a){var d="",e=a/8,g,c;for(g=0;g>>2]>>>8*(3+g%4*-1)&255,d+=String.fromCharCode(c);return d}function H(b,a){var d=a/8,e,g=new ArrayBuffer(d),c;c=new Uint8Array(g);for(e=0;e>>2]>>>8*(3+e%4*-1)&255;return g}function D(b){var a={outputUpper:!1, +b64Pad:"=",shakeLen:-1};b=b||{};a.outputUpper=b.outputUpper||!1;!0===b.hasOwnProperty("b64Pad")&&(a.b64Pad=b.b64Pad);if("boolean"!==typeof a.outputUpper)throw Error("Invalid outputUpper formatting option");if("string"!==typeof a.b64Pad)throw Error("Invalid b64Pad formatting option");return a}function C(b,a){var d;switch(a){case "UTF8":case "UTF16BE":case "UTF16LE":break;default:throw Error("encoding must be UTF8, UTF16BE, or UTF16LE");}switch(b){case "HEX":d=function(a,b,d){var f=a.length,c,n,h,l, +p;if(0!==f%2)throw Error("String of HEX type must be in byte increments");b=b||[0];d=d||0;p=d>>>3;for(c=0;c>>1)+p;for(h=l>>>2;b.length<=h;)b.push(0);b[h]|=n<<8*(3+l%4*-1)}return{value:b,binLen:4*f+d}};break;case "TEXT":d=function(b,d,c){var f,n,m=0,h,l,p,t,q,r;d=d||[0];c=c||0;p=c>>>3;if("UTF8"===a)for(r=3,h=0;hf?n.push(f):2048>f?(n.push(192| +f>>>6),n.push(128|f&63)):55296>f||57344<=f?n.push(224|f>>>12,128|f>>>6&63,128|f&63):(h+=1,f=65536+((f&1023)<<10|b.charCodeAt(h)&1023),n.push(240|f>>>18,128|f>>>12&63,128|f>>>6&63,128|f&63)),l=0;l>>2;d.length<=t;)d.push(0);d[t]|=n[l]<<8*(r+q%4*-1);m+=1}else if("UTF16BE"===a||"UTF16LE"===a)for(r=2,n="UTF16LE"===a&&!0||"UTF16LE"!==a&&!1,h=0;h>>8);q=m+p;for(t=q>>>2;d.length<=t;)d.push(0);d[t]|=f<<8*(r+q%4*-1);m+= +2}return{value:d,binLen:8*m+c}};break;case "B64":d=function(a,b,d){var c=0,n,m,h,l,p,t,q;if(-1===a.search(/^[a-zA-Z0-9=+\/]+$/))throw Error("Invalid character in base-64 string");m=a.indexOf("=");a=a.replace(/\=/g,"");if(-1!==m&&m>> 3; + shiftModifier = (bigEndianMod === -1) ? 3 : 0; + + for (i = 0; i < str.length; i += 4) + { + strPart = str.substr(i, 4); + tmpInt = 0; + + for (j = 0; j < strPart.length; j += 1) + { + index = b64Tab.indexOf(strPart[j]); + tmpInt |= index << (18 - (6 * j)); + } + + for (j = 0; j < strPart.length - 1; j += 1) + { + byteOffset = byteCnt + existingByteLen; + intOffset = byteOffset >>> 2; + while (packed.length <= intOffset) + { + packed.push(0); + } + packed[intOffset] |= ((tmpInt >>> (16 - (j * 8))) & 0xFF) << + (8 * (shiftModifier + bigEndianMod * (byteOffset % 4))); + byteCnt += 1; + } + } + + return {"value" : packed, "binLen" : byteCnt * 8 + existingPackedLen}; + } + + /** + * Convert an ArrayBuffer to an array of big-endian words + * + * @private + * @param {ArrayBuffer} arr ArrayBuffer to be converted to binary + * representation + * @param {Array} existingPacked A packed int array of bytes to + * append the results to + * @param {number} existingPackedLen The number of bits in the existingPacked + * array + * @param {number} bigEndianMod Modifier for whether hash function is + * big or small endian + * @return {{value : Array, binLen : number}} Hash list where + * "value" contains the output number array and "binLen" is the binary + * length of "value" + */ + function arraybuffer2packed(arr, existingPacked, existingPackedLen, bigEndianMod) + { + var packed, i, existingByteLen, intOffset, byteOffset, shiftModifier, arrView; + + packed = existingPacked || [0]; + existingPackedLen = existingPackedLen || 0; + existingByteLen = existingPackedLen >>> 3; + shiftModifier = (bigEndianMod === -1) ? 3 : 0; + arrView = new Uint8Array(arr); + + for (i = 0; i < arr.byteLength; i += 1) + { + byteOffset = i + existingByteLen; + intOffset = byteOffset >>> 2; + if (packed.length <= intOffset) + { + packed.push(0); + } + packed[intOffset] |= arrView[i] << (8 * (shiftModifier + bigEndianMod * (byteOffset % 4))); + } + + return {"value" : packed, "binLen" : arr.byteLength * 8 + existingPackedLen}; + } + + /** + * Convert an array of big-endian words to a hex string. + * + * @private + * @param {Array} packed Array of integers to be converted to + * hexidecimal representation + * @param {number} outputLength Length of output in bits + * @param {number} bigEndianMod Modifier for whether hash function is + * big or small endian + * @param {{outputUpper : boolean, b64Pad : string}} formatOpts Hash list + * containing validated output formatting options + * @return {string} Hexidecimal representation of the parameter in string + * form + */ + function packed2hex(packed, outputLength, bigEndianMod, formatOpts) + { + var hex_tab = "0123456789abcdef", str = "", + length = outputLength / 8, i, srcByte, shiftModifier; + + shiftModifier = (bigEndianMod === -1) ? 3 : 0; + + for (i = 0; i < length; i += 1) + { + /* The below is more than a byte but it gets taken care of later */ + srcByte = packed[i >>> 2] >>> (8 * (shiftModifier + bigEndianMod * (i % 4))); + str += hex_tab.charAt((srcByte >>> 4) & 0xF) + + hex_tab.charAt(srcByte & 0xF); + } + + return (formatOpts["outputUpper"]) ? str.toUpperCase() : str; + } + + /** + * Convert an array of big-endian words to a base-64 string + * + * @private + * @param {Array} packed Array of integers to be converted to + * base-64 representation + * @param {number} outputLength Length of output in bits + * @param {number} bigEndianMod Modifier for whether hash function is + * big or small endian + * @param {{outputUpper : boolean, b64Pad : string}} formatOpts Hash list + * containing validated output formatting options + * @return {string} Base-64 encoded representation of the parameter in + * string form + */ + function packed2b64(packed, outputLength, bigEndianMod, formatOpts) + { + var str = "", length = outputLength / 8, i, j, triplet, int1, int2, shiftModifier, + b64Tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + + shiftModifier = (bigEndianMod === -1) ? 3 : 0; + + for (i = 0; i < length; i += 3) + { + int1 = ((i + 1) < length) ? packed[(i + 1) >>> 2] : 0; + int2 = ((i + 2) < length) ? packed[(i + 2) >>> 2] : 0; + triplet = (((packed[i >>> 2] >>> (8 * (shiftModifier + bigEndianMod * (i % 4)))) & 0xFF) << 16) | + (((int1 >>> (8 * (shiftModifier + bigEndianMod * ((i + 1) % 4)))) & 0xFF) << 8) | + ((int2 >>> (8 * (shiftModifier + bigEndianMod * ((i + 2) % 4)))) & 0xFF); + for (j = 0; j < 4; j += 1) + { + if (i * 8 + j * 6 <= outputLength) + { + str += b64Tab.charAt((triplet >>> 6 * (3 - j)) & 0x3F); + } + else + { + str += formatOpts["b64Pad"]; + } + } + } + return str; + } + + /** + * Convert an array of big-endian words to raw bytes string + * + * @private + * @param {Array} packed Array of integers to be converted to + * a raw bytes string representation + * @param {number} outputLength Length of output in bits + * @param {number} bigEndianMod Modifier for whether hash function is + * big or small endian + * @return {string} Raw bytes representation of the parameter in string + * form + */ + function packed2bytes(packed, outputLength, bigEndianMod) + { + var str = "", length = outputLength / 8, i, srcByte, shiftModifier; + + shiftModifier = (bigEndianMod === -1) ? 3 : 0; + + for (i = 0; i < length; i += 1) + { + srcByte = (packed[i >>> 2] >>> (8 * (shiftModifier + bigEndianMod * (i % 4)))) & 0xFF; + str += String.fromCharCode(srcByte); + } + + return str; + } + + /** + * Convert an array of big-endian words to an ArrayBuffer + * + * @private + * @param {Array} packed Array of integers to be converted to + * an ArrayBuffer + * @param {number} outputLength Length of output in bits + * @param {number} bigEndianMod Modifier for whether hash function is + * big or small endian + * @return {ArrayBuffer} Raw bytes representation of the parameter in an + * ArrayBuffer + */ + function packed2arraybuffer(packed, outputLength, bigEndianMod) + { + var length = outputLength / 8, i, retVal = new ArrayBuffer(length), shiftModifier, arrView; + arrView = new Uint8Array(retVal); + + shiftModifier = (bigEndianMod === -1) ? 3 : 0; + + for (i = 0; i < length; i += 1) + { + arrView[i] = (packed[i >>> 2] >>> (8 * (shiftModifier + bigEndianMod * (i % 4)))) & 0xFF; + } + + return retVal; + } + + /** + * Validate hash list containing output formatting options, ensuring + * presence of every option or adding the default value + * + * @private + * @param {{outputUpper : (boolean|undefined), b64Pad : (string|undefined), + * shakeLen : (number|undefined)}=} options Hash list of output formatting options + * @return {{outputUpper : boolean, b64Pad : string, shakeLen : number}} Validated + * hash list containing output formatting options + */ + function getOutputOpts(options) + { + var retVal = {"outputUpper" : false, "b64Pad" : "=", "shakeLen" : -1}, + outputOptions; + outputOptions = options || {}; + + retVal["outputUpper"] = outputOptions["outputUpper"] || false; + + if (true === outputOptions.hasOwnProperty("b64Pad")) + { + retVal["b64Pad"] = outputOptions["b64Pad"]; + } + + if ((true === outputOptions.hasOwnProperty("shakeLen")) && ((8 & SUPPORTED_ALGS) !== 0)) + { + if (outputOptions["shakeLen"] % 8 !== 0) + { + throw new Error("shakeLen must be a multiple of 8"); + } + retVal["shakeLen"] = outputOptions["shakeLen"]; + } + + if ("boolean" !== typeof(retVal["outputUpper"])) + { + throw new Error("Invalid outputUpper formatting option"); + } + + if ("string" !== typeof(retVal["b64Pad"])) + { + throw new Error("Invalid b64Pad formatting option"); + } + + return retVal; + } + + /** + * Function that takes an input format and UTF encoding and returns the + * appropriate function used to convert the input. + * + * @private + * @param {string} format The format of the string to be converted + * @param {string} utfType The string encoding to use (UTF8, UTF16BE, + * UTF16LE) + * @param {number} bigEndianMod Modifier for whether hash function is + * big or small endian + * @return {function((string|ArrayBuffer), Array=, number=): {value : + * Array, binLen : number}} Function that will convert an input + * string to a packed int array + */ + function getStrConverter(format, utfType, bigEndianMod) + { + var retVal; + + /* Validate encoding */ + switch (utfType) + { + case "UTF8": + /* Fallthrough */ + case "UTF16BE": + /* Fallthrough */ + case "UTF16LE": + /* Fallthrough */ + break; + default: + throw new Error("encoding must be UTF8, UTF16BE, or UTF16LE"); + } + + /* Map inputFormat to the appropriate converter */ + switch (format) + { + case "HEX": + /** + * @param {string} str String of raw bytes to be converted to binary representation + * @param {Array} existingBin A packed int array of bytes to + * append the results to + * @param {number} existingBinLen The number of bits in the existingBin + * array + * @return {{value : Array, binLen : number}} Hash list where + * "value" contains the output number array and "binLen" is the binary + * length of "value" + */ + retVal = function(str, existingBin, existingBinLen) + { + return hex2packed(str, existingBin, existingBinLen, bigEndianMod); + }; + break; + case "TEXT": + /** + * @param {string} str String of raw bytes to be converted to binary representation + * @param {Array} existingBin A packed int array of bytes to + * append the results to + * @param {number} existingBinLen The number of bits in the existingBin + * array + * @return {{value : Array, binLen : number}} Hash list where + * "value" contains the output number array and "binLen" is the binary + * length of "value" + */ + retVal = function(str, existingBin, existingBinLen) + { + return str2packed(str, utfType, existingBin, existingBinLen, bigEndianMod); + }; + break; + case "B64": + /** + * @param {string} str String of raw bytes to be converted to binary representation + * @param {Array} existingBin A packed int array of bytes to + * append the results to + * @param {number} existingBinLen The number of bits in the existingBin + * array + * @return {{value : Array, binLen : number}} Hash list where + * "value" contains the output number array and "binLen" is the binary + * length of "value" + */ + retVal = function(str, existingBin, existingBinLen) + { + return b642packed(str, existingBin, existingBinLen, bigEndianMod); + }; + break; + case "BYTES": + /** + * @param {string} str String of raw bytes to be converted to binary representation + * @param {Array} existingBin A packed int array of bytes to + * append the results to + * @param {number} existingBinLen The number of bits in the existingBin + * array + * @return {{value : Array, binLen : number}} Hash list where + * "value" contains the output number array and "binLen" is the binary + * length of "value" + */ + retVal = function(str, existingBin, existingBinLen) + { + return bytes2packed(str, existingBin, existingBinLen, bigEndianMod); + }; + break; + case "ARRAYBUFFER": + try { + retVal = new ArrayBuffer(0); + } catch(ignore) { + throw new Error("ARRAYBUFFER not supported by this environment"); + } + /** + * @param {ArrayBuffer} arr ArrayBuffer to be converted to binary + * representation + * @param {Array} existingBin A packed int array of bytes to + * append the results to + * @param {number} existingBinLen The number of bits in the existingBin + * array + * @return {{value : Array, binLen : number}} Hash list where + * "value" contains the output number array and "binLen" is the binary + * length of "value" + */ + retVal = function(arr, existingBin, existingBinLen) + { + return arraybuffer2packed(arr, existingBin, existingBinLen, bigEndianMod); + }; + break; + default: + throw new Error("format must be HEX, TEXT, B64, BYTES, or ARRAYBUFFER"); + } + + return retVal; + } + + /** + * The 32-bit implementation of circular rotate left + * + * @private + * @param {number} x The 32-bit integer argument + * @param {number} n The number of bits to shift + * @return {number} The x shifted circularly by n bits + */ + function rotl_32(x, n) + { + return (x << n) | (x >>> (32 - n)); + } + + /** + * The 64-bit implementation of circular rotate left + * + * @private + * @param {Int_64} x The 64-bit integer argument + * @param {number} n The number of bits to shift + * @return {Int_64} The x shifted circularly by n bits + */ + function rotl_64(x, n) + { + if (n > 32) + { + n = n - 32; + return new Int_64( + x.lowOrder << n | x.highOrder >>> (32 - n), + x.highOrder << n | x.lowOrder >>> (32 - n) + ); + } + else if (0 !== n) + { + return new Int_64( + x.highOrder << n | x.lowOrder >>> (32 - n), + x.lowOrder << n | x.highOrder >>> (32 - n) + ); + } + else + { + return x; + } + } + + /** + * The 32-bit implementation of circular rotate right + * + * @private + * @param {number} x The 32-bit integer argument + * @param {number} n The number of bits to shift + * @return {number} The x shifted circularly by n bits + */ + function rotr_32(x, n) + { + return (x >>> n) | (x << (32 - n)); + } + + /** + * The 64-bit implementation of circular rotate right + * + * @private + * @param {Int_64} x The 64-bit integer argument + * @param {number} n The number of bits to shift + * @return {Int_64} The x shifted circularly by n bits + */ + function rotr_64(x, n) + { + var retVal = null, tmp = new Int_64(x.highOrder, x.lowOrder); + + if (32 >= n) + { + retVal = new Int_64( + (tmp.highOrder >>> n) | ((tmp.lowOrder << (32 - n)) & 0xFFFFFFFF), + (tmp.lowOrder >>> n) | ((tmp.highOrder << (32 - n)) & 0xFFFFFFFF) + ); + } + else + { + retVal = new Int_64( + (tmp.lowOrder >>> (n - 32)) | ((tmp.highOrder << (64 - n)) & 0xFFFFFFFF), + (tmp.highOrder >>> (n - 32)) | ((tmp.lowOrder << (64 - n)) & 0xFFFFFFFF) + ); + } + + return retVal; + } + + /** + * The 32-bit implementation of shift right + * + * @private + * @param {number} x The 32-bit integer argument + * @param {number} n The number of bits to shift + * @return {number} The x shifted by n bits + */ + function shr_32(x, n) + { + return x >>> n; + } + + /** + * The 64-bit implementation of shift right + * + * @private + * @param {Int_64} x The 64-bit integer argument + * @param {number} n The number of bits to shift + * @return {Int_64} The x shifted by n bits + */ + function shr_64(x, n) + { + var retVal = null; + + if (32 >= n) + { + retVal = new Int_64( + x.highOrder >>> n, + x.lowOrder >>> n | ((x.highOrder << (32 - n)) & 0xFFFFFFFF) + ); + } + else + { + retVal = new Int_64( + 0, + x.highOrder >>> (n - 32) + ); + } + + return retVal; + } + + /** + * The 32-bit implementation of the NIST specified Parity function + * + * @private + * @param {number} x The first 32-bit integer argument + * @param {number} y The second 32-bit integer argument + * @param {number} z The third 32-bit integer argument + * @return {number} The NIST specified output of the function + */ + function parity_32(x, y, z) + { + return x ^ y ^ z; + } + + /** + * The 32-bit implementation of the NIST specified Ch function + * + * @private + * @param {number} x The first 32-bit integer argument + * @param {number} y The second 32-bit integer argument + * @param {number} z The third 32-bit integer argument + * @return {number} The NIST specified output of the function + */ + function ch_32(x, y, z) + { + return (x & y) ^ (~x & z); + } + + /** + * The 64-bit implementation of the NIST specified Ch function + * + * @private + * @param {Int_64} x The first 64-bit integer argument + * @param {Int_64} y The second 64-bit integer argument + * @param {Int_64} z The third 64-bit integer argument + * @return {Int_64} The NIST specified output of the function + */ + function ch_64(x, y, z) + { + return new Int_64( + (x.highOrder & y.highOrder) ^ (~x.highOrder & z.highOrder), + (x.lowOrder & y.lowOrder) ^ (~x.lowOrder & z.lowOrder) + ); + } + + /** + * The 32-bit implementation of the NIST specified Maj function + * + * @private + * @param {number} x The first 32-bit integer argument + * @param {number} y The second 32-bit integer argument + * @param {number} z The third 32-bit integer argument + * @return {number} The NIST specified output of the function + */ + function maj_32(x, y, z) + { + return (x & y) ^ (x & z) ^ (y & z); + } + + /** + * The 64-bit implementation of the NIST specified Maj function + * + * @private + * @param {Int_64} x The first 64-bit integer argument + * @param {Int_64} y The second 64-bit integer argument + * @param {Int_64} z The third 64-bit integer argument + * @return {Int_64} The NIST specified output of the function + */ + function maj_64(x, y, z) + { + return new Int_64( + (x.highOrder & y.highOrder) ^ + (x.highOrder & z.highOrder) ^ + (y.highOrder & z.highOrder), + (x.lowOrder & y.lowOrder) ^ + (x.lowOrder & z.lowOrder) ^ + (y.lowOrder & z.lowOrder) + ); + } + + /** + * The 32-bit implementation of the NIST specified Sigma0 function + * + * @private + * @param {number} x The 32-bit integer argument + * @return {number} The NIST specified output of the function + */ + function sigma0_32(x) + { + return rotr_32(x, 2) ^ rotr_32(x, 13) ^ rotr_32(x, 22); + } + + /** + * The 64-bit implementation of the NIST specified Sigma0 function + * + * @private + * @param {Int_64} x The 64-bit integer argument + * @return {Int_64} The NIST specified output of the function + */ + function sigma0_64(x) + { + var rotr28 = rotr_64(x, 28), rotr34 = rotr_64(x, 34), + rotr39 = rotr_64(x, 39); + + return new Int_64( + rotr28.highOrder ^ rotr34.highOrder ^ rotr39.highOrder, + rotr28.lowOrder ^ rotr34.lowOrder ^ rotr39.lowOrder); + } + + /** + * The 32-bit implementation of the NIST specified Sigma1 function + * + * @private + * @param {number} x The 32-bit integer argument + * @return {number} The NIST specified output of the function + */ + function sigma1_32(x) + { + return rotr_32(x, 6) ^ rotr_32(x, 11) ^ rotr_32(x, 25); + } + + /** + * The 64-bit implementation of the NIST specified Sigma1 function + * + * @private + * @param {Int_64} x The 64-bit integer argument + * @return {Int_64} The NIST specified output of the function + */ + function sigma1_64(x) + { + var rotr14 = rotr_64(x, 14), rotr18 = rotr_64(x, 18), + rotr41 = rotr_64(x, 41); + + return new Int_64( + rotr14.highOrder ^ rotr18.highOrder ^ rotr41.highOrder, + rotr14.lowOrder ^ rotr18.lowOrder ^ rotr41.lowOrder); + } + + /** + * The 32-bit implementation of the NIST specified Gamma0 function + * + * @private + * @param {number} x The 32-bit integer argument + * @return {number} The NIST specified output of the function + */ + function gamma0_32(x) + { + return rotr_32(x, 7) ^ rotr_32(x, 18) ^ shr_32(x, 3); + } + + /** + * The 64-bit implementation of the NIST specified Gamma0 function + * + * @private + * @param {Int_64} x The 64-bit integer argument + * @return {Int_64} The NIST specified output of the function + */ + function gamma0_64(x) + { + var rotr1 = rotr_64(x, 1), rotr8 = rotr_64(x, 8), shr7 = shr_64(x, 7); + + return new Int_64( + rotr1.highOrder ^ rotr8.highOrder ^ shr7.highOrder, + rotr1.lowOrder ^ rotr8.lowOrder ^ shr7.lowOrder + ); + } + + /** + * The 32-bit implementation of the NIST specified Gamma1 function + * + * @private + * @param {number} x The 32-bit integer argument + * @return {number} The NIST specified output of the function + */ + function gamma1_32(x) + { + return rotr_32(x, 17) ^ rotr_32(x, 19) ^ shr_32(x, 10); + } + + /** + * The 64-bit implementation of the NIST specified Gamma1 function + * + * @private + * @param {Int_64} x The 64-bit integer argument + * @return {Int_64} The NIST specified output of the function + */ + function gamma1_64(x) + { + var rotr19 = rotr_64(x, 19), rotr61 = rotr_64(x, 61), + shr6 = shr_64(x, 6); + + return new Int_64( + rotr19.highOrder ^ rotr61.highOrder ^ shr6.highOrder, + rotr19.lowOrder ^ rotr61.lowOrder ^ shr6.lowOrder + ); + } + + /** + * Add two 32-bit integers, wrapping at 2^32. This uses 16-bit operations + * internally to work around bugs in some JS interpreters. + * + * @private + * @param {number} a The first 32-bit integer argument to be added + * @param {number} b The second 32-bit integer argument to be added + * @return {number} The sum of a + b + */ + function safeAdd_32_2(a, b) + { + var lsw = (a & 0xFFFF) + (b & 0xFFFF), + msw = (a >>> 16) + (b >>> 16) + (lsw >>> 16); + + return ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF); + } + + /** + * Add four 32-bit integers, wrapping at 2^32. This uses 16-bit operations + * internally to work around bugs in some JS interpreters. + * + * @private + * @param {number} a The first 32-bit integer argument to be added + * @param {number} b The second 32-bit integer argument to be added + * @param {number} c The third 32-bit integer argument to be added + * @param {number} d The fourth 32-bit integer argument to be added + * @return {number} The sum of a + b + c + d + */ + function safeAdd_32_4(a, b, c, d) + { + var lsw = (a & 0xFFFF) + (b & 0xFFFF) + (c & 0xFFFF) + (d & 0xFFFF), + msw = (a >>> 16) + (b >>> 16) + (c >>> 16) + (d >>> 16) + + (lsw >>> 16); + + return ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF); + } + + /** + * Add five 32-bit integers, wrapping at 2^32. This uses 16-bit operations + * internally to work around bugs in some JS interpreters. + * + * @private + * @param {number} a The first 32-bit integer argument to be added + * @param {number} b The second 32-bit integer argument to be added + * @param {number} c The third 32-bit integer argument to be added + * @param {number} d The fourth 32-bit integer argument to be added + * @param {number} e The fifth 32-bit integer argument to be added + * @return {number} The sum of a + b + c + d + e + */ + function safeAdd_32_5(a, b, c, d, e) + { + var lsw = (a & 0xFFFF) + (b & 0xFFFF) + (c & 0xFFFF) + (d & 0xFFFF) + + (e & 0xFFFF), + msw = (a >>> 16) + (b >>> 16) + (c >>> 16) + (d >>> 16) + + (e >>> 16) + (lsw >>> 16); + + return ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF); + } + + /** + * Add two 64-bit integers, wrapping at 2^64. This uses 16-bit operations + * internally to work around bugs in some JS interpreters. + * + * @private + * @param {Int_64} x The first 64-bit integer argument to be added + * @param {Int_64} y The second 64-bit integer argument to be added + * @return {Int_64} The sum of x + y + */ + function safeAdd_64_2(x, y) + { + var lsw, msw, lowOrder, highOrder; + + lsw = (x.lowOrder & 0xFFFF) + (y.lowOrder & 0xFFFF); + msw = (x.lowOrder >>> 16) + (y.lowOrder >>> 16) + (lsw >>> 16); + lowOrder = ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF); + + lsw = (x.highOrder & 0xFFFF) + (y.highOrder & 0xFFFF) + (msw >>> 16); + msw = (x.highOrder >>> 16) + (y.highOrder >>> 16) + (lsw >>> 16); + highOrder = ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF); + + return new Int_64(highOrder, lowOrder); + } + + /** + * Add four 64-bit integers, wrapping at 2^64. This uses 16-bit operations + * internally to work around bugs in some JS interpreters. + * + * @private + * @param {Int_64} a The first 64-bit integer argument to be added + * @param {Int_64} b The second 64-bit integer argument to be added + * @param {Int_64} c The third 64-bit integer argument to be added + * @param {Int_64} d The fouth 64-bit integer argument to be added + * @return {Int_64} The sum of a + b + c + d + */ + function safeAdd_64_4(a, b, c, d) + { + var lsw, msw, lowOrder, highOrder; + + lsw = (a.lowOrder & 0xFFFF) + (b.lowOrder & 0xFFFF) + + (c.lowOrder & 0xFFFF) + (d.lowOrder & 0xFFFF); + msw = (a.lowOrder >>> 16) + (b.lowOrder >>> 16) + + (c.lowOrder >>> 16) + (d.lowOrder >>> 16) + (lsw >>> 16); + lowOrder = ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF); + + lsw = (a.highOrder & 0xFFFF) + (b.highOrder & 0xFFFF) + + (c.highOrder & 0xFFFF) + (d.highOrder & 0xFFFF) + (msw >>> 16); + msw = (a.highOrder >>> 16) + (b.highOrder >>> 16) + + (c.highOrder >>> 16) + (d.highOrder >>> 16) + (lsw >>> 16); + highOrder = ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF); + + return new Int_64(highOrder, lowOrder); + } + + /** + * Add five 64-bit integers, wrapping at 2^64. This uses 16-bit operations + * internally to work around bugs in some JS interpreters. + * + * @private + * @param {Int_64} a The first 64-bit integer argument to be added + * @param {Int_64} b The second 64-bit integer argument to be added + * @param {Int_64} c The third 64-bit integer argument to be added + * @param {Int_64} d The fouth 64-bit integer argument to be added + * @param {Int_64} e The fouth 64-bit integer argument to be added + * @return {Int_64} The sum of a + b + c + d + e + */ + function safeAdd_64_5(a, b, c, d, e) + { + var lsw, msw, lowOrder, highOrder; + + lsw = (a.lowOrder & 0xFFFF) + (b.lowOrder & 0xFFFF) + + (c.lowOrder & 0xFFFF) + (d.lowOrder & 0xFFFF) + + (e.lowOrder & 0xFFFF); + msw = (a.lowOrder >>> 16) + (b.lowOrder >>> 16) + + (c.lowOrder >>> 16) + (d.lowOrder >>> 16) + (e.lowOrder >>> 16) + + (lsw >>> 16); + lowOrder = ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF); + + lsw = (a.highOrder & 0xFFFF) + (b.highOrder & 0xFFFF) + + (c.highOrder & 0xFFFF) + (d.highOrder & 0xFFFF) + + (e.highOrder & 0xFFFF) + (msw >>> 16); + msw = (a.highOrder >>> 16) + (b.highOrder >>> 16) + + (c.highOrder >>> 16) + (d.highOrder >>> 16) + + (e.highOrder >>> 16) + (lsw >>> 16); + highOrder = ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF); + + return new Int_64(highOrder, lowOrder); + } + + /** + * XORs two given arguments. + * + * @private + * @param {Int_64} a First argument to be XORed + * @param {Int_64} b Second argument to be XORed + * @return {Int_64} The XOR of the arguments + */ + function xor_64_2(a, b) + { + return new Int_64( + a.highOrder ^ b.highOrder, + a.lowOrder ^ b.lowOrder + ); + } + + /** + * XORs five given arguments. + * + * @private + * @param {Int_64} a First argument to be XORed + * @param {Int_64} b Second argument to be XORed + * @param {Int_64} c Third argument to be XORed + * @param {Int_64} d Fourth argument to be XORed + * @param {Int_64} e Fifth argument to be XORed + * @return {Int_64} The XOR of the arguments + */ + function xor_64_5(a, b, c, d, e) + { + return new Int_64( + a.highOrder ^ b.highOrder ^ c.highOrder ^ d.highOrder ^ e.highOrder, + a.lowOrder ^ b.lowOrder ^ c.lowOrder ^ d.lowOrder ^ e.lowOrder + ); + } + + /** + * Returns a clone of the given SHA3 state + * + * @private + * @param {Array>} state The state to be cloned + * @return {Array>} The cloned state + */ + function cloneSHA3State(state) { + var clone = [], i; + for (i = 0; i < 5; i += 1) + { + clone[i] = state[i].slice(); + } + + return clone; + } + + /** + * Gets the state values for the specified SHA variant + * + * @param {string} variant The SHA variant + * @return {Array>} The initial state values + */ + function getNewState(variant) + { + var retVal = [], H_trunc, H_full, i; + + if (("SHA-1" === variant) && ((1 & SUPPORTED_ALGS) !== 0)) + { + retVal = [ + 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 + ]; + } + else if ((variant.lastIndexOf("SHA-", 0) === 0) && ((6 & SUPPORTED_ALGS) !== 0)) + { + H_trunc = [ + 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, + 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4 + ]; + H_full = [ + 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, + 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19 + ]; + + switch (variant) + { + case "SHA-224": + retVal = H_trunc; + break; + case "SHA-256": + retVal = H_full; + break; + case "SHA-384": + retVal = [ + new Int_64(0xcbbb9d5d, H_trunc[0]), + new Int_64(0x0629a292a, H_trunc[1]), + new Int_64(0x9159015a, H_trunc[2]), + new Int_64(0x0152fecd8, H_trunc[3]), + new Int_64(0x67332667, H_trunc[4]), + new Int_64(0x98eb44a87, H_trunc[5]), + new Int_64(0xdb0c2e0d, H_trunc[6]), + new Int_64(0x047b5481d, H_trunc[7]) + ]; + break; + case "SHA-512": + retVal = [ + new Int_64(H_full[0], 0xf3bcc908), + new Int_64(H_full[1], 0x84caa73b), + new Int_64(H_full[2], 0xfe94f82b), + new Int_64(H_full[3], 0x5f1d36f1), + new Int_64(H_full[4], 0xade682d1), + new Int_64(H_full[5], 0x2b3e6c1f), + new Int_64(H_full[6], 0xfb41bd6b), + new Int_64(H_full[7], 0x137e2179) + ]; + break; + default: + throw new Error("Unknown SHA variant"); + } + } + else if (((variant.lastIndexOf("SHA3-", 0) === 0) || (variant.lastIndexOf("SHAKE", 0) === 0)) && + ((8 & SUPPORTED_ALGS) !== 0)) + { + for (i = 0; i < 5; i += 1) + { + retVal[i] = [new Int_64(0, 0), new Int_64(0, 0), new Int_64(0, 0), new Int_64(0, 0), new Int_64(0, 0)]; + } + } + else + { + throw new Error("No SHA variants supported"); + } + + return retVal; + } + + /** + * Performs a round of SHA-1 hashing over a 512-byte block + * + * @private + * @param {Array} block The binary array representation of the + * block to hash + * @param {Array} H The intermediate H values from a previous + * round + * @return {Array} The resulting H values + */ + function roundSHA1(block, H) + { + var W = [], a, b, c, d, e, T, ch = ch_32, parity = parity_32, + maj = maj_32, rotl = rotl_32, safeAdd_2 = safeAdd_32_2, t, + safeAdd_5 = safeAdd_32_5; + + a = H[0]; + b = H[1]; + c = H[2]; + d = H[3]; + e = H[4]; + + for (t = 0; t < 80; t += 1) + { + if (t < 16) + { + W[t] = block[t]; + } + else + { + W[t] = rotl(W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16], 1); + } + + if (t < 20) + { + T = safeAdd_5(rotl(a, 5), ch(b, c, d), e, 0x5a827999, W[t]); + } + else if (t < 40) + { + T = safeAdd_5(rotl(a, 5), parity(b, c, d), e, 0x6ed9eba1, W[t]); + } + else if (t < 60) + { + T = safeAdd_5(rotl(a, 5), maj(b, c, d), e, 0x8f1bbcdc, W[t]); + } else { + T = safeAdd_5(rotl(a, 5), parity(b, c, d), e, 0xca62c1d6, W[t]); + } + + e = d; + d = c; + c = rotl(b, 30); + b = a; + a = T; + } + + H[0] = safeAdd_2(a, H[0]); + H[1] = safeAdd_2(b, H[1]); + H[2] = safeAdd_2(c, H[2]); + H[3] = safeAdd_2(d, H[3]); + H[4] = safeAdd_2(e, H[4]); + + return H; + } + + /** + * Finalizes the SHA-1 hash + * + * @private + * @param {Array} remainder Any leftover unprocessed packed ints + * that still need to be processed + * @param {number} remainderBinLen The number of bits in remainder + * @param {number} processedBinLen The number of bits already + * processed + * @param {Array} H The intermediate H values from a previous + * round + * @param {number} outputLen Unused for this variant + * @return {Array} The array of integers representing the SHA-1 + * hash of message + */ + function finalizeSHA1(remainder, remainderBinLen, processedBinLen, H, outputLen) + { + var i, appendedMessageLength, offset, totalLen; + + /* The 65 addition is a hack but it works. The correct number is + actually 72 (64 + 8) but the below math fails if + remainderBinLen + 72 % 512 = 0. Since remainderBinLen % 8 = 0, + "shorting" the addition is OK. */ + offset = (((remainderBinLen + 65) >>> 9) << 4) + 15; + while (remainder.length <= offset) + { + remainder.push(0); + } + /* Append '1' at the end of the binary string */ + remainder[remainderBinLen >>> 5] |= 0x80 << (24 - (remainderBinLen % 32)); + /* Append length of binary string in the position such that the new + * length is a multiple of 512. Logic does not work for even multiples + * of 512 but there can never be even multiples of 512. JavaScript + * numbers are limited to 2^53 so it's "safe" to treat the totalLen as + * a 64-bit integer. */ + totalLen = remainderBinLen + processedBinLen; + remainder[offset] = totalLen & 0xFFFFFFFF; + /* Bitwise operators treat the operand as a 32-bit number so need to + * use hacky division and round to get access to upper 32-ish bits */ + remainder[offset - 1] = (totalLen / TWO_PWR_32) | 0; + + appendedMessageLength = remainder.length; + + /* This will always be at least 1 full chunk */ + for (i = 0; i < appendedMessageLength; i += 16) + { + H = roundSHA1(remainder.slice(i, i + 16), H); + } + + return H; + } + + /* Put this here so the K arrays aren't put on the stack for every block */ + var K_sha2, K_sha512, r_sha3, rc_sha3; + if ((6 & SUPPORTED_ALGS) !== 0) + { + K_sha2 = [ + 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, + 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5, + 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3, + 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174, + 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC, + 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA, + 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, + 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967, + 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13, + 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85, + 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3, + 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070, + 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, + 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3, + 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208, + 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2 + ]; + + if ((4 & SUPPORTED_ALGS) !== 0) + { + K_sha512 = [ + new Int_64(K_sha2[ 0], 0xd728ae22), new Int_64(K_sha2[ 1], 0x23ef65cd), + new Int_64(K_sha2[ 2], 0xec4d3b2f), new Int_64(K_sha2[ 3], 0x8189dbbc), + new Int_64(K_sha2[ 4], 0xf348b538), new Int_64(K_sha2[ 5], 0xb605d019), + new Int_64(K_sha2[ 6], 0xaf194f9b), new Int_64(K_sha2[ 7], 0xda6d8118), + new Int_64(K_sha2[ 8], 0xa3030242), new Int_64(K_sha2[ 9], 0x45706fbe), + new Int_64(K_sha2[10], 0x4ee4b28c), new Int_64(K_sha2[11], 0xd5ffb4e2), + new Int_64(K_sha2[12], 0xf27b896f), new Int_64(K_sha2[13], 0x3b1696b1), + new Int_64(K_sha2[14], 0x25c71235), new Int_64(K_sha2[15], 0xcf692694), + new Int_64(K_sha2[16], 0x9ef14ad2), new Int_64(K_sha2[17], 0x384f25e3), + new Int_64(K_sha2[18], 0x8b8cd5b5), new Int_64(K_sha2[19], 0x77ac9c65), + new Int_64(K_sha2[20], 0x592b0275), new Int_64(K_sha2[21], 0x6ea6e483), + new Int_64(K_sha2[22], 0xbd41fbd4), new Int_64(K_sha2[23], 0x831153b5), + new Int_64(K_sha2[24], 0xee66dfab), new Int_64(K_sha2[25], 0x2db43210), + new Int_64(K_sha2[26], 0x98fb213f), new Int_64(K_sha2[27], 0xbeef0ee4), + new Int_64(K_sha2[28], 0x3da88fc2), new Int_64(K_sha2[29], 0x930aa725), + new Int_64(K_sha2[30], 0xe003826f), new Int_64(K_sha2[31], 0x0a0e6e70), + new Int_64(K_sha2[32], 0x46d22ffc), new Int_64(K_sha2[33], 0x5c26c926), + new Int_64(K_sha2[34], 0x5ac42aed), new Int_64(K_sha2[35], 0x9d95b3df), + new Int_64(K_sha2[36], 0x8baf63de), new Int_64(K_sha2[37], 0x3c77b2a8), + new Int_64(K_sha2[38], 0x47edaee6), new Int_64(K_sha2[39], 0x1482353b), + new Int_64(K_sha2[40], 0x4cf10364), new Int_64(K_sha2[41], 0xbc423001), + new Int_64(K_sha2[42], 0xd0f89791), new Int_64(K_sha2[43], 0x0654be30), + new Int_64(K_sha2[44], 0xd6ef5218), new Int_64(K_sha2[45], 0x5565a910), + new Int_64(K_sha2[46], 0x5771202a), new Int_64(K_sha2[47], 0x32bbd1b8), + new Int_64(K_sha2[48], 0xb8d2d0c8), new Int_64(K_sha2[49], 0x5141ab53), + new Int_64(K_sha2[50], 0xdf8eeb99), new Int_64(K_sha2[51], 0xe19b48a8), + new Int_64(K_sha2[52], 0xc5c95a63), new Int_64(K_sha2[53], 0xe3418acb), + new Int_64(K_sha2[54], 0x7763e373), new Int_64(K_sha2[55], 0xd6b2b8a3), + new Int_64(K_sha2[56], 0x5defb2fc), new Int_64(K_sha2[57], 0x43172f60), + new Int_64(K_sha2[58], 0xa1f0ab72), new Int_64(K_sha2[59], 0x1a6439ec), + new Int_64(K_sha2[60], 0x23631e28), new Int_64(K_sha2[61], 0xde82bde9), + new Int_64(K_sha2[62], 0xb2c67915), new Int_64(K_sha2[63], 0xe372532b), + new Int_64(0xca273ece, 0xea26619c), new Int_64(0xd186b8c7, 0x21c0c207), + new Int_64(0xeada7dd6, 0xcde0eb1e), new Int_64(0xf57d4f7f, 0xee6ed178), + new Int_64(0x06f067aa, 0x72176fba), new Int_64(0x0a637dc5, 0xa2c898a6), + new Int_64(0x113f9804, 0xbef90dae), new Int_64(0x1b710b35, 0x131c471b), + new Int_64(0x28db77f5, 0x23047d84), new Int_64(0x32caab7b, 0x40c72493), + new Int_64(0x3c9ebe0a, 0x15c9bebc), new Int_64(0x431d67c4, 0x9c100d4c), + new Int_64(0x4cc5d4be, 0xcb3e42b6), new Int_64(0x597f299c, 0xfc657e2a), + new Int_64(0x5fcb6fab, 0x3ad6faec), new Int_64(0x6c44198c, 0x4a475817) + ]; + } + } + if ((8 & SUPPORTED_ALGS) !== 0) + { + rc_sha3 = [ + new Int_64(0x00000000, 0x00000001), new Int_64(0x00000000, 0x00008082), + new Int_64(0x80000000, 0x0000808A), new Int_64(0x80000000, 0x80008000), + new Int_64(0x00000000, 0x0000808B), new Int_64(0x00000000, 0x80000001), + new Int_64(0x80000000, 0x80008081), new Int_64(0x80000000, 0x00008009), + new Int_64(0x00000000, 0x0000008A), new Int_64(0x00000000, 0x00000088), + new Int_64(0x00000000, 0x80008009), new Int_64(0x00000000, 0x8000000A), + new Int_64(0x00000000, 0x8000808B), new Int_64(0x80000000, 0x0000008B), + new Int_64(0x80000000, 0x00008089), new Int_64(0x80000000, 0x00008003), + new Int_64(0x80000000, 0x00008002), new Int_64(0x80000000, 0x00000080), + new Int_64(0x00000000, 0x0000800A), new Int_64(0x80000000, 0x8000000A), + new Int_64(0x80000000, 0x80008081), new Int_64(0x80000000, 0x00008080), + new Int_64(0x00000000, 0x80000001), new Int_64(0x80000000, 0x80008008) + ]; + + r_sha3 = [ + [ 0, 36, 3, 41, 18], + [ 1, 44, 10, 45, 2], + [62, 6, 43, 15, 61], + [28, 55, 25, 21, 56], + [27, 20, 39, 8, 14] + ]; + } + + /** + * Performs a round of SHA-2 hashing over a block + * + * @private + * @param {Array} block The binary array representation of the + * block to hash + * @param {Array} H The intermediate H values from a previous + * round + * @param {string} variant The desired SHA-2 variant + * @return {Array} The resulting H values + */ + function roundSHA2(block, H, variant) + { + var a, b, c, d, e, f, g, h, T1, T2, numRounds, t, binaryStringMult, + safeAdd_2, safeAdd_4, safeAdd_5, gamma0, gamma1, sigma0, sigma1, + ch, maj, Int, W = [], int1, int2, offset, K; + + /* Set up the various function handles and variable for the specific + * variant */ + if ((variant === "SHA-224" || variant === "SHA-256") && + ((2 & SUPPORTED_ALGS) !== 0)) + { + /* 32-bit variant */ + numRounds = 64; + binaryStringMult = 1; + Int = Number; + safeAdd_2 = safeAdd_32_2; + safeAdd_4 = safeAdd_32_4; + safeAdd_5 = safeAdd_32_5; + gamma0 = gamma0_32; + gamma1 = gamma1_32; + sigma0 = sigma0_32; + sigma1 = sigma1_32; + maj = maj_32; + ch = ch_32; + K = K_sha2; + } + else if ((variant === "SHA-384" || variant === "SHA-512") && + ((4 & SUPPORTED_ALGS) !== 0)) + { + /* 64-bit variant */ + numRounds = 80; + binaryStringMult = 2; + Int = Int_64; + safeAdd_2 = safeAdd_64_2; + safeAdd_4 = safeAdd_64_4; + safeAdd_5 = safeAdd_64_5; + gamma0 = gamma0_64; + gamma1 = gamma1_64; + sigma0 = sigma0_64; + sigma1 = sigma1_64; + maj = maj_64; + ch = ch_64; + K = K_sha512; + } + else + { + throw new Error("Unexpected error in SHA-2 implementation"); + } + + a = H[0]; + b = H[1]; + c = H[2]; + d = H[3]; + e = H[4]; + f = H[5]; + g = H[6]; + h = H[7]; + + for (t = 0; t < numRounds; t += 1) + { + if (t < 16) + { + offset = t * binaryStringMult; + int1 = (block.length <= offset) ? 0 : block[offset]; + int2 = (block.length <= offset + 1) ? 0 : block[offset + 1]; + /* Bit of a hack - for 32-bit, the second term is ignored */ + W[t] = new Int(int1, int2); + } + else + { + W[t] = safeAdd_4( + gamma1(W[t - 2]), W[t - 7], + gamma0(W[t - 15]), W[t - 16] + ); + } + + T1 = safeAdd_5(h, sigma1(e), ch(e, f, g), K[t], W[t]); + T2 = safeAdd_2(sigma0(a), maj(a, b, c)); + h = g; + g = f; + f = e; + e = safeAdd_2(d, T1); + d = c; + c = b; + b = a; + a = safeAdd_2(T1, T2); + } + + H[0] = safeAdd_2(a, H[0]); + H[1] = safeAdd_2(b, H[1]); + H[2] = safeAdd_2(c, H[2]); + H[3] = safeAdd_2(d, H[3]); + H[4] = safeAdd_2(e, H[4]); + H[5] = safeAdd_2(f, H[5]); + H[6] = safeAdd_2(g, H[6]); + H[7] = safeAdd_2(h, H[7]); + + return H; + } + + /** + * Finalizes the SHA-2 hash + * + * @private + * @param {Array} remainder Any leftover unprocessed packed ints + * that still need to be processed + * @param {number} remainderBinLen The number of bits in remainder + * @param {number} processedBinLen The number of bits already + * processed + * @param {Array} H The intermediate H values from a previous + * round + * @param {string} variant The desired SHA-2 variant + * @param {number} outputLen Unused for this variant + * @return {Array} The array of integers representing the SHA-2 + * hash of message + */ + function finalizeSHA2(remainder, remainderBinLen, processedBinLen, H, variant, outputLen) + { + var i, appendedMessageLength, offset, retVal, binaryStringInc, totalLen; + + if ((variant === "SHA-224" || variant === "SHA-256") && + ((2 & SUPPORTED_ALGS) !== 0)) + { + /* 32-bit variant */ + /* The 65 addition is a hack but it works. The correct number is + actually 72 (64 + 8) but the below math fails if + remainderBinLen + 72 % 512 = 0. Since remainderBinLen % 8 = 0, + "shorting" the addition is OK. */ + offset = (((remainderBinLen + 65) >>> 9) << 4) + 15; + binaryStringInc = 16; + } + else if ((variant === "SHA-384" || variant === "SHA-512") && + ((4 & SUPPORTED_ALGS) !== 0)) + { + /* 64-bit variant */ + /* The 129 addition is a hack but it works. The correct number is + actually 136 (128 + 8) but the below math fails if + remainderBinLen + 136 % 1024 = 0. Since remainderBinLen % 8 = 0, + "shorting" the addition is OK. */ + offset = (((remainderBinLen + 129) >>> 10) << 5) + 31; + binaryStringInc = 32; + } + else + { + throw new Error("Unexpected error in SHA-2 implementation"); + } + + while (remainder.length <= offset) + { + remainder.push(0); + } + /* Append '1' at the end of the binary string */ + remainder[remainderBinLen >>> 5] |= 0x80 << (24 - remainderBinLen % 32); + /* Append length of binary string in the position such that the new + * length is correct. JavaScript numbers are limited to 2^53 so it's + * "safe" to treat the totalLen as a 64-bit integer. */ + totalLen = remainderBinLen + processedBinLen; + remainder[offset] = totalLen & 0xFFFFFFFF; + /* Bitwise operators treat the operand as a 32-bit number so need to + * use hacky division and round to get access to upper 32-ish bits */ + remainder[offset - 1] = (totalLen / TWO_PWR_32) | 0; + + appendedMessageLength = remainder.length; + + /* This will always be at least 1 full chunk */ + for (i = 0; i < appendedMessageLength; i += binaryStringInc) + { + H = roundSHA2(remainder.slice(i, i + binaryStringInc), H, variant); + } + + if (("SHA-224" === variant) && ((2 & SUPPORTED_ALGS) !== 0)) + { + retVal = [ + H[0], H[1], H[2], H[3], + H[4], H[5], H[6] + ]; + } + else if (("SHA-256" === variant) && ((2 & SUPPORTED_ALGS) !== 0)) + { + retVal = H; + } + else if (("SHA-384" === variant) && ((4 & SUPPORTED_ALGS) !== 0)) + { + retVal = [ + H[0].highOrder, H[0].lowOrder, + H[1].highOrder, H[1].lowOrder, + H[2].highOrder, H[2].lowOrder, + H[3].highOrder, H[3].lowOrder, + H[4].highOrder, H[4].lowOrder, + H[5].highOrder, H[5].lowOrder + ]; + } + else if (("SHA-512" === variant) && ((4 & SUPPORTED_ALGS) !== 0)) + { + retVal = [ + H[0].highOrder, H[0].lowOrder, + H[1].highOrder, H[1].lowOrder, + H[2].highOrder, H[2].lowOrder, + H[3].highOrder, H[3].lowOrder, + H[4].highOrder, H[4].lowOrder, + H[5].highOrder, H[5].lowOrder, + H[6].highOrder, H[6].lowOrder, + H[7].highOrder, H[7].lowOrder + ]; + } + else /* This should never be reached */ + { + throw new Error("Unexpected error in SHA-2 implementation"); + } + + return retVal; + } + + /** + * Performs a round of SHA-3 hashing over a block + * + * @private + * @param {Array|null} block The binary array representation of the + * block to hash + * @param {Array>} state The binary array representation of the + * block to hash + * @return {Array>} The resulting state value + */ + function roundSHA3(block, state) + { + var round, x, y, B, C = [], D = []; + + if (null !== block) + { + for (x = 0; x < block.length; x+=2) + { + state[(x >>> 1) % 5][((x >>> 1) / 5) | 0] = xor_64_2( + state[(x >>> 1) % 5][((x >>> 1) / 5) | 0], + new Int_64(block[x + 1], block[x]) + ); + } + } + + for (round = 0; round < 24; round += 1) + { + /* getNewState doesn't care about variant beyond SHA3 so feed it a + value that triggers the getNewState "if" statement + */ + B = getNewState("SHA3-"); + + /* Perform theta step */ + for (x = 0; x < 5; x += 1) + { + C[x] = xor_64_5(state[x][0], state[x][1], state[x][2], + state[x][3], state[x][4]); + } + for (x = 0; x < 5; x += 1) + { + D[x] = xor_64_2(C[(x + 4) % 5], rotl_64(C[(x + 1) % 5], 1)); + } + for (x = 0; x < 5; x += 1) + { + for (y = 0; y < 5; y += 1) + { + state[x][y] = xor_64_2(state[x][y], D[x]); + } + } + + /* Perform combined ro and pi steps */ + for (x = 0; x < 5; x += 1) + { + for (y = 0; y < 5; y += 1) + { + B[y][(2 * x + 3 * y) % 5] = rotl_64( + state[x][y], + r_sha3[x][y] + ); + } + } + + /* Perform chi step */ + for (x = 0; x < 5; x += 1) + { + for (y = 0; y < 5; y += 1) + { + state[x][y] = xor_64_2( + B[x][y], + new Int_64( + ~(B[(x + 1) % 5][y].highOrder) & B[(x + 2) % 5][y].highOrder, + ~(B[(x + 1) % 5][y].lowOrder) & B[(x + 2) % 5][y].lowOrder + ) + ); + } + } + + /* Perform iota step */ + state[0][0] = xor_64_2(state[0][0], rc_sha3[round]); + } + + return state; + } + + /** + * Finalizes the SHA-3 hash + * + * @private + * @param {Array} remainder Any leftover unprocessed packed ints + * that still need to be processed + * @param {number} remainderBinLen The number of bits in remainder + * @param {number} processedBinLen The number of bits already + * processed + * @param {Array>} state The state from a previous round + * @param {number} blockSize The block size/rate of the variant in bits + * @param {number} delimiter The delimiter value for the variant + * @param {number} outputLen The output length for the variant in bits + * @return {Array} The array of integers representing the SHA-3 + * hash of message + */ + function finalizeSHA3(remainder, remainderBinLen, processedBinLen, state, blockSize, delimiter, outputLen) + { + var i, retVal = [], binaryStringInc = blockSize >>> 5, state_offset = 0, + remainderIntLen = remainderBinLen >>> 5, temp; + + + /* Process as many blocks as possible, some may be here for multiple rounds + with SHAKE + */ + for (i = 0; i < remainderIntLen && remainderBinLen >= blockSize; i += binaryStringInc) + { + state = roundSHA3(remainder.slice(i, i + binaryStringInc), state); + remainderBinLen -= blockSize; + } + + remainder = remainder.slice(i); + remainderBinLen = remainderBinLen % blockSize; + + /* Pad out the remainder to a full block */ + while (remainder.length < binaryStringInc) + { + remainder.push(0); + } + + /* Find the next "empty" byte for the 0x80 and append it via an xor */ + i = remainderBinLen >>> 3; + remainder[i >> 2] ^= delimiter << (8 * (i % 4)); + + remainder[binaryStringInc - 1] ^= 0x80000000; + state = roundSHA3(remainder, state); + + while (retVal.length * 32 < outputLen) + { + temp = state[state_offset % 5][(state_offset / 5) | 0]; + retVal.push(temp.lowOrder); + if (retVal.length * 32 >= outputLen) + { + break; + } + retVal.push(temp.highOrder); + state_offset += 1; + + if (0 === ((state_offset * 64) % blockSize)) + { + roundSHA3(null, state); + } + } + + return retVal; + } + + /** + * jsSHA is the workhorse of the library. Instantiate it with the string to + * be hashed as the parameter + * + * @constructor + * @this {jsSHA} + * @param {string} variant The desired SHA variant (SHA-1, SHA-224, SHA-256, + * SHA-384, SHA-512, SHA3-224, SHA3-256, SHA3-384, or SHA3-512) + * @param {string} inputFormat The format of srcString: HEX, TEXT, B64, + * BYTES, or ARRAYBUFFER + * @param {{encoding: (string|undefined), numRounds: (number|undefined)}=} + * options Optional values + */ + var jsSHA = function(variant, inputFormat, options) + { + var processedLen = 0, remainder = [], remainderLen = 0, utfType, + intermediateState, converterFunc, shaVariant = variant, outputBinLen, + variantBlockSize, roundFunc, finalizeFunc, stateCloneFunc, + hmacKeySet = false, keyWithIPad = [], keyWithOPad = [], numRounds, + updatedCalled = false, inputOptions, isSHAKE = false, bigEndianMod = -1; + + inputOptions = options || {}; + utfType = inputOptions["encoding"] || "UTF8"; + numRounds = inputOptions["numRounds"] || 1; + + if ((numRounds !== parseInt(numRounds, 10)) || (1 > numRounds)) + { + throw new Error("numRounds must a integer >= 1"); + } + + if (("SHA-1" === shaVariant) && ((1 & SUPPORTED_ALGS) !== 0)) + { + variantBlockSize = 512; + roundFunc = roundSHA1; + finalizeFunc = finalizeSHA1; + outputBinLen = 160; + stateCloneFunc = function(state) { return state.slice();}; + } + else if ((shaVariant.lastIndexOf("SHA-", 0) === 0) && ((6 & SUPPORTED_ALGS) !== 0)) + { + roundFunc = function (block, H) { + return roundSHA2(block, H, shaVariant); + }; + finalizeFunc = function (remainder, remainderBinLen, processedBinLen, H, outputLen) + { + return finalizeSHA2(remainder, remainderBinLen, processedBinLen, H, shaVariant, outputLen); + }; + stateCloneFunc = function(state) { return state.slice(); }; + + if (("SHA-224" === shaVariant) && ((2 & SUPPORTED_ALGS) !== 0)) + { + variantBlockSize = 512; + outputBinLen = 224; + } + else if (("SHA-256" === shaVariant) && ((2 & SUPPORTED_ALGS) !== 0)) + { + variantBlockSize = 512; + outputBinLen = 256; + } + else if (("SHA-384" === shaVariant) && ((4 & SUPPORTED_ALGS) !== 0)) + { + variantBlockSize = 1024; + outputBinLen = 384; + } + else if (("SHA-512" === shaVariant) && ((4 & SUPPORTED_ALGS) !== 0)) + { + variantBlockSize = 1024; + outputBinLen = 512; + } + else + { + throw new Error("Chosen SHA variant is not supported"); + } + } + else if (((shaVariant.lastIndexOf("SHA3-", 0) === 0) || (shaVariant.lastIndexOf("SHAKE", 0) === 0)) && + ((8 & SUPPORTED_ALGS) !== 0)) + { + var delimiter = 0x06; + + roundFunc = roundSHA3; + stateCloneFunc = function(state) { return cloneSHA3State(state);}; + bigEndianMod = 1; + + if ("SHA3-224" === shaVariant) + { + variantBlockSize = 1152; + outputBinLen = 224; + + } + else if ("SHA3-256" === shaVariant) + { + variantBlockSize = 1088; + outputBinLen = 256; + } + else if ("SHA3-384" === shaVariant) + { + variantBlockSize = 832; + outputBinLen = 384; + } + else if ("SHA3-512" === shaVariant) + { + variantBlockSize = 576; + outputBinLen = 512; + } + else if ("SHAKE128" === shaVariant) + { + variantBlockSize = 1344; + outputBinLen = -1; + delimiter = 0x1F; + isSHAKE = true; + } + else if ("SHAKE256" === shaVariant) + { + variantBlockSize = 1088; + outputBinLen = -1; + delimiter = 0x1F; + isSHAKE = true; + } + else + { + throw new Error("Chosen SHA variant is not supported"); + } + finalizeFunc = function (remainder, remainderBinLen, processedBinLen, state, outputLen) + { + return finalizeSHA3(remainder, remainderBinLen, processedBinLen, state, variantBlockSize, delimiter, outputLen); + }; + } + else + { + throw new Error("Chosen SHA variant is not supported"); + } + converterFunc = getStrConverter(inputFormat, utfType, bigEndianMod); + intermediateState = getNewState(shaVariant); + + /** + * Sets the HMAC key for an eventual getHMAC call. Must be called + * immediately after jsSHA object instantiation + * + * @expose + * @param {string|ArrayBuffer} key The key used to calculate the HMAC + * @param {string} inputFormat The format of key, HEX, TEXT, B64, BYTES, + * or ARRAYBUFFER + * @param {{encoding : (string|undefined)}=} options Associative array + * of input format options + */ + this.setHMACKey = function(key, inputFormat, options) + { + var keyConverterFunc, convertRet, keyBinLen, keyToUse, blockByteSize, + i, lastArrayIndex, keyOptions; + + if (true === hmacKeySet) + { + throw new Error("HMAC key already set"); + } + + if (true === updatedCalled) + { + throw new Error("Cannot set HMAC key after calling update"); + } + + if ((isSHAKE === true) && ((8 & SUPPORTED_ALGS) !== 0)) + { + throw new Error("SHAKE is not supported for HMAC"); + } + + keyOptions = options || {}; + utfType = keyOptions["encoding"] || "UTF8"; + + keyConverterFunc = getStrConverter(inputFormat, utfType, bigEndianMod); + + convertRet = keyConverterFunc(key); + keyBinLen = convertRet["binLen"]; + keyToUse = convertRet["value"]; + + blockByteSize = variantBlockSize >>> 3; + + /* These are used multiple times, calculate and store them */ + lastArrayIndex = (blockByteSize / 4) - 1; + + /* Figure out what to do with the key based on its size relative to + * the hash's block size */ + if (blockByteSize < (keyBinLen / 8)) + { + + keyToUse = finalizeFunc(keyToUse, keyBinLen, 0,getNewState(shaVariant), outputBinLen); + /* For all variants, the block size is bigger than the output + * size so there will never be a useful byte at the end of the + * string */ + while (keyToUse.length <= lastArrayIndex) + { + keyToUse.push(0); + } + keyToUse[lastArrayIndex] &= 0xFFFFFF00; + } + else if (blockByteSize > (keyBinLen / 8)) + { + /* If the blockByteSize is greater than the key length, there + * will always be at LEAST one "useless" byte at the end of the + * string */ + while (keyToUse.length <= lastArrayIndex) + { + keyToUse.push(0); + } + keyToUse[lastArrayIndex] &= 0xFFFFFF00; + } + + /* Create ipad and opad */ + for (i = 0; i <= lastArrayIndex; i += 1) + { + keyWithIPad[i] = keyToUse[i] ^ 0x36363636; + keyWithOPad[i] = keyToUse[i] ^ 0x5C5C5C5C; + } + + intermediateState = roundFunc(keyWithIPad, intermediateState); + processedLen = variantBlockSize; + + hmacKeySet = true; + }; + + /** + * Takes strString and hashes as many blocks as possible. Stores the + * rest for either a future update or getHash call. + * + * @expose + * @param {string|ArrayBuffer} srcString The string to be hashed + */ + this.update = function(srcString) + { + var convertRet, chunkBinLen, chunkIntLen, chunk, i, updateProcessedLen = 0, + variantBlockIntInc = variantBlockSize >>> 5; + + convertRet = converterFunc(srcString, remainder, remainderLen); + chunkBinLen = convertRet["binLen"]; + chunk = convertRet["value"]; + + chunkIntLen = chunkBinLen >>> 5; + for (i = 0; i < chunkIntLen; i += variantBlockIntInc) + { + if (updateProcessedLen + variantBlockSize <= chunkBinLen) + { + intermediateState = roundFunc( + chunk.slice(i, i + variantBlockIntInc), + intermediateState + ); + updateProcessedLen += variantBlockSize; + } + } + processedLen += updateProcessedLen; + remainder = chunk.slice(updateProcessedLen >>> 5); + remainderLen = chunkBinLen % variantBlockSize; + updatedCalled = true; + + }; + + /** + * Returns the desired SHA hash of the string specified at instantiation + * using the specified parameters + * + * @expose + * @param {string} format The desired output formatting (B64, HEX, + * BYTES, or ARRAYBUFFER) + * @param {{outputUpper : (boolean|undefined), b64Pad : (string|undefined), + * shakeLen : (number|undefined)}=} options Hash list of output formatting options + * @return {string|ArrayBuffer} The string representation of the hash + * in the format specified. + */ + this.getHash = function(format, options) + { + var formatFunc, i, outputOptions, finalizedState; + + if (true === hmacKeySet) + { + throw new Error("Cannot call getHash after setting HMAC key"); + } + + outputOptions = getOutputOpts(options); + + if ((isSHAKE === true) && ((8 & SUPPORTED_ALGS) !== 0)) + { + if (outputOptions["shakeLen"] === -1) + { + throw new Error("shakeLen must be specified in options"); + } + outputBinLen = outputOptions["shakeLen"]; + } + + /* Validate the output format selection */ + switch (format) + { + case "HEX": + formatFunc = function(binarray) {return packed2hex(binarray, outputBinLen, bigEndianMod, outputOptions);}; + break; + case "B64": + formatFunc = function(binarray) {return packed2b64(binarray, outputBinLen, bigEndianMod, outputOptions);}; + break; + case "BYTES": + formatFunc = function(binarray) {return packed2bytes(binarray, outputBinLen, bigEndianMod);}; + break; + case "ARRAYBUFFER": + try { + i = new ArrayBuffer(0); + } catch (ignore) { + throw new Error("ARRAYBUFFER not supported by this environment"); + } + formatFunc = function(binarray) {return packed2arraybuffer(binarray, outputBinLen, bigEndianMod);}; + break; + default: + throw new Error("format must be HEX, B64, BYTES, or ARRAYBUFFER"); + } + + finalizedState = finalizeFunc(remainder.slice(), remainderLen, processedLen, stateCloneFunc(intermediateState), outputBinLen); + for (i = 1; i < numRounds; i += 1) + { + /* This weird fix-up is only for the case of SHAKE algorithms + * and outputBinLen is not a multiple of 32. In this case, the + * very last block of finalizedState has data that needs to be + * ignored because all the finalizeFunc calls need to have + * unneeded bits set to 0. + */ + if (((8 & SUPPORTED_ALGS) !== 0) && (isSHAKE === true) && (outputBinLen % 32 !== 0)) + { + finalizedState[finalizedState.length - 1] &= 0x00FFFFFF >>> 24 - (outputBinLen % 32); + } + finalizedState = finalizeFunc(finalizedState, outputBinLen, 0, getNewState(shaVariant), outputBinLen); + } + + return formatFunc(finalizedState); + }; + + /** + * Returns the the HMAC in the specified format using the key given by + * a previous setHMACKey call. + * + * @expose + * @param {string} format The desired output formatting + * (B64, HEX, BYTES, or ARRAYBUFFER) + * @param {{outputUpper : (boolean|undefined), b64Pad : (string|undefined), + * shakeLen : (number|undefined)}=} options associative array of output + * formatting options + * @return {string|ArrayBuffer} The string representation of the hash in the + * format specified. + */ + this.getHMAC = function(format, options) + { + var formatFunc, firstHash, outputOptions, finalizedState; + + if (false === hmacKeySet) + { + throw new Error("Cannot call getHMAC without first setting HMAC key"); + } + + outputOptions = getOutputOpts(options); + + /* Validate the output format selection */ + switch (format) + { + case "HEX": + formatFunc = function(binarray) {return packed2hex(binarray, outputBinLen, bigEndianMod, outputOptions);}; + break; + case "B64": + formatFunc = function(binarray) {return packed2b64(binarray, outputBinLen, bigEndianMod, outputOptions);}; + break; + case "BYTES": + formatFunc = function(binarray) {return packed2bytes(binarray, outputBinLen, bigEndianMod);}; + break; + case "ARRAYBUFFER": + try { + formatFunc = new ArrayBuffer(0); + } catch(ignore) { + throw new Error("ARRAYBUFFER not supported by this environment"); + } + formatFunc = function(binarray) {return packed2arraybuffer(binarray, outputBinLen, bigEndianMod);}; + break; + default: + throw new Error("outputFormat must be HEX, B64, BYTES, or ARRAYBUFFER"); + } + + firstHash = finalizeFunc(remainder.slice(), remainderLen, processedLen, stateCloneFunc(intermediateState), outputBinLen); + finalizedState = roundFunc(keyWithOPad, getNewState(shaVariant)); + finalizedState = finalizeFunc(firstHash, outputBinLen, variantBlockSize, finalizedState, outputBinLen); + + return formatFunc(finalizedState); + }; + }; + + if (("function" === typeof define) && (define["amd"])) /* AMD Support */ + { + define(function() + { + return jsSHA; + }); + } else if ("undefined" !== typeof exports) /* Node Support */ + { + if (("undefined" !== typeof module) && module["exports"]) + { + module["exports"] = jsSHA; + exports = jsSHA; + } + else { + exports = jsSHA; + } + } else { /* Browsers and Web Workers*/ + global["jsSHA"] = jsSHA; + } +}(this)); diff --git a/frontend/jsSHA/test/genHashRounds.py b/frontend/jsSHA/test/genHashRounds.py new file mode 100755 index 0000000..12f3845 --- /dev/null +++ b/frontend/jsSHA/test/genHashRounds.py @@ -0,0 +1,67 @@ +#!/usr/bin/env python2 +import binascii +import hashlib + +import sha3 + +def main(): + hash_funcs = [ + ('SHA-1', hashlib.sha1), + ('SHA-224', hashlib.sha224), + ('SHA-256', hashlib.sha256), + ('SHA-384', hashlib.sha384), + ('SHA-512', hashlib.sha512)] + + for (sha_type, sha_func) in hash_funcs: + digest = sha_func('abc').digest() + + # Only loop 4 times since an iteration was done above + for x in xrange(0, 4): + digest = sha_func(digest).digest() + print('{} with 5 Rounds: {}'.format(sha_type, digest.encode('hex'))) + + # Loop another 5 times to get to 10 + for x in xrange(0, 5): + digest = sha_func(digest).digest() + print('{} with 10 Rounds: {}'.format(sha_type, digest.encode('hex'))) + + # SHA3 is handled differently as it's not in hashlib. + # Use the SHA3 creators' version + hash3_funcs = [ + ('SHA3-224', sha3.SHA3_224), + ('SHA3-256', sha3.SHA3_256), + ('SHA3-384', sha3.SHA3_384), + ('SHA3-512', sha3.SHA3_512)] + + for (sha_type, sha_func) in hash3_funcs: + digest = sha_func([ord(c) for c in 'abc']) + + # Only loop 4 times since an iteration was done above + for x in xrange(0, 4): + digest = sha_func(digest) + print('{} with 5 Rounds: {}'.format(sha_type, binascii.hexlify(digest))) + + # Loop another 5 times to get to 10 + for x in xrange(0, 5): + digest = sha_func(digest) + print('{} with 10 Rounds: {}'.format(sha_type, binascii.hexlify(digest))) + + hash3_funcs = [ + ('SHAKE128', sha3.SHAKE128), + ('SHAKE256', sha3.SHAKE256)] + + for (sha_type, sha_func) in hash3_funcs: + digest = sha_func([ord(c) for c in 'abc'], 31) + + # Only loop 4 times since an iteration was done above + for x in xrange(0, 4): + digest = sha_func(digest, 31) + print('{} with 5 Rounds: {}'.format(sha_type, binascii.hexlify(digest))) + + # Loop another 5 times to get to 10 + for x in xrange(0, 5): + digest = sha_func(digest, 31) + print('{} with 10 Rounds: {}'.format(sha_type, binascii.hexlify(digest))) + +if ('__main__' == __name__): + main() diff --git a/frontend/jsSHA/test/genShake.py b/frontend/jsSHA/test/genShake.py new file mode 100755 index 0000000..f4be6d5 --- /dev/null +++ b/frontend/jsSHA/test/genShake.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python2 +import binascii + +import sha3 + +def main(): + test_vectors = { + 'Short': 'abc', + 'Medium': 'abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu', + 'Long': 'a' * 1000000 + } + + hash_funcs = {'SHAKE128': sha3.SHAKE128, 'SHAKE256': sha3.SHAKE256} + output_lens = [31, 63] + + for hash_name, hash_func in hash_funcs.items(): + for vector_name, vector_value in test_vectors.items(): + for output_len in output_lens: + print('%s with %s UTF-8 Input and %d bit Output: %s' % ( + hash_name, + vector_name, + output_len * 8, + binascii.hexlify(hash_func(vector_value.encode(), output_len)).decode() + ) + ) + print('%s with %s UTF-16BE Input and %d bit Output: %s' % ( + hash_name, + vector_name, + output_len * 8, + binascii.hexlify(hash_func(vector_value.encode('UTF-16BE'), output_len)).decode() + ) + ) + print('%s with %s UTF-16LE Input and %d bit Output: %s' % ( + hash_name, + vector_name, + output_len * 8, + binascii.hexlify(hash_func(vector_value.encode('UTF-16LE'), output_len)).decode() + ) + ) + +if ('__main__' == __name__): + main() diff --git a/frontend/jsSHA/test/hash-file.html b/frontend/jsSHA/test/hash-file.html new file mode 100755 index 0000000..acc1121 --- /dev/null +++ b/frontend/jsSHA/test/hash-file.html @@ -0,0 +1,114 @@ + + + + jsSHA (http://caligatio.github.com/jsSHA/) - File Test + + + + + + + Drop this project's LICENSE file to test, or any other file to find its hashes: +

+ +

+ NOTE: This may not work in Internet Explorer +
+ + diff --git a/frontend/jsSHA/test/sha3.py b/frontend/jsSHA/test/sha3.py new file mode 100755 index 0000000..c54b183 --- /dev/null +++ b/frontend/jsSHA/test/sha3.py @@ -0,0 +1,106 @@ +# -*- coding: utf-8 -*- +# Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, +# Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby +# denoted as "the implementer". +# +# For more information, feedback or questions, please refer to our websites: +# http://keccak.noekeon.org/ +# http://keyak.noekeon.org/ +# http://ketje.noekeon.org/ +# +# To the extent possible under law, the implementer has waived all copyright +# and related or neighboring rights to the source code in this file. +# http://creativecommons.org/publicdomain/zero/1.0/ + +def ROL64(a, n): + return ((a >> (64-(n%64))) + (a << (n%64))) % (1 << 64) + +def KeccakF1600onLanes(lanes): + R = 1 + for round in range(24): + # θ + C = [lanes[x][0] ^ lanes[x][1] ^ lanes[x][2] ^ lanes[x][3] ^ lanes[x][4] for x in range(5)] + D = [C[(x+4)%5] ^ ROL64(C[(x+1)%5], 1) for x in range(5)] + lanes = [[lanes[x][y]^D[x] for y in range(5)] for x in range(5)] + # ρ and π + (x, y) = (1, 0) + current = lanes[x][y] + for t in range(24): + (x, y) = (y, (2*x+3*y)%5) + (current, lanes[x][y]) = (lanes[x][y], ROL64(current, (t+1)*(t+2)//2)) + # χ + for y in range(5): + T = [lanes[x][y] for x in range(5)] + for x in range(5): + lanes[x][y] = T[x] ^((~T[(x+1)%5]) & T[(x+2)%5]) + # ι + for j in range(7): + R = ((R << 1) ^ ((R >> 7)*0x71)) % 256 + if (R & 2): + lanes[0][0] = lanes[0][0] ^ (1 << ((1<> (8*i)) % 256 for i in range(8)) + +def KeccakF1600(state): + lanes = [[load64(state[8*(x+5*y):8*(x+5*y)+8]) for y in range(5)] for x in range(5)] + lanes = KeccakF1600onLanes(lanes) + state = bytearray(200) + for x in range(5): + for y in range(5): + state[8*(x+5*y):8*(x+5*y)+8] = store64(lanes[x][y]) + return state + +def Keccak(rate, capacity, inputBytes, delimitedSuffix, outputByteLen): + outputBytes = bytearray() + state = bytearray([0 for i in range(200)]) + rateInBytes = rate//8 + blockSize = 0 + if (((rate + capacity) != 1600) or ((rate % 8) != 0)): + return + inputOffset = 0 + # === Absorb all the input blocks === + while(inputOffset < len(inputBytes)): + blockSize = min(len(inputBytes)-inputOffset, rateInBytes) + for i in range(blockSize): + state[i] = state[i] ^ inputBytes[i+inputOffset] + inputOffset = inputOffset + blockSize + if (blockSize == rateInBytes): + state = KeccakF1600(state) + blockSize = 0 + # === Do the padding and switch to the squeezing phase === + state[blockSize] = state[blockSize] ^ delimitedSuffix + if (((delimitedSuffix & 0x80) != 0) and (blockSize == (rateInBytes-1))): + state = KeccakF1600(state) + state[rateInBytes-1] = state[rateInBytes-1] ^ 0x80 + state = KeccakF1600(state) + # === Squeeze out all the output blocks === + while(outputByteLen > 0): + blockSize = min(outputByteLen, rateInBytes) + outputBytes = outputBytes + state[0:blockSize] + outputByteLen = outputByteLen - blockSize + if (outputByteLen > 0): + state = KeccakF1600(state) + return outputBytes + +def SHAKE128(inputBytes, outputByteLen): + return Keccak(1344, 256, inputBytes, 0x1F, outputByteLen) + +def SHAKE256(inputBytes, outputByteLen): + return Keccak(1088, 512, inputBytes, 0x1F, outputByteLen) + +def SHA3_224(inputBytes): + return Keccak(1152, 448, inputBytes, 0x06, 224//8) + +def SHA3_256(inputBytes): + return Keccak(1088, 512, inputBytes, 0x06, 256//8) + +def SHA3_384(inputBytes): + return Keccak(832, 768, inputBytes, 0x06, 384//8) + +def SHA3_512(inputBytes): + return Keccak(576, 1024, inputBytes, 0x06, 512//8) diff --git a/frontend/jsSHA/test/test.html b/frontend/jsSHA/test/test.html new file mode 100755 index 0000000..22142af --- /dev/null +++ b/frontend/jsSHA/test/test.html @@ -0,0 +1,38 @@ + + + + jsSHA (http://caligatio.github.com/jsSHA/) Tests + + + + + + + + + + + + +

jsSHA Hash Test Page

+

Hash Tests

+

+ These tests implement the test vectors found on the NIST Examples page. +

+ +

+ Note that the "Long" test involves hashing a 1,000,000 character string and can take quite a while depending on the browser and machine. +

+ +

Custom Tests

+

+ Values for SHAKE tests can be generated using the included genShake.py. Similarly, values for the multiple round tests can be generated using the included getHashRounds.py. +

+ +
+ + diff --git a/frontend/jsSHA/test/test_hashes.js b/frontend/jsSHA/test/test_hashes.js new file mode 100755 index 0000000..1a9ab98 --- /dev/null +++ b/frontend/jsSHA/test/test_hashes.js @@ -0,0 +1,1213 @@ +/* Kind of hack to get the tests working both in the browser and node.js */ + +/*jslint + bitwise: true, multivar: true, for: true, this: true, sub: true, esversion: 3 +*/ +if (("undefined" !== typeof module) && module["exports"]) +{ + mocha = require("mocha"); + chai = require("chai"); + jsSHA = require("../src/sha_dev.js"); +} + +String.prototype.repeat = function(times) { + return (new Array(times + 1)).join(this); +}; + +function hexToArrayBuffer(hexStr) +{ + var arrayBuffer = new ArrayBuffer(hexStr.length / 2), arrView = new Uint8Array(arrayBuffer), i; + + for (i = 0; i < hexStr.length; i += 2) + { + num = parseInt(hexStr.substr(i, 2), 16); + if (!isNaN(num)) + { + arrView[i >>> 1] = num; + } + else + { + throw new Error("String of HEX type contains invalid characters"); + } + } + + return arrayBuffer; +} + +function arrayBufferToHex(arrayBuffer) +{ + var hex_tab = "0123456789abcdef", arrView = new Uint8Array(arrayBuffer), i, str = ""; + + for (i = 0; i < arrView.length; i += 1) + { + str += (hex_tab.charAt((arrView[i] >>> 4) & 0xF) + + hex_tab.charAt(arrView[i] & 0xF)); + } + + return str; +} + +/* These are used often so make a global copy that everything can reference */ +var millionaAscii = "a".repeat(1000000), millionaHex = "61".repeat(1000000), millionaB64 = "YWFh".repeat(333333) + "YQ=="; + +/* ============================================================================ + * Begin Basic Hash Tests + * ============================================================================ + */ +var hashTests = [ + { + "hash": "SHA-1", + "tests" : [ + { + "name": "Short", + "ptInputs": [ + {"type": "TEXT", "value": "abc", "encoding": "UTF8"}, + {"type": "HEX", "value": "616263"}, + {"type": "B64", "value": "YWJj"} + ], + "outputs" : [ + {"type": "HEX", "value": "a9993e364706816aba3e25717850c26c9cd0d89d"}, + {"type": "B64", "value": "qZk+NkcGgWq6PiVxeFDCbJzQ2J0="} + ] + }, + { + "name": "Medium", + "ptInputs": [ + {"type": "TEXT", "value": "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "encoding": "UTF8"}, + {"type": "HEX", "value": "6162636462636465636465666465666765666768666768696768696A68696A6B696A6B6C6A6B6C6D6B6C6D6E6C6D6E6F6D6E6F706E6F7071"}, + {"type": "B64", "value": "YWJjZGJjZGVjZGVmZGVmZ2VmZ2hmZ2hpZ2hpamhpamtpamtsamtsbWtsbW5sbW5vbW5vcG5vcHE="} + ], + "outputs" : [ + {"type": "HEX", "value": "84983e441c3bd26ebaae4aa1f95129e5e54670f1"}, + {"type": "B64", "value": "hJg+RBw70m66rkqh+VEp5eVGcPE="} + ] + }, + { + "name": "Long", + "ptInputs": [ + {"type": "TEXT", "value": millionaAscii, "encoding": "UTF8"}, + {"type": "HEX", "value": millionaHex}, + {"type": "B64", "value": millionaB64} + ], + "outputs" : [ + {"type": "HEX", "value": "34aa973cd4c4daa4f61eeb2bdbad27316534016f"}, + {"type": "B64", "value": "NKqXPNTE2qT2Husr260nMWU0AW8="} + ] + }, + { + "name": "Short UTF16-BE", + "ptInputs": [ + {"type": "TEXT", "value": "abc", "encoding": "UTF16BE"} + ], + "outputs" : [ + {"type": "HEX", "value": "af68535cb6d1af8b6e3c60305cf0bfae6c57de36"} + ] + }, + { + "name": "Medium UTF16-BE", + "ptInputs": [ + {"type": "TEXT", "value": "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "encoding": "UTF16BE"} + ], + "outputs" : [ + {"type": "HEX", "value": "bef8f6cd143d7fa6d9f726eef2ff444391fe76ac"} + ] + }, + { + "name": "Long UTF16-BE", + "ptInputs": [ + {"type": "TEXT", "value": millionaAscii, "encoding": "UTF16BE"} + ], + "outputs" : [ + {"type": "HEX", "value": "94359e86fb2a95ceed60bd0b58bcffd7192d9c16"} + ] + }, + { + "name": "Short UTF16-LE", + "ptInputs": [ + {"type": "TEXT", "value": "abc", "encoding": "UTF16LE"} + ], + "outputs" : [ + {"type": "HEX", "value": "9f04f41a848514162050e3d68c1a7abb441dc2b5"} + ] + }, + { + "name": "Medium UTF16-LE", + "ptInputs": [ + {"type": "TEXT", "value": "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "encoding": "UTF16LE"} + ], + "outputs" : [ + {"type": "HEX", "value": "51d7d8769ac72c409c5b0e3f69c60adc9a039014"} + ] + }, + { + "name": "Long UTF16-LE", + "ptInputs": [ + {"type": "TEXT", "value": millionaAscii, "encoding": "UTF16LE"} + ], + "outputs" : [ + {"type": "HEX", "value": "c4609560a108a0c626aa7f2b38a65566739353c5"} + ] + } + ] + }, + { + "hash": "SHA-224", + "tests": [ + { + "name": "Short", + "ptInputs": [ + {"type": "TEXT", "value": "abc", "encoding": "UTF8"}, + {"type": "HEX", "value": "616263"}, + {"type": "B64", "value": "YWJj"} + ], + "outputs" : [ + {"type": "HEX", "value": "23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7"}, + {"type": "B64", "value": "Iwl9IjQF2CKGQqR3vaJVsyqtvOS9oLP342ydpw=="} + ] + }, + { + "name": "Medium", + "ptInputs": [ + {"type": "TEXT", "value": "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "encoding": "UTF8"}, + {"type": "HEX", "value": "6162636462636465636465666465666765666768666768696768696A68696A6B696A6B6C6A6B6C6D6B6C6D6E6C6D6E6F6D6E6F706E6F7071"}, + {"type": "B64", "value": "YWJjZGJjZGVjZGVmZGVmZ2VmZ2hmZ2hpZ2hpamhpamtpamtsamtsbWtsbW5sbW5vbW5vcG5vcHE="} + ], + "outputs" : [ + {"type": "HEX", "value": "75388b16512776cc5dba5da1fd890150b0c6455cb4f58b1952522525"}, + {"type": "B64", "value": "dTiLFlEndsxdul2h/YkBULDGRVy09YsZUlIlJQ=="} + ] + }, + { + "name": "Long", + "ptInputs": [ + {"type": "TEXT", "value": millionaAscii, "encoding": "UTF8"}, + {"type": "HEX", "value": millionaHex}, + {"type": "B64", "value": millionaB64} + ], + "outputs" : [ + {"type": "HEX", "value": "20794655980c91d8bbb4c1ea97618a4bf03f42581948b2ee4ee7ad67"}, + {"type": "B64", "value": "IHlGVZgMkdi7tMHql2GKS/A/QlgZSLLuTuetZw=="} + ] + }, + { + "name": "Short UTF16-BE", + "ptInputs": [ + {"type": "TEXT", "value": "abc", "encoding": "UTF16BE"} + ], + "outputs" : [ + {"type": "HEX", "value": "4751f7e6ffd48fd96549183745ed3b51517cf79479475670299dcaa1"} + ] + }, + { + "name": "Medium UTF16-BE", + "ptInputs": [ + {"type": "TEXT", "value": "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "encoding": "UTF16BE"} + ], + "outputs" : [ + {"type": "HEX", "value": "1591f5aa2b329fa3cd3645ca52e62cb859fee74922e4495783e17213"} + ] + }, + { + "name": "Long UTF16-BE", + "ptInputs": [ + {"type": "TEXT", "value": millionaAscii, "encoding": "UTF16BE"} + ], + "outputs" : [ + {"type": "HEX", "value": "3bd39fdaa867ff89948d8699c179b79ece1eb8a78d2413481824397a"} + ] + }, + { + "name": "Short UTF16-LE", + "ptInputs": [ + {"type": "TEXT", "value": "abc", "encoding": "UTF16LE"} + ], + "outputs" : [ + {"type": "HEX", "value": "57ba76af9d4846f1e08697d79422ea3f516fe3145ad7fc4c93ba85ac"} + ] + }, + { + "name": "Medium UTF16-LE", + "ptInputs": [ + {"type": "TEXT", "value": "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "encoding": "UTF16LE"} + ], + "outputs" : [ + {"type": "HEX", "value": "2d30dab9655cd28a84790ae02e742d28b02c1d5d2e7196cee1732ca5"} + ] + }, + { + "name": "Long UTF16-LE", + "ptInputs": [ + {"type": "TEXT", "value": millionaAscii, "encoding": "UTF16LE"} + ], + "outputs" : [ + {"type": "HEX", "value": "11bb18d73d725c7d104e1ca15ee9b5094c3703ac152ffb2484b45a78"} + ] + } + ] + }, + { + "hash": "SHA3-224", + "tests": [ + { + "name": "Short", + "ptInputs": [ + {"type": "TEXT", "value": "abc", "encoding": "UTF8"}, + {"type": "HEX", "value": "616263"}, + {"type": "B64", "value": "YWJj"} + ], + "outputs" : [ + {"type": "HEX", "value": "e642824c3f8cf24ad09234ee7d3c766fc9a3a5168d0c94ad73b46fdf"}, + {"type": "B64", "value": "5kKCTD+M8krQkjTufTx2b8mjpRaNDJStc7Rv3w=="} + ] + }, + { + "name": "Medium", + "ptInputs": [ + {"type": "TEXT", "value": "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "encoding": "UTF8"}, + {"type": "HEX", "value": "6162636462636465636465666465666765666768666768696768696A68696A6B696A6B6C6A6B6C6D6B6C6D6E6C6D6E6F6D6E6F706E6F7071"}, + {"type": "B64", "value": "YWJjZGJjZGVjZGVmZGVmZ2VmZ2hmZ2hpZ2hpamhpamtpamtsamtsbWtsbW5sbW5vbW5vcG5vcHE="} + ], + "outputs" : [ + {"type": "HEX", "value": "8a24108b154ada21c9fd5574494479ba5c7e7ab76ef264ead0fcce33"}, + {"type": "B64", "value": "iiQQixVK2iHJ/VV0SUR5ulx+erdu8mTq0PzOMw=="} + ] + }, + { + "name": "Long", + "ptInputs": [ + {"type": "TEXT", "value": millionaAscii, "encoding": "UTF8"}, + {"type": "HEX", "value": millionaHex}, + {"type": "B64", "value": millionaB64} + ], + "outputs" : [ + {"type": "HEX", "value": "d69335b93325192e516a912e6d19a15cb51c6ed5c15243e7a7fd653c"}, + {"type": "B64", "value": "1pM1uTMlGS5RapEubRmhXLUcbtXBUkPnp/1lPA=="} + ] + }, + { + "name": "Short UTF16-BE", + "ptInputs": [ + {"type": "TEXT", "value": "abc", "encoding": "UTF16BE"} + ], + "outputs" : [ + {"type": "HEX", "value": "d5c49292551814f4dd267d4b9f3e10bc12d97ae01a75688fc94973c6"} + ] + }, + { + "name": "Medium UTF16-BE", + "ptInputs": [ + {"type": "TEXT", "value": "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "encoding": "UTF16BE"} + ], + "outputs" : [ + {"type": "HEX", "value": "e8d8ae12828497d89f36e573ab18f6237028e063f0bc1e8dce812a54"} + ] + }, + { + "name": "Long UTF16-BE", + "ptInputs": [ + {"type": "TEXT", "value": millionaAscii, "encoding": "UTF16BE"} + ], + "outputs" : [ + {"type": "HEX", "value": "ea9658eb20be9aaeb24ced54c9e9688dd127d249e92b3e3e9b47bbe8"} + ] + }, + { + "name": "Short UTF16-LE", + "ptInputs": [ + {"type": "TEXT", "value": "abc", "encoding": "UTF16LE"} + ], + "outputs" : [ + {"type": "HEX", "value": "bcaf706ac4a322d3b95f7fcd33e623a82b83ffa5b4044df21fb970de"} + ] + }, + { + "name": "Medium UTF16-LE", + "ptInputs": [ + {"type": "TEXT", "value": "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "encoding": "UTF16LE"} + ], + "outputs" : [ + {"type": "HEX", "value": "5e3d1dc2dc50b3d3bf03beac724d6d3203231eea900449fd4f542540"} + ] + }, + { + "name": "Long UTF16-LE", + "ptInputs": [ + {"type": "TEXT", "value": millionaAscii, "encoding": "UTF16LE"} + ], + "outputs" : [ + {"type": "HEX", "value": "116fbbbb67efdb66c257763918ff03c2daca1a726a2559d0d5c31dc1"} + ] + } + ] + }, + { + "hash": "SHA-256", + "tests": [ + { + "name": "Short", + "ptInputs": [ + {"type": "TEXT", "value": "abc", "encoding": "UTF8"}, + {"type": "HEX", "value": "616263"}, + {"type": "B64", "value": "YWJj"} + ], + "outputs" : [ + {"type": "HEX", "value": "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"}, + {"type": "B64", "value": "ungWv48Bz+pBQUDeXa4iI7ADYaOWF3qctBD/YfIAFa0="} + ] + }, + { + "name": "Medium", + "ptInputs": [ + {"type": "TEXT", "value": "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "encoding": "UTF8"}, + {"type": "HEX", "value": "6162636462636465636465666465666765666768666768696768696A68696A6B696A6B6C6A6B6C6D6B6C6D6E6C6D6E6F6D6E6F706E6F7071"}, + {"type": "B64", "value": "YWJjZGJjZGVjZGVmZGVmZ2VmZ2hmZ2hpZ2hpamhpamtpamtsamtsbWtsbW5sbW5vbW5vcG5vcHE="} + ], + "outputs" : [ + {"type": "HEX", "value": "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1"}, + {"type": "B64", "value": "JI1qYdIGOLjlwCaTDD5gOaM85Flk/yFn9uzt1BnbBsE="} + ] + }, + { + "name": "Long", + "ptInputs": [ + {"type": "TEXT", "value": millionaAscii, "encoding": "UTF8"}, + {"type": "HEX", "value": millionaHex}, + {"type": "B64", "value": millionaB64} + ], + "outputs" : [ + {"type": "HEX", "value": "cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0"}, + {"type": "B64", "value": "zcduXJkU+5KBocfihNc+Z/GAmkiklyAOBG05zMcRLNA="} + ] + }, + { + "name": "Short UTF16-BE", + "ptInputs": [ + {"type": "TEXT", "value": "abc", "encoding": "UTF16BE"} + ], + "outputs" : [ + {"type": "HEX", "value": "e265e98c934ff1ff7d55359eed484c4581b3c372bac922350c645fb5fd937280"} + ] + }, + { + "name": "Medium UTF16-BE", + "ptInputs": [ + {"type": "TEXT", "value": "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "encoding": "UTF16BE"} + ], + "outputs" : [ + {"type": "HEX", "value": "1d04116da99940f5eb149d21c7a556e1625839dd7fd74bcf4c3028b97b9da57f"} + ] + }, + { + "name": "Long UTF16-BE", + "ptInputs": [ + {"type": "TEXT", "value": millionaAscii, "encoding": "UTF16BE"} + ], + "outputs" : [ + {"type": "HEX", "value": "b21c3efa2f1a0075d566f7354aa51f0156e66ed209ee708902aa5953a7eb8140"} + ] + }, + { + "name": "Short UTF16-LE", + "ptInputs": [ + {"type": "TEXT", "value": "abc", "encoding": "UTF16LE"} + ], + "outputs" : [ + {"type": "HEX", "value": "13e228567e8249fce53337f25d7970de3bd68ab2653424c7b8f9fd05e33caedf"} + ] + }, + { + "name": "Medium UTF16-LE", + "ptInputs": [ + {"type": "TEXT", "value": "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "encoding": "UTF16LE"} + ], + "outputs" : [ + {"type": "HEX", "value": "fa84fa96dd6f1a0fda1769cacec9bac12efadad72ab60ff68ec5ae1a4d3fab8e"} + ] + }, + { + "name": "Long UTF16-LE", + "ptInputs": [ + {"type": "TEXT", "value": millionaAscii, "encoding": "UTF16LE"} + ], + "outputs" : [ + {"type": "HEX", "value": "a0bc50078623514a87e96de81d8d200527a1b1150acd92252d88aa109dfa0aa4"} + ] + } + ] + }, + { + "hash": "SHA3-256", + "tests": [ + { + "name": "Short", + "ptInputs": [ + {"type": "TEXT", "value": "abc", "encoding": "UTF8"}, + {"type": "HEX", "value": "616263"}, + {"type": "B64", "value": "YWJj"} + ], + "outputs" : [ + {"type": "HEX", "value": "3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532"}, + {"type": "B64", "value": "Ophdp0/iJbIEXBcta9OQvYVfCG4+nVJbRr/iRRFDFTI="} + ] + }, + { + "name": "Medium", + "ptInputs": [ + {"type": "TEXT", "value": "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "encoding": "UTF8"}, + {"type": "HEX", "value": "6162636462636465636465666465666765666768666768696768696A68696A6B696A6B6C6A6B6C6D6B6C6D6E6C6D6E6F6D6E6F706E6F7071"}, + {"type": "B64", "value": "YWJjZGJjZGVjZGVmZGVmZ2VmZ2hmZ2hpZ2hpamhpamtpamtsamtsbWtsbW5sbW5vbW5vcG5vcHE="} + ], + "outputs" : [ + {"type": "HEX", "value": "41c0dba2a9d6240849100376a8235e2c82e1b9998a999e21db32dd97496d3376"}, + {"type": "B64", "value": "QcDboqnWJAhJEAN2qCNeLILhuZmKmZ4h2zLdl0ltM3Y="} + ] + }, + { + "name": "Long", + "ptInputs": [ + {"type": "TEXT", "value": millionaAscii, "encoding": "UTF8"}, + {"type": "HEX", "value": millionaHex}, + {"type": "B64", "value": millionaB64} + ], + "outputs" : [ + {"type": "HEX", "value": "5c8875ae474a3634ba4fd55ec85bffd661f32aca75c6d699d0cdcb6c115891c1"}, + {"type": "B64", "value": "XIh1rkdKNjS6T9VeyFv/1mHzKsp1xtaZ0M3LbBFYkcE="} + ] + }, + { + "name": "Short UTF16-BE", + "ptInputs": [ + {"type": "TEXT", "value": "abc", "encoding": "UTF16BE"} + ], + "outputs" : [ + {"type": "HEX", "value": "a3198ab574d5b50d1a9aa1e34dbdaaa50ed6df67031bf66838e9c8b902a05feb"} + ] + }, + { + "name": "Medium UTF16-BE", + "ptInputs": [ + {"type": "TEXT", "value": "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "encoding": "UTF16BE"} + ], + "outputs" : [ + {"type": "HEX", "value": "5cbbd5115111f239eaa31c106c3497e785bfe49dcae896642aa6e21f631bd4d5"} + ] + }, + { + "name": "Long UTF16-BE", + "ptInputs": [ + {"type": "TEXT", "value": millionaAscii, "encoding": "UTF16BE"} + ], + "outputs" : [ + {"type": "HEX", "value": "a9cd30fe7649d1c0d8ba700d01fde163a95e2bccb68c3faae8cc300c44264725"} + ] + }, + { + "name": "Short UTF16-LE", + "ptInputs": [ + {"type": "TEXT", "value": "abc", "encoding": "UTF16LE"} + ], + "outputs" : [ + {"type": "HEX", "value": "a7fc119e08d5dbcdbd7f69d7bba10866c62ba2a3e31577a7d7c582f4ec20b78b"} + ] + }, + { + "name": "Medium UTF16-LE", + "ptInputs": [ + {"type": "TEXT", "value": "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "encoding": "UTF16LE"} + ], + "outputs" : [ + {"type": "HEX", "value": "86037e690b1baa71450a0c2314cacbb08e0c571019f7f1f98aac1921c2d53889"} + ] + }, + { + "name": "Long UTF16-LE", + "ptInputs": [ + {"type": "TEXT", "value": millionaAscii, "encoding": "UTF16LE"} + ], + "outputs" : [ + {"type": "HEX", "value": "73b713b341e839a18e5ad439771ab52a71656662a0c019d9d1dcf9b001819a57"} + ] + } + ] + }, + { + "hash": "SHA-384", + "tests": [ + { + "name": "Short", + "ptInputs": [ + {"type": "TEXT", "value": "abc", "encoding": "UTF8"}, + {"type": "HEX", "value": "616263"}, + {"type": "B64", "value": "YWJj"} + ], + "outputs" : [ + {"type": "HEX", "value": "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7"}, + {"type": "B64", "value": "ywB1P0WjXou1oD1pmsZQBycsMqsO3tFjGotgWkP/W+2AhgcroefMI1i67KE0yCWn"} + ] + }, + { + "name": "Medium", + "ptInputs": [ + {"type": "TEXT", "value": "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", "encoding": "UTF8"}, + {"type": "HEX", "value": "61626364656667686263646566676869636465666768696A6465666768696A6B65666768696A6B6C666768696A6B6C6D6768696A6B6C6D6E68696A6B6C6D6E6F696A6B6C6D6E6F706A6B6C6D6E6F70716B6C6D6E6F7071726C6D6E6F707172736D6E6F70717273746E6F707172737475"}, + {"type": "B64", "value": "YWJjZGVmZ2hiY2RlZmdoaWNkZWZnaGlqZGVmZ2hpamtlZmdoaWprbGZnaGlqa2xtZ2hpamtsbW5oaWprbG1ub2lqa2xtbm9wamtsbW5vcHFrbG1ub3Bxcmxtbm9wcXJzbW5vcHFyc3Rub3BxcnN0dQ=="} + ], + "outputs" : [ + {"type": "HEX", "value": "09330c33f71147e83d192fc782cd1b4753111b173b3b05d22fa08086e3b0f712fcc7c71a557e2db966c3e9fa91746039"}, + {"type": "B64", "value": "CTMMM/cRR+g9GS/Hgs0bR1MRGxc7OwXSL6CAhuOw9xL8x8caVX4tuWbD6fqRdGA5"} + ] + }, + { + "name": "Long", + "ptInputs": [ + {"type": "TEXT", "value": millionaAscii, "encoding": "UTF8"}, + {"type": "HEX", "value": millionaHex}, + {"type": "B64", "value": millionaB64} + ], + "outputs" : [ + {"type": "HEX", "value": "9d0e1809716474cb086e834e310a4a1ced149e9c00f248527972cec5704c2a5b07b8b3dc38ecc4ebae97ddd87f3d8985"}, + {"type": "B64", "value": "nQ4YCXFkdMsIboNOMQpKHO0UnpwA8khSeXLOxXBMKlsHuLPcOOzE666X3dh/PYmF"} + ] + }, + { + "name": "Short UTF16-BE", + "ptInputs": [ + {"type": "TEXT", "value": "abc", "encoding": "UTF16BE"} + ], + "outputs" : [ + {"type": "HEX", "value": "46591d403db207914d0cc5b58ad3c665e79fd957753594cf815d28b7115fe776395643a49d15ab8f4e24c13a36cdb9ec"} + ] + }, + { + "name": "Medium UTF16-BE", + "ptInputs": [ + {"type": "TEXT", "value": "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", "encoding": "UTF16BE"} + ], + "outputs" : [ + {"type": "HEX", "value": "71a48b0abb2245253c2bb9fcebb4e7149a9b214b8598d11352b9a3e07de1f35c059c8153545070229d19880af122aa48"} + ] + }, + { + "name": "Long UTF16-BE", + "ptInputs": [ + {"type": "TEXT", "value": millionaAscii, "encoding": "UTF16BE"} + ], + "outputs" : [ + {"type": "HEX", "value": "e26cb55351464f57b23def3b2447281dc8ba4e38f543b20bf7ba026f1f2bea57d54d3a721dd97337a8022a26bbef2c49"} + ] + }, + { + "name": "Short UTF16-LE", + "ptInputs": [ + {"type": "TEXT", "value": "abc", "encoding": "UTF16LE"} + ], + "outputs" : [ + {"type": "HEX", "value": "9b7ce7c7af46e400a37c8099cb4bbb5d0408061dd74cdb5dac7661bed1e53724bd07f299e265f400802a48d2e0b2092c"} + ] + }, + { + "name": "Medium UTF16-LE", + "ptInputs": [ + {"type": "TEXT", "value": "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", "encoding": "UTF16LE"} + ], + "outputs" : [ + {"type": "HEX", "value": "3c5fbafef52900a32840433c972999429d5c157426fdfb5c4968278f25bd4fe4f3b7aee8ae060695b05f61e595609637"} + ] + }, + { + "name": "Long UTF16-LE", + "ptInputs": [ + {"type": "TEXT", "value": millionaAscii, "encoding": "UTF16LE"} + ], + "outputs" : [ + {"type": "HEX", "value": "85056c62b9b2eba33a1ea69d06e32e71715188b25d3f7a2bc37be377890c4b0c08e7f55bc83550f0fe27a209088bc671"} + ] + } + ] + }, + { + "hash": "SHA3-384", + "tests": [ + { + "name": "Short", + "ptInputs": [ + {"type": "TEXT", "value": "abc", "encoding": "UTF8"}, + {"type": "HEX", "value": "616263"}, + {"type": "B64", "value": "YWJj"} + ], + "outputs" : [ + {"type": "HEX", "value": "ec01498288516fc926459f58e2c6ad8df9b473cb0fc08c2596da7cf0e49be4b298d88cea927ac7f539f1edf228376d25"}, + {"type": "B64", "value": "7AFJgohRb8kmRZ9Y4satjfm0c8sPwIwlltp88OSb5LKY2IzqknrH9Tnx7fIoN20l"} + ] + }, + { + "name": "Medium", + "ptInputs": [ + {"type": "TEXT", "value": "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", "encoding": "UTF8"}, + {"type": "HEX", "value": "61626364656667686263646566676869636465666768696A6465666768696A6B65666768696A6B6C666768696A6B6C6D6768696A6B6C6D6E68696A6B6C6D6E6F696A6B6C6D6E6F706A6B6C6D6E6F70716B6C6D6E6F7071726C6D6E6F707172736D6E6F70717273746E6F707172737475"}, + {"type": "B64", "value": "YWJjZGVmZ2hiY2RlZmdoaWNkZWZnaGlqZGVmZ2hpamtlZmdoaWprbGZnaGlqa2xtZ2hpamtsbW5oaWprbG1ub2lqa2xtbm9wamtsbW5vcHFrbG1ub3Bxcmxtbm9wcXJzbW5vcHFyc3Rub3BxcnN0dQ=="} + ], + "outputs" : [ + {"type": "HEX", "value": "79407d3b5916b59c3e30b09822974791c313fb9ecc849e406f23592d04f625dc8c709b98b43b3852b337216179aa7fc7"}, + {"type": "B64", "value": "eUB9O1kWtZw+MLCYIpdHkcMT+57MhJ5AbyNZLQT2JdyMcJuYtDs4UrM3IWF5qn/H"} + ] + }, + { + "name": "Long", + "ptInputs": [ + {"type": "TEXT", "value": millionaAscii, "encoding": "UTF8"}, + {"type": "HEX", "value": millionaHex}, + {"type": "B64", "value": millionaB64} + ], + "outputs" : [ + {"type": "HEX", "value": "eee9e24d78c1855337983451df97c8ad9eedf256c6334f8e948d252d5e0e76847aa0774ddb90a842190d2c558b4b8340"}, + {"type": "B64", "value": "7uniTXjBhVM3mDRR35fIrZ7t8lbGM0+OlI0lLV4OdoR6oHdN25CoQhkNLFWLS4NA"} + ] + }, + { + "name": "Short UTF16-BE", + "ptInputs": [ + {"type": "TEXT", "value": "abc", "encoding": "UTF16BE"} + ], + "outputs" : [ + {"type": "HEX", "value": "1f7807100bfb7293a3f94c1b410b9d413497ad81ec7032442f72c832891a251632dcda5c5b3b63233b71c6305379fe3d"} + ] + }, + { + "name": "Medium UTF16-BE", + "ptInputs": [ + {"type": "TEXT", "value": "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", "encoding": "UTF16BE"} + ], + "outputs" : [ + {"type": "HEX", "value": "b43e4a80f5ac9cf4f555dcca7b5a0cc0c7bf6f14ea30dbef4c7db98d18f159536a4211b31aaca5157f4fbae599ced799"} + ] + }, + { + "name": "Long UTF16-BE", + "ptInputs": [ + {"type": "TEXT", "value": millionaAscii, "encoding": "UTF16BE"} + ], + "outputs" : [ + {"type": "HEX", "value": "91f1c447390dd54913eceab5d1036b55d6cedd2a1cee7f99627d7183a6f3125632689aa3e4716a8e96a57b2da1fef69a"} + ] + }, + { + "name": "Short UTF16-LE", + "ptInputs": [ + {"type": "TEXT", "value": "abc", "encoding": "UTF16LE"} + ], + "outputs" : [ + {"type": "HEX", "value": "3f41b737dcc1e28410b9ad759f3687b31703247d36e98f3e1d96b1725d798d4e9c58a50e6217d4410d0ea81bc788f7b8"} + ] + }, + { + "name": "Medium UTF16-LE", + "ptInputs": [ + {"type": "TEXT", "value": "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", "encoding": "UTF16LE"} + ], + "outputs" : [ + {"type": "HEX", "value": "4bb8558d278d4e5b3b26e4173acc2c55a840f74ceb5ae0d9533eee416c3d3b1b4772ab0f0499e47fd03e0b4d579790f6"} + ] + }, + { + "name": "Long UTF16-LE", + "ptInputs": [ + {"type": "TEXT", "value": millionaAscii, "encoding": "UTF16LE"} + ], + "outputs" : [ + {"type": "HEX", "value": "ea60905cf5146f377d87be1e7774d9dfdf9500722023efbf5602b511417e44b69a5518b26f944eff8a97cfa662adfa01"} + ] + } + ] + }, + { + "hash": "SHA-512", + "tests": [ + { + "name": "Short", + "ptInputs": [ + {"type": "TEXT", "value": "abc", "encoding": "UTF8"}, + {"type": "HEX", "value": "616263"}, + {"type": "B64", "value": "YWJj"} + ], + "outputs" : [ + {"type": "HEX", "value": "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f"}, + {"type": "B64", "value": "3a81oZNherrMQXNJriBBMRLm+k6JqX6iCp7u5ktV05ohkpkqJ0/BqDa6PCOj/uu9RU1EI2Q86A4qmslPpUyknw=="} + ] + }, + { + "name": "Medium", + "ptInputs": [ + {"type": "TEXT", "value": "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", "encoding": "UTF8"}, + {"type": "HEX", "value": "61626364656667686263646566676869636465666768696A6465666768696A6B65666768696A6B6C666768696A6B6C6D6768696A6B6C6D6E68696A6B6C6D6E6F696A6B6C6D6E6F706A6B6C6D6E6F70716B6C6D6E6F7071726C6D6E6F707172736D6E6F70717273746E6F707172737475"}, + {"type": "B64", "value": "YWJjZGVmZ2hiY2RlZmdoaWNkZWZnaGlqZGVmZ2hpamtlZmdoaWprbGZnaGlqa2xtZ2hpamtsbW5oaWprbG1ub2lqa2xtbm9wamtsbW5vcHFrbG1ub3Bxcmxtbm9wcXJzbW5vcHFyc3Rub3BxcnN0dQ=="} + ], + "outputs" : [ + {"type": "HEX", "value": "8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909"}, + {"type": "B64", "value": "jpWbddrjE9qM9PcoFPwUP493ecbrn3+hcpmurbaIkBhQHSieSQD35DMbmd7EtUM6x9Mp7rbdJlReluVbh0vpCQ=="} + ] + }, + { + "name": "Long", + "ptInputs": [ + {"type": "TEXT", "value": millionaAscii, "encoding": "UTF8"}, + {"type": "HEX", "value": millionaHex}, + {"type": "B64", "value": millionaB64} + ], + "outputs" : [ + {"type": "HEX", "value": "e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973ebde0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b"}, + {"type": "B64", "value": "5xhIPQznaWROLkLHvBW0Y44fmLE7IEQoVjKoA6+pc+veD/JEh36mCkywQyzld8Mb6wCcXCxJqi5OrbIXrYzAmw=="} + ] + }, + { + "name": "Short UTF16-BE", + "ptInputs": [ + {"type": "TEXT", "value": "abc", "encoding": "UTF16BE"} + ], + "outputs" : [ + {"type": "HEX", "value": "cec00c412e5fe0ab4ff6ee7da097cce9b9ee67c8eeb3e99e11aec89dff1b8a2e417e37369c9c1bd65ce70f1b6be1ebf4ddbcaf2312fded40260fd55cf2ffe097"} + ] + }, + { + "name": "Medium UTF16-BE", + "ptInputs": [ + {"type": "TEXT", "value": "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", "encoding": "UTF16BE"} + ], + "outputs" : [ + {"type": "HEX", "value": "8f56290fb4a9cabfc427c0998abbef6527112db8c6916a9908421d97c820880b7a4137b29b7f6449b8f92a7666d85741faa01bdadb9b5d588570227b9be83360"} + ] + }, + { + "name": "Long UTF16-BE", + "ptInputs": [ + {"type": "TEXT", "value": millionaAscii, "encoding": "UTF16BE"} + ], + "outputs" : [ + {"type": "HEX", "value": "c89b6863e6568833664c449879f42fbe3e72b8054a43af61885904f72cebcc1a49b0d776b571cbf44530a291b5f5e2e26d8daa50047e5f0efc0b8e01a2ae6a08"} + ] + }, + { + "name": "Short UTF16-LE", + "ptInputs": [ + {"type": "TEXT", "value": "abc", "encoding": "UTF16LE"} + ], + "outputs" : [ + {"type": "HEX", "value": "add8b8154df7a734d2947a981f4e61c5366710d610040e5b54894d1006e89283cba082287ed5dd4c25cdaa5af56d24ab9fbedc56897130b0b5f3e50c7f9ee6df"} + ] + }, + { + "name": "Medium UTF16-LE", + "ptInputs": [ + {"type": "TEXT", "value": "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", "encoding": "UTF16LE"} + ], + "outputs" : [ + {"type": "HEX", "value": "d14cbc5ecfd355acf9d181ee878b91db4f30a7b03f7904388f252a77b1fffa9feb96803698294556ff7ce87ad0ab3ae748df979603733105ff3ac038e51483a3"} + ] + }, + { + "name": "Long UTF16-LE", + "ptInputs": [ + {"type": "TEXT", "value": millionaAscii, "encoding": "UTF16LE"} + ], + "outputs" : [ + {"type": "HEX", "value": "5e6b9aa02688b69fe5ebe842aeab69b22144d815ca603051f2e61ab752d202f85dc54252d19f9d62381a2d5e88ab391b7c6565d5e0d39925a4ad5b07e99925bd"} + ] + } + ] + }, + { + "hash": "SHA3-512", + "tests": [ + { + "name": "Short", + "ptInputs": [ + {"type": "TEXT", "value": "abc", "encoding": "UTF8"}, + {"type": "HEX", "value": "616263"}, + {"type": "B64", "value": "YWJj"} + ], + "outputs" : [ + {"type": "HEX", "value": "b751850b1a57168a5693cd924b6b096e08f621827444f70d884f5d0240d2712e10e116e9192af3c91a7ec57647e3934057340b4cf408d5a56592f8274eec53f0"}, + {"type": "B64", "value": "t1GFCxpXFopWk82SS2sJbgj2IYJ0RPcNiE9dAkDScS4Q4RbpGSrzyRp+xXZH45NAVzQLTPQI1aVlkvgnTuxT8A=="} + ] + }, + { + "name": "Medium", + "ptInputs": [ + {"type": "TEXT", "value": "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", "encoding": "UTF8"}, + {"type": "HEX", "value": "61626364656667686263646566676869636465666768696A6465666768696A6B65666768696A6B6C666768696A6B6C6D6768696A6B6C6D6E68696A6B6C6D6E6F696A6B6C6D6E6F706A6B6C6D6E6F70716B6C6D6E6F7071726C6D6E6F707172736D6E6F70717273746E6F707172737475"}, + {"type": "B64", "value": "YWJjZGVmZ2hiY2RlZmdoaWNkZWZnaGlqZGVmZ2hpamtlZmdoaWprbGZnaGlqa2xtZ2hpamtsbW5oaWprbG1ub2lqa2xtbm9wamtsbW5vcHFrbG1ub3Bxcmxtbm9wcXJzbW5vcHFyc3Rub3BxcnN0dQ=="} + ], + "outputs" : [ + {"type": "HEX", "value": "afebb2ef542e6579c50cad06d2e578f9f8dd6881d7dc824d26360feebf18a4fa73e3261122948efcfd492e74e82e2189ed0fb440d187f382270cb455f21dd185"}, + {"type": "B64", "value": "r+uy71QuZXnFDK0G0uV4+fjdaIHX3IJNJjYP7r8YpPpz4yYRIpSO/P1JLnToLiGJ7Q+0QNGH84InDLRV8h3RhQ=="} + ] + }, + { + "name": "Long", + "ptInputs": [ + {"type": "TEXT", "value": millionaAscii, "encoding": "UTF8"}, + {"type": "HEX", "value": millionaHex}, + {"type": "B64", "value": millionaB64} + ], + "outputs" : [ + {"type": "HEX", "value": "3c3a876da14034ab60627c077bb98f7e120a2a5370212dffb3385a18d4f38859ed311d0a9d5141ce9cc5c66ee689b266a8aa18ace8282a0e0db596c90b0a7b87"}, + {"type": "B64", "value": "PDqHbaFANKtgYnwHe7mPfhIKKlNwIS3/szhaGNTziFntMR0KnVFBzpzFxm7mibJmqKoYrOgoKg4NtZbJCwp7hw=="} + ] + }, + { + "name": "Short UTF16-BE", + "ptInputs": [ + {"type": "TEXT", "value": "abc", "encoding": "UTF16BE"} + ], + "outputs" : [ + {"type": "HEX", "value": "e056f3f5c960c7adb4d8c45e6b91604ecd0d98e7f082dc63ace7da388fb9908ccf8a548cbcf8de7b069aa5c1005f09a4d8a28dcec324801b565673342e74caf1"} + ] + }, + { + "name": "Medium UTF16-BE", + "ptInputs": [ + {"type": "TEXT", "value": "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", "encoding": "UTF16BE"} + ], + "outputs" : [ + {"type": "HEX", "value": "b10dd0b98cbd73190e06b5720404cfb0f122a0ff7f063ad4a6ed6ed609eb5e1d3c87260ecc7b877fdf6592dc521c845ae06a5e106928e90f4021bac16c030a8d"} + ] + }, + { + "name": "Long UTF16-BE", + "ptInputs": [ + {"type": "TEXT", "value": millionaAscii, "encoding": "UTF16BE"} + ], + "outputs" : [ + {"type": "HEX", "value": "5f0b393b1a9bc521289a721291a860d95af6c420a1a16b0810d203870a1b37a0d047e000de95208d63fb373d2207dfd0cde5024692aebfd947e78c6c3ddd5ed8"} + ] + }, + { + "name": "Short UTF16-LE", + "ptInputs": [ + {"type": "TEXT", "value": "abc", "encoding": "UTF16LE"} + ], + "outputs" : [ + {"type": "HEX", "value": "115fbb697dc2dcbcb61888d910a34d01162842f5329ead230870e98bcb75afb516b6440241f51192b7a67f6788b6396201dab5f205d6cd940312bcfe958b8aaa"} + ] + }, + { + "name": "Medium UTF16-LE", + "ptInputs": [ + {"type": "TEXT", "value": "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", "encoding": "UTF16LE"} + ], + "outputs" : [ + {"type": "HEX", "value": "ebe4b4d745a02d3fe56f23d38b6cf2674b4684696704586fc95f7be033c1140a9bdd530f80b867f3e927d1eb24969c8a2bb385ba0596e4ae1e0c2d84eff7266c"} + ] + }, + { + "name": "Long UTF16-LE", + "ptInputs": [ + {"type": "TEXT", "value": millionaAscii, "encoding": "UTF16LE"} + ], + "outputs" : [ + {"type": "HEX", "value": "b17e56d64e29cbe22943719ff00912b9866e6d372a6fe19130e7e2bb6d8572d002f8be5a547b1774c542e1089131a64106f5b687da295a3a92ec941301622596"} + ] + } + ] + }, + { + "hash": "SHAKE128", + "tests": [ + { + "name": "Short", + "ptInputs": [ + {"type": "TEXT", "value": "abc", "encoding": "UTF8"}, + {"type": "HEX", "value": "616263"}, + {"type": "B64", "value": "YWJj"} + ], + "outputs" : [ + {"type": "HEX", "value": "5881092dd818bf5cf8a3ddb793fbcba74097d5c526a6d35f97b83351940f2c", "shakeLen": 248}, + {"type": "B64", "value": "WIEJLdgYv1z4o923k/vLp0CX1cUmptNfl7gzUZQPLA==", "shakeLen": 248}, + {"type": "HEX", "value": "5881092dd818bf5cf8a3ddb793fbcba74097d5c526a6d35f97b83351940f2cc844c50af32acd3f2cdd066568706f509bc1bdde58295dae3f891a9a0fca5783", "shakeLen": 504}, + {"type": "B64", "value": "WIEJLdgYv1z4o923k/vLp0CX1cUmptNfl7gzUZQPLMhExQrzKs0/LN0GZWhwb1Cbwb3eWCldrj+JGpoPyleD", "shakeLen": 504} + ] + }, + { + "name": "Medium", + "ptInputs": [ + {"type": "TEXT", "value": "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", "encoding": "UTF8"}, + {"type": "HEX", "value": "61626364656667686263646566676869636465666768696A6465666768696A6B65666768696A6B6C666768696A6B6C6D6768696A6B6C6D6E68696A6B6C6D6E6F696A6B6C6D6E6F706A6B6C6D6E6F70716B6C6D6E6F7071726C6D6E6F707172736D6E6F70717273746E6F707172737475"}, + {"type": "B64", "value": "YWJjZGVmZ2hiY2RlZmdoaWNkZWZnaGlqZGVmZ2hpamtlZmdoaWprbGZnaGlqa2xtZ2hpamtsbW5oaWprbG1ub2lqa2xtbm9wamtsbW5vcHFrbG1ub3Bxcmxtbm9wcXJzbW5vcHFyc3Rub3BxcnN0dQ=="} + ], + "outputs" : [ + {"type": "HEX", "value": "7b6df6ff181173b6d7898d7ff63fb07b7c237daf471a5ae5602adbccef9ccf", "shakeLen": 248}, + {"type": "B64", "value": "e232/xgRc7bXiY1/9j+we3wjfa9HGlrlYCrbzO+czw==", "shakeLen": 248}, + {"type": "HEX", "value": "7b6df6ff181173b6d7898d7ff63fb07b7c237daf471a5ae5602adbccef9ccf4b37e06b4a3543164ffbe0d0557c02f9b25ad434005526d88ca04a6094b93ee5", "shakeLen": 504}, + {"type": "B64", "value": "e232/xgRc7bXiY1/9j+we3wjfa9HGlrlYCrbzO+cz0s34GtKNUMWT/vg0FV8AvmyWtQ0AFUm2IygSmCUuT7l", "shakeLen": 504} + ] + }, + { + "name": "Long", + "ptInputs": [ + {"type": "TEXT", "value": millionaAscii, "encoding": "UTF8"}, + {"type": "HEX", "value": millionaHex}, + {"type": "B64", "value": millionaB64} + ], + "outputs" : [ + {"type": "HEX", "value": "9d222c79c4ff9d092cf6ca86143aa411e369973808ef97093255826c5572ef", "shakeLen": 248}, + {"type": "B64", "value": "nSIsecT/nQks9sqGFDqkEeNplzgI75cJMlWCbFVy7w==", "shakeLen": 248}, + {"type": "HEX", "value": "9d222c79c4ff9d092cf6ca86143aa411e369973808ef97093255826c5572ef58424c4b5c28475ffdcf981663867fec6321c1262e387bccf8ca676884c4a9d0", "shakeLen": 504}, + {"type": "B64", "value": "nSIsecT/nQks9sqGFDqkEeNplzgI75cJMlWCbFVy71hCTEtcKEdf/c+YFmOGf+xjIcEmLjh7zPjKZ2iExKnQ", "shakeLen": 504} + ] + }, + { + "name": "Short UTF16-BE", + "ptInputs": [ + {"type": "TEXT", "value": "abc", "encoding": "UTF16BE"} + ], + "outputs" : [ + {"type": "HEX", "value": "40f2bdd295c3208f7f2f3436d2cab325ac0e7f204e04430853fdc217db767b", "shakeLen": 248}, + {"type": "HEX", "value": "40f2bdd295c3208f7f2f3436d2cab325ac0e7f204e04430853fdc217db767b9bb579eb6534f387de5c79544d0761849870d332aad8bf94d4ffc2c1e638ea47", "shakeLen": 504} + ] + }, + { + "name": "Medium UTF16-BE", + "ptInputs": [ + {"type": "TEXT", "value": "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", "encoding": "UTF16BE"} + ], + "outputs" : [ + {"type": "HEX", "value": "d8ccc8505c54a81ddafd0db03b7eb8c2f309655b980781629b04bc4e9d7dbf", "shakeLen": 248}, + {"type": "HEX", "value": "d8ccc8505c54a81ddafd0db03b7eb8c2f309655b980781629b04bc4e9d7dbf4a708b19fa12e434749880492d6c2dfd3deda5ae42c44c760f0faaf1b2ee31aa", "shakeLen": 504} + ] + }, + { + "name": "Long UTF16-BE", + "ptInputs": [ + {"type": "TEXT", "value": millionaAscii, "encoding": "UTF16BE"} + ], + "outputs" : [ + {"type": "HEX", "value": "29d48c0b789a3039977b97ebe61c8e963e2a1128acefd2301b476f7625630e", "shakeLen": 248}, + {"type": "HEX", "value": "29d48c0b789a3039977b97ebe61c8e963e2a1128acefd2301b476f7625630e0fb6660aaaa4103ef05246d4a5e52dbd08c8fa5fcc61e9c05aedbdc3289d91d1", "shakeLen": 504} + ] + }, + { + "name": "Short UTF16-LE", + "ptInputs": [ + {"type": "TEXT", "value": "abc", "encoding": "UTF16LE"} + ], + "outputs" : [ + {"type": "HEX", "value": "6a426b1cd7f9cc84a2194ca196cff2642a730356065484756827a5c9615659", "shakeLen": 248}, + {"type": "HEX", "value": "6a426b1cd7f9cc84a2194ca196cff2642a730356065484756827a5c96156591c195572879ae4c2c2a4345b20cee264c18188c3033a45238d01fb6fcbfb2b44", "shakeLen": 504} + ] + }, + { + "name": "Medium UTF16-LE", + "ptInputs": [ + {"type": "TEXT", "value": "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", "encoding": "UTF16LE"} + ], + "outputs" : [ + {"type": "HEX", "value": "c589c37bdd19b37c96b650ce2622a7914d8b0d5ecb7855c77bd9b723a0c73b", "shakeLen": 248}, + {"type": "HEX", "value": "c589c37bdd19b37c96b650ce2622a7914d8b0d5ecb7855c77bd9b723a0c73be880392931a248a5ce89338d0f46e837adde144d8a0780625599477adff6a124", "shakeLen": 504} + ] + }, + { + "name": "Long UTF16-LE", + "ptInputs": [ + {"type": "TEXT", "value": millionaAscii, "encoding": "UTF16LE"} + ], + "outputs" : [ + {"type": "HEX", "value": "fe68432164f01f9b90a715299126d6b50787e50691a0c4b1af01243bcbf283", "shakeLen": 248}, + {"type": "HEX", "value": "fe68432164f01f9b90a715299126d6b50787e50691a0c4b1af01243bcbf2837f94a8275fcd414c244505ad9709c78ff53578fe06ef69ba1195394a50d1b4f7", "shakeLen": 504} + ] + } + ] + }, + { + "hash": "SHAKE256", + "tests": [ + { + "name": "Short", + "ptInputs": [ + {"type": "TEXT", "value": "abc", "encoding": "UTF8"}, + {"type": "HEX", "value": "616263"}, + {"type": "B64", "value": "YWJj"} + ], + "outputs" : [ + {"type": "HEX", "value": "483366601360a8771c6863080cc4114d8db44530f8f1e1ee4f94ea37e78b57", "shakeLen": 248}, + {"type": "B64", "value": "SDNmYBNgqHccaGMIDMQRTY20RTD48eHuT5TqN+eLVw==", "shakeLen": 248}, + {"type": "HEX", "value": "483366601360a8771c6863080cc4114d8db44530f8f1e1ee4f94ea37e78b5739d5a15bef186a5386c75744c0527e1faa9f8726e462a12a4feb06bd8801e751", "shakeLen": 504}, + {"type": "B64", "value": "SDNmYBNgqHccaGMIDMQRTY20RTD48eHuT5TqN+eLVznVoVvvGGpThsdXRMBSfh+qn4cm5GKhKk/rBr2IAedR", "shakeLen": 504} + ] + }, + { + "name": "Medium", + "ptInputs": [ + {"type": "TEXT", "value": "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", "encoding": "UTF8"}, + {"type": "HEX", "value": "61626364656667686263646566676869636465666768696A6465666768696A6B65666768696A6B6C666768696A6B6C6D6768696A6B6C6D6E68696A6B6C6D6E6F696A6B6C6D6E6F706A6B6C6D6E6F70716B6C6D6E6F7071726C6D6E6F707172736D6E6F70717273746E6F707172737475"}, + {"type": "B64", "value": "YWJjZGVmZ2hiY2RlZmdoaWNkZWZnaGlqZGVmZ2hpamtlZmdoaWprbGZnaGlqa2xtZ2hpamtsbW5oaWprbG1ub2lqa2xtbm9wamtsbW5vcHFrbG1ub3Bxcmxtbm9wcXJzbW5vcHFyc3Rub3BxcnN0dQ=="} + ], + "outputs" : [ + {"type": "HEX", "value": "98be04516c04cc73593fef3ed0352ea9f6443942d6950e29a372a681c3deaf", "shakeLen": 248}, + {"type": "B64", "value": "mL4EUWwEzHNZP+8+0DUuqfZEOULWlQ4po3KmgcPerw==", "shakeLen": 248}, + {"type": "HEX", "value": "98be04516c04cc73593fef3ed0352ea9f6443942d6950e29a372a681c3deaf4535423709b02843948684e029010badcc0acd8303fc85fdad3eabf4f78cae16", "shakeLen": 504}, + {"type": "B64", "value": "mL4EUWwEzHNZP+8+0DUuqfZEOULWlQ4po3KmgcPer0U1QjcJsChDlIaE4CkBC63MCs2DA/yF/a0+q/T3jK4W", "shakeLen": 504} + ] + }, + { + "name": "Long", + "ptInputs": [ + {"type": "TEXT", "value": millionaAscii, "encoding": "UTF8"}, + {"type": "HEX", "value": millionaHex}, + {"type": "B64", "value": millionaB64} + ], + "outputs" : [ + {"type": "HEX", "value": "3578a7a4ca9137569cdf76ed617d31bb994fca9c1bbf8b184013de8234dfd1", "shakeLen": 248}, + {"type": "B64", "value": "NXinpMqRN1ac33btYX0xu5lPypwbv4sYQBPegjTf0Q==", "shakeLen": 248}, + {"type": "HEX", "value": "3578a7a4ca9137569cdf76ed617d31bb994fca9c1bbf8b184013de8234dfd13a3fd124d4df76c0a539ee7dd2f6e1ec346124c815d9410e145eb561bcd97b18", "shakeLen": 504}, + {"type": "B64", "value": "NXinpMqRN1ac33btYX0xu5lPypwbv4sYQBPegjTf0To/0STU33bApTnufdL24ew0YSTIFdlBDhRetWG82XsY", "shakeLen": 504} + ] + }, + { + "name": "Short UTF16-BE", + "ptInputs": [ + {"type": "TEXT", "value": "abc", "encoding": "UTF16BE"} + ], + "outputs" : [ + {"type": "HEX", "value": "a8e58b37e3dab187c7c20123870900aa11fee5f0c3bbba8af2edc6e892b429", "shakeLen": 248}, + {"type": "HEX", "value": "a8e58b37e3dab187c7c20123870900aa11fee5f0c3bbba8af2edc6e892b42984543e4ba39cd6661a22a785dcf6531f7275be0b47d6c9690475ce347e00da58", "shakeLen": 504} + ] + }, + { + "name": "Medium UTF16-BE", + "ptInputs": [ + {"type": "TEXT", "value": "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", "encoding": "UTF16BE"} + ], + "outputs" : [ + {"type": "HEX", "value": "262903200110b573ba851475488f5b751dcba77579d436180d9efccfc93b91", "shakeLen": 248}, + {"type": "HEX", "value": "262903200110b573ba851475488f5b751dcba77579d436180d9efccfc93b912c4d70f115c9bf3fdbb133e34f23768fa57151f54135d7c681a5e2cf1b5129d0", "shakeLen": 504} + ] + }, + { + "name": "Long UTF16-BE", + "ptInputs": [ + {"type": "TEXT", "value": millionaAscii, "encoding": "UTF16BE"} + ], + "outputs" : [ + {"type": "HEX", "value": "25444b2108287ee102e524a9499103bd87f9ae7e82b18777e8c84e2834ce0b", "shakeLen": 248}, + {"type": "HEX", "value": "25444b2108287ee102e524a9499103bd87f9ae7e82b18777e8c84e2834ce0b4d38350f3c0536fb12ec9f0109397b520abf249a17dcbe33421c5abf21f23cdb", "shakeLen": 504} + ] + }, + { + "name": "Short UTF16-LE", + "ptInputs": [ + {"type": "TEXT", "value": "abc", "encoding": "UTF16LE"} + ], + "outputs" : [ + {"type": "HEX", "value": "d94f7da7db99cfbb32bc5fa89917a60dc1c12f46c924bcac76b05bb9eefa70", "shakeLen": 248}, + {"type": "HEX", "value": "d94f7da7db99cfbb32bc5fa89917a60dc1c12f46c924bcac76b05bb9eefa705f909795f964f22e2036ccb560d952f1485d75127b060d680e19efb0bf852cf9", "shakeLen": 504} + ] + }, + { + "name": "Medium UTF16-LE", + "ptInputs": [ + {"type": "TEXT", "value": "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", "encoding": "UTF16LE"} + ], + "outputs" : [ + {"type": "HEX", "value": "cade3014570c222dc6aa327be04ac8088f85fe0a177f08e48b24b6a30dc078", "shakeLen": 248}, + {"type": "HEX", "value": "cade3014570c222dc6aa327be04ac8088f85fe0a177f08e48b24b6a30dc0783fd4bdef46fddd440dba74b8dd5b524b9530d85e2a30e2e35a1bee69f7c7ed9a", "shakeLen": 504} + ] + }, + { + "name": "Long UTF16-LE", + "ptInputs": [ + {"type": "TEXT", "value": millionaAscii, "encoding": "UTF16LE"} + ], + "outputs" : [ + {"type": "HEX", "value": "295697f761094a339fc6626b97f10d89912839d276ab7a1bf330eb3c40baad", "shakeLen": 248}, + {"type": "HEX", "value": "295697f761094a339fc6626b97f10d89912839d276ab7a1bf330eb3c40baad9d21210c4847df516ec630ae7077a9a17f0d6792561d7708068a3d32850c8cca", "shakeLen": 504} + ] + } + ] + } +]; + +/* Dynamically build ArrayBuffer tests if the environment supports them */ +try +{ + hashTests.forEach(function(testSuite) { + testSuite["tests"].forEach(function(test) { + var clonedOutputs = []; + test["ptInputs"].forEach(function(ptInput) { + if (ptInput["type"] === "HEX") + { + test["ptInputs"].push({"type": "ARRAYBUFFER", "value": hexToArrayBuffer(ptInput["value"])}); + } + }); + test["outputs"].forEach(function(output) { + if (output["type"] === "HEX") + { + /* Can't compare ARRAYBUFFERs so actually use the HEX output directly and convert in the unit test */ + if (output.hasOwnProperty("shakeLen")) + { + clonedOutputs.push({"type": "ARRAYBUFFER", "value": output["value"], "shakeLen": output["shakeLen"]}); + } + else + { + clonedOutputs.push({"type": "ARRAYBUFFER", "value": output["value"]}); + } + } + }); + test["outputs"] = test["outputs"].concat(clonedOutputs); + }); + }); +} +catch (ignore) +{ + /* ArrayBuffers may not be supported by the environment */ +} + +hashTests.forEach(function(testSuite) { + describe("Basic " + testSuite["hash"] + " Tests", function() { + try + { + testSuite["tests"].forEach(function(test) { + test["ptInputs"].forEach(function(ptInput) { + var inOptions = {}, hash = null; + if (ptInput.hasOwnProperty("encoding")) + { + inOptions["encoding"] = ptInput["encoding"]; + } + hash = new jsSHA(testSuite["hash"], ptInput["type"], inOptions); + hash.update(ptInput["value"]); + + test["outputs"].forEach(function(output) { + var outOptions = {}; + if (output.hasOwnProperty("shakeLen")) + { + outOptions["shakeLen"] = output["shakeLen"]; + } + + if (output["type"] != "ARRAYBUFFER") + { + it(test["name"] + " " + ptInput["type"] + " Input - " + output["type"] + " Output", function() { + chai.assert.equal(hash.getHash(output["type"], outOptions), output["value"]); + }); + } + else /* Matching the dynamic build of ArrayBuffer tests, need to use HEX as a comparison medium */ + { + it(test["name"] + " " + ptInput["type"] + " Input - " + output["type"] + " Output", function() { + chai.assert.equal(arrayBufferToHex(hash.getHash(output["type"], outOptions)), output["value"]); + }); + } + }); + }); + }); + } + catch(e) + { + if (e.message != "Chosen SHA variant is not supported") + { + throw new Error("Testing of " + testSuite["hash"] + " failed"); + } + } + }); +}); +/* ============================================================================ + * End Basic Hash Tests + * ============================================================================ + */ diff --git a/frontend/jsSHA/test/test_hmac.js b/frontend/jsSHA/test/test_hmac.js new file mode 100755 index 0000000..91ee5e8 --- /dev/null +++ b/frontend/jsSHA/test/test_hmac.js @@ -0,0 +1,533 @@ +/* Kind of hack to get the tests working both in the browser and node.js */ +if (("undefined" !== typeof module) && module["exports"]) +{ + mocha = require("mocha"); + chai = require("chai"); + jsSHA = require("../src/sha_dev.js"); +} + +String.prototype.repeat = function(times) { + return (new Array(times + 1)).join(this); +} + +/* These are used often so make a global copy that everything can reference */ +var millionaAscii = "a".repeat(1000000), millionaHex = "61".repeat(1000000), millionaB64 = "YWFh".repeat(333333) + "YQ=="; + +/* ============================================================================ + * Begin HMAC Tests + * ============================================================================ + */ +var hmacTests = [ + { + "hash": "SHA-1", + "tests": [ + { + "name": "Short", + "ptInputs": [ + {"type": "TEXT", "value": "Sample message for keylenblocklen"}, + {"type": "HEX", "value": "53616d706c65206d65737361676520666f72206b65796c656e3e626c6f636b6c656e"}, + {"type": "B64", "value": "U2FtcGxlIG1lc3NhZ2UgZm9yIGtleWxlbj5ibG9ja2xlbg=="} + ], + "keyInputs": [ + {"type": "HEX", "value": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaab"}, + {"type": "B64", "value": "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqqw=="} + ], + "outputs": [ + {"type": "HEX", "value": "078695eecc227c636ad31d063a15dd05a7e819a66ec6d8de1e193e59"}, + {"type": "B64", "value": "B4aV7swifGNq0x0GOhXdBafoGaZuxtjeHhk+WQ=="} + ], + } + ] + }, + { + "hash": "SHA-256", + "tests": [ + { + "name": "Short", + "ptInputs": [ + {"type": "TEXT", "value": "Sample message for keylenblocklen"}, + {"type": "HEX", "value": "53616d706c65206d65737361676520666f72206b65796c656e3e626c6f636b6c656e"}, + {"type": "B64", "value": "U2FtcGxlIG1lc3NhZ2UgZm9yIGtleWxlbj5ibG9ja2xlbg=="} + ], + "keyInputs": [ + {"type": "HEX", "value": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7"}, + {"type": "B64", "value": "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6ChoqOkpaan"} + ], + "outputs": [ + {"type": "HEX", "value": "9bcf2c238e235c3ce88404e813bd2f3a97185ac6f238c63d6229a00b07974258"}, + {"type": "B64", "value": "m88sI44jXDzohAToE70vOpcYWsbyOMY9YimgCweXQlg="} + ] + } + ] + }, + { + "hash": "SHA-384", + "tests": [ + { + "name": "Short", + "ptInputs": [ + {"type": "TEXT", "value": "Sample message for keylenblocklen"}, + {"type": "HEX", "value": "53616d706c65206d65737361676520666f72206b65796c656e3e626c6f636b6c656e"}, + {"type": "B64", "value": "U2FtcGxlIG1lc3NhZ2UgZm9yIGtleWxlbj5ibG9ja2xlbg=="} + ], + "keyInputs": [ + {"type": "HEX", "value": "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F9091929394959697"}, + {"type": "B64", "value": "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpc="} + ], + "outputs": [ + {"type": "HEX", "value": "e5ae4c739f455279368ebf36d4f5354c95aa184c899d3870e460ebc288ef1f9470053f73f7c6da2a71bcaec38ce7d6ac"}, + {"type": "B64", "value": "5a5Mc59FUnk2jr821PU1TJWqGEyJnThw5GDrwojvH5RwBT9z98baKnG8rsOM59as"} + ] + } + ] + }, + { + "hash": "SHA-512", + "tests": [ + { + "name": "Short", + "ptInputs": [ + {"type": "TEXT", "value": "Sample message for keylenblocklen"}, + {"type": "HEX", "value": "53616d706c65206d65737361676520666f72206b65796c656e3e626c6f636b6c656e"}, + {"type": "B64", "value": "U2FtcGxlIG1lc3NhZ2UgZm9yIGtleWxlbj5ibG9ja2xlbg=="} + ], + "keyInputs": [ + {"type": "HEX", "value": "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F8081828384858687"}, + {"type": "B64", "value": "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGhw=="} + ], + "outputs": [ + {"type": "HEX", "value": "5f464f5e5b7848e3885e49b2c385f0694985d0e38966242dc4a5fe3fea4b37d46b65ceced5dcf59438dd840bab22269f0ba7febdb9fcf74602a35666b2a32915"}, + {"type": "B64", "value": "X0ZPXlt4SOOIXkmyw4XwaUmF0OOJZiQtxKX+P+pLN9RrZc7O1dz1lDjdhAurIiafC6f+vbn890YCo1ZmsqMpFQ=="} + ] + } + ] + } +] + +hmacTests.forEach(function(testSuite) { + describe("HMAC " + testSuite["hash"] + " Tests", function() { + try + { + testSuite["tests"].forEach(function(test) { + test["ptInputs"].forEach(function(ptInput) { + test["keyInputs"].forEach(function(keyInput) { + var hash = new jsSHA(testSuite["hash"], ptInput["type"]); + hash.setHMACKey(keyInput["value"], keyInput["type"]) + hash.update(ptInput["value"]); + test["outputs"].forEach(function(output) { + it(ptInput["type"] + " Input - " + test["name"] + " " + keyInput["type"] + " Key - " + output["type"] + " Output", function() { + chai.assert.equal(hash.getHMAC(output["type"]), output["value"]); + }); + }); + }); + }); + }); + } + catch(e) + { + if (e.message != "Chosen SHA variant is not supported") + { + throw new Error("Testing of HMAC " + testSuite["hash"] + " failed"); + } + } + }); +}); +/* ============================================================================ + * End HMAC Tests + * ============================================================================ + */ diff --git a/frontend/jsSHA/test/test_multi.js b/frontend/jsSHA/test/test_multi.js new file mode 100755 index 0000000..9e616f9 --- /dev/null +++ b/frontend/jsSHA/test/test_multi.js @@ -0,0 +1,220 @@ +/* Kind of hack to get the tests working both in the browser and node.js */ +if (("undefined" !== typeof module) && module["exports"]) +{ + mocha = require("mocha"); + chai = require("chai"); + jsSHA = require("../src/sha_dev.js"); +} + +String.prototype.repeat = function(times) { + return (new Array(times + 1)).join(this); +} + +/* These are used often so make a global copy that everything can reference */ +var millionaAscii = "a".repeat(1000000), millionaHex = "61".repeat(1000000), millionaB64 = "YWFh".repeat(333333) + "YQ=="; + +/* ============================================================================ + * Begin Multi-Round Hash Tests + * ============================================================================ + */ +var multiRoundTests = [ + { + "hash": "SHA-1", + "tests": [ + { + "name": "Short", + "ptInputs": [ + {"type": "TEXT", "value": "abc"} + ], + "outputs": [ + {"type": "HEX", "rounds": 5, "value": "b5c64925eb9940259be55c005c9cecc7d9897ef9"}, + {"type": "HEX", "rounds": 10, "value": "94ebc0d3c81b61eb98670666f5fde68560c4e165"} + ] + } + ] + }, + { + "hash": "SHA-224", + "tests": [ + { + "name": "Short", + "ptInputs": [ + {"type": "TEXT", "value": "abc"} + ], + "outputs": [ + {"type": "HEX", "rounds": 5, "value": "5b4b17f720d52c6a864229e784fb636184ca48ce7dd848fdad986239"}, + {"type": "HEX", "rounds": 10, "value": "5230eb37afcc115f4f380a9f50c4743d457bbe586e6faa6bf21696f9"} + ] + } + ] + }, + { + "hash": "SHA3-224", + "tests": [ + { + "name": "Short", + "ptInputs": [ + {"type": "TEXT", "value": "abc"} + ], + "outputs": [ + {"type": "HEX", "rounds": 5, "value": "7d208060760d239d9e9b041b5c30ac992b83ff1df658263953c9eff0"}, + {"type": "HEX", "rounds": 10, "value": "a1b668748fd69b8b6a6453d3bada2b9eb9a06a29b78fbcff5ab530ae"} + ] + } + ] + }, + { + "hash": "SHA-256", + "tests": [ + { + "name": "Short", + "ptInputs": [ + {"type": "TEXT", "value": "abc"} + ], + "outputs": [ + {"type": "HEX", "rounds": 5, "value": "184f6d6e82554c051b33f15e7ffffecb0cc0f461a29096c41c214e168e34c21d"}, + {"type": "HEX", "rounds": 10, "value": "10e286f907c0fe9f02cea3864cbaec04ae47e2c0a13b60473bc9968a4851b219"} + ] + } + ] + }, + { + "hash": "SHA3-256", + "tests": [ + { + "name": "Short", + "ptInputs": [ + {"type": "TEXT", "value": "abc"} + ], + "outputs": [ + {"type": "HEX", "rounds": 5, "value": "fd5ad48a1abf3fd8211ecd2a6a0b0503e745d953def260541fa5db7dc1b3b84f"}, + {"type": "HEX", "rounds": 10, "value": "5b814fc96d03918994939bccb796945d9683fa90a22f99350d6a964de78a7980"} + ] + } + ] + }, + { + "hash": "SHA-384", + "tests": [ + { + "name": "Short", + "ptInputs": [ + {"type": "TEXT", "value": "abc"} + ], + "outputs": [ + {"type": "HEX", "rounds": 5, "value": "a4aa4cd8534aecb2d07765f928303d1d2609835ea85d14312bcee264e99dc5d7dc08bb18ec694053fd7fe6906706d55f"}, + {"type": "HEX", "rounds": 10, "value": "b80c82979453f2f3dcf89ec4cef5c71e89837537de170e3942af8b37757cc790d4cc4ebe16a52164ad19f3a02d192f1c"} + ] + } + ] + }, + { + "hash": "SHA3-384", + "tests": [ + { + "name": "Short", + "ptInputs": [ + {"type": "TEXT", "value": "abc"} + ], + "outputs": [ + {"type": "HEX", "rounds": 5, "value": "be2f2365cecd5df751f3ab7d23cabfb60491ce28bdf80b121f7941ee33227ce86d5d62d6633f5654a4f3ae5381cf1825"}, + {"type": "HEX", "rounds": 10, "value": "4cb125e919d39ab283964e06ce58dd8923fa599046b533958c9353317ab368066b9902c2e1a9c9376d66f321fcc2c0a1"} + ] + } + ] + }, + { + "hash": "SHA-512", + "tests": [ + { + "name": "Short", + "ptInputs": [ + {"type": "TEXT", "value": "abc"} + ], + "outputs": [ + {"type": "HEX", "rounds": 5, "value": "299b2e3ce932e4d0e9005345e37af5a4cc6be21e6b6e21231ce71ccde2a7aba4a6822cd7a9aaf9b13918db05ede70d3f1e6af65f8ad0bda1c4c4fa263e3cabdd"}, + {"type": "HEX", "rounds": 10, "value": "4c3ead8c83442fff47d4386702044f2a6c19730a806de541964b0fa9987cac08641611e02b2e0742ef2600ff82bfe3a711567c8e76dda16b4948f4c76e3c6e9c"} + ] + } + ] + }, + { + "hash": "SHA3-512", + "tests": [ + { + "name": "Short", + "ptInputs": [ + {"type": "TEXT", "value": "abc"} + ], + "outputs": [ + {"type": "HEX", "rounds": 5, "value": "8c74189ca608ad188bb96c8c374fb717ce982500dc2c0ce90ad8e5888b498ce9fda0e4bf256feeaaf1674b69e9ea80cf5ed444dfdd5d3eb05cfebd597b4aab67"}, + {"type": "HEX", "rounds": 10, "value": "0e3c0126a211563fdedc96149f1c2334aa5f5b2afcf5590cb71fec0ab348ba522e56c1136f165f525b22890e2546d2f9edbea6b6f5e929237b6c0f395e1b2e9b"} + ] + } + ] + }, + { + "hash": "SHAKE128", + "tests": [ + { + "name": "Short", + "ptInputs": [ + {"type": "TEXT", "value": "abc"} + ], + "outputs": [ + {"type": "HEX", "rounds": 5, "value": "99d5aa0763f5bd9464ed4bbc631ecdac6f67e77cbf61c7f7171dd2ffa892ba", "shakeLen": 248}, + {"type": "HEX", "rounds": 10, "value": "5a5aeb2022e0e92ef4da3dc3e261a9303224b65cf6666f87a4d395a4ab94fe", "shakeLen": 248} + ] + } + ] + }, + { + "hash": "SHAKE256", + "tests": [ + { + "name": "Short", + "ptInputs": [ + {"type": "TEXT", "value": "abc"} + ], + "outputs": [ + {"type": "HEX", "rounds": 5, "value": "70368c73548e76dd6405ea6c1b4358eb0aeb4c0efe73526c7c6e1d9a9e4e0a", "shakeLen": 248}, + {"type": "HEX", "rounds": 10, "value": "d706c35b6642f39a27635c61c85ab13e76827de8fde4557e25bfc96b445f10", "shakeLen": 248} + ] + } + ] + } +] + +multiRoundTests.forEach(function(testSuite) { + describe("Multiround " + testSuite["hash"] + " Tests", function() { + try + { + testSuite["tests"].forEach(function(test) { + test["ptInputs"].forEach(function(ptInput) { + test["outputs"].forEach(function(output) { + var options = {}, hash = new jsSHA(testSuite["hash"], ptInput["type"], {"numRounds": output["rounds"]}); + hash.update(ptInput["value"]); + it(test["name"] + " " + ptInput["type"] + " Input - " + output["type"] + " Output - " + output["rounds"] + " Rounds ", function() { + if (output.hasOwnProperty("shakeLen")) + { + options["shakeLen"] = output["shakeLen"] + } + chai.assert.equal(hash.getHash(output["type"], options), output["value"]); + }); + }); + }); + }); + } + catch(e) + { + if (e.message != "Chosen SHA variant is not supported") + { + throw new Error("Testing of multi-round " + testSuite["hash"] + " failed"); + } + } + }); +}); +/* ============================================================================ + * End Multi-Round Hash Tests + * ============================================================================ + */ diff --git a/frontend/thumbnail.png b/frontend/thumbnail.png new file mode 100644 index 0000000..514fc3e Binary files /dev/null and b/frontend/thumbnail.png differ diff --git a/index.js b/index.js index 8567388..7398776 100644 --- a/index.js +++ b/index.js @@ -15,11 +15,7 @@ const { sendInitialStats } = require('./stats.js') const fs = require('fs') const ObjectId = require('mongodb').ObjectId // just to check ObjectIDs -const static_files_path = path.join(__dirname, - isDevEnvironment - ? '../volt.link-frontend/build/' - : '../volt.link-frontend/' -) +const static_files_path = path.join(__dirname, './frontend/') function checkOrigin(origin){ return (